Author: cziegeler
Date: Fri Sep 19 08:07:31 2014
New Revision: 1626138

URL: http://svn.apache.org/r1626138
Log:
Add slingstart model

Added:
    sling/trunk/tooling/support/slingstart-model/
    sling/trunk/tooling/support/slingstart-model/src/
    sling/trunk/tooling/support/slingstart-model/src/main/
    sling/trunk/tooling/support/slingstart-model/src/main/java/
    sling/trunk/tooling/support/slingstart-model/src/main/java/org/
    sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/
    sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
   (with props)
    
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
   (with props)

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+/**
+ * Description of an artifact.
+ */
+public class SSMArtifact {
+
+    public String groupId;
+    public String artifactId;
+    public String version;
+    public String classifier;
+    public String type;
+
+    public String getRepositoryPath() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(groupId.replace('.', '/'));
+        sb.append('/');
+        sb.append(artifactId);
+        sb.append('/');
+        sb.append(version);
+        sb.append('/');
+        sb.append(artifactId);
+        sb.append('-');
+        sb.append(version);
+        if ( classifier != null ) {
+            sb.append('-');
+            sb.append(classifier);
+        }
+        sb.append('.');
+        sb.append(type);
+        return sb.toString();
+    }
+
+    /**
+     * validates the object and throws an IllegalStateException
+     * This object needs:
+     * - groupId
+     * - artifactId
+     * - version
+     * If type is null, it's set to "jar"
+     * If type is "bundle", it's set to "jar"
+     * - classifier is optional
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        // trim values first
+        if ( groupId != null ) groupId = groupId.trim();
+        if ( artifactId != null ) artifactId = artifactId.trim();
+        if ( version != null ) version = version.trim();
+        if ( type != null ) type = type.trim();
+        if ( classifier != null ) classifier = classifier.trim();
+
+        // check/correct values
+        if ( groupId == null || groupId.isEmpty() ) {
+            throw new IllegalStateException(this + " : groupId");
+        }
+        if ( artifactId == null || artifactId.isEmpty() ) {
+            throw new IllegalStateException(this + " : artifactId");
+        }
+        if ( version == null || version.isEmpty() ) {
+            throw new IllegalStateException(this + " : version");
+        }
+        if ( "bundle".equals(type) || type == null || type.isEmpty() ) {
+            type = "jar";
+        }
+        if ( type == null || type.isEmpty() ) {
+            throw new IllegalStateException(this + " : type");
+        }
+        if ( classifier != null && classifier.isEmpty() ) {
+            classifier = null;
+        }
+    }
+
+    public static SSMArtifact fromMvnUrl(final String url) {
+        // 'mvn:' [ repository-url '!' ] group-id '/' artifact-id [ '/' 
[version] [ '/' [type] [ '/' classifier ] ] ] ]
+        final String content = url.substring(4);
+        // ignore repository url
+        int pos = content.indexOf('!');
+        final String coordinates = (pos == -1 ? content : 
content.substring(pos + 1));
+        final SSMArtifact ad = new SSMArtifact();
+        int part = 0;
+        String value = coordinates;
+        while ( value != null ) {
+            pos = value.indexOf('/');
+            final String current;
+            if ( pos == -1 ) {
+                current = value;
+                value = null;
+            } else {
+                if ( pos == 0 ) {
+                    current = null;
+                } else {
+                    current = value.substring(0, pos);
+                }
+                value = value.substring(pos + 1);
+            }
+            if ( current != null ) {
+                if ( part == 0 ) {
+                    ad.groupId = current;
+                } else if ( part == 1 ) {
+                    ad.artifactId = current;
+                } else if ( part == 2 ) {
+                    ad.version = current;
+                } else if ( part == 3 ) {
+                    ad.type = current;
+                } else if ( part == 4 ) {
+                    ad.classifier = current;
+                }
+            }
+            part++;
+        }
+        if ( ad.version == null ) {
+            ad.version = "LATEST";
+        }
+        if ( ad.type == null || ad.type.length() == 0 || 
ad.type.equals("bundle") ) {
+            ad.type = "jar";
+        }
+        return ad;
+    }
+
+    @Override
+    public String toString() {
+        return "CSArtifact [groupId=" + groupId + ", artifactId=" + artifactId
+                + ", version=" + version + ", classifier=" + classifier
+                + ", type=" + type + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMArtifact.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+
+/**
+ * Configuration
+ */
+public class SSMConfiguration {
+
+    public String pid;
+
+    public String factoryPid;
+
+    public String properties;
+
+    /**
+     * validates the object and throws an IllegalStateException
+     * This object needs:
+     * - pid
+     * - properties
+     * - factoryPid is optional
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        // trim values first
+        if ( pid != null ) pid = pid.trim();
+        if ( factoryPid != null ) factoryPid = factoryPid.trim();
+        if ( properties != null ) properties = properties.trim();
+
+        // check/correct values
+        if ( pid == null || pid.isEmpty() ) {
+            throw new IllegalStateException("pid");
+        }
+        if ( properties == null || properties.isEmpty() ) {
+            throw new IllegalStateException("properties");
+        }
+    }
+
+    public boolean isSpecial() {
+        if ( pid != null && pid.startsWith(":") ) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "CSConfiguration [pid=" + pid + ", factoryPid=" + factoryPid
+                + ", properties=" + properties + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConfiguration.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+
+public abstract class SSMConstants {
+
+    /** Name of the configuration containing the web.xml. */
+    public static final String CFG_WEB_XML = ":web.xml";
+
+    /** Name of the configuration for the bootstrap contents. */
+    public static final String CFG_BOOTSTRAP = ":bootstrap";
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMConstants.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A run mode is a collection of
+ * - artifacts (through start levels)
+ * - configurations
+ * - settings
+ */
+public class SSMRunMode {
+
+    public static final String RUN_MODE_BASE = ":base";
+
+    public static final String RUN_MODE_BOOT = ":boot";
+
+    public static final String RUN_MODE_WEBAPP = ":webapp";
+
+    public static final String RUN_MODE_STANDALONE = ":standalone";
+
+    public String[] runModes;
+
+    public final List<SSMStartLevel> startLevels = new 
ArrayList<SSMStartLevel>();
+
+    public final List<SSMConfiguration> configurations = new 
ArrayList<SSMConfiguration>();
+
+    public SSMSettings settings;
+
+    /**
+     * validates the object and throws an IllegalStateException
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        if ( this.runModes != null ) {
+            boolean hasSpecial = false;
+            final List<String> modes = new ArrayList<String>();
+            for(String m : this.runModes) {
+                if ( m != null ) m = m.trim();
+                if ( m != null && !m.isEmpty()) {
+                    modes.add(m);
+                    if ( m.startsWith(":") ) {
+                        if ( hasSpecial ) {
+                            throw new IllegalStateException("Invalid modes " + 
Arrays.toString(this.runModes));
+                        }
+                        hasSpecial = true;
+                    }
+                }
+            }
+            if ( modes.size() == 0 ) {
+                this.runModes = null;
+            } else {
+                this.runModes = modes.toArray(new String[modes.size()]);
+            }
+        }
+        for(final SSMStartLevel sl : this.startLevels) {
+            sl.validate();
+        }
+        for(final SSMConfiguration c : this.configurations) {
+            c.validate();
+        }
+        if( settings != null ) {
+            if (!this.isSpecial() ) {
+                throw new IllegalStateException("Settings not allowed for 
custom run modes");
+            }
+            settings.validate();
+        }
+    }
+
+    /**
+     * Check if this run mode is active wrt the given set of active run modes.
+     */
+    public boolean isActive(final Set<String> activeRunModes) {
+        boolean active = true;
+        if ( runModes != null ) {
+            for(final String mode : runModes) {
+                if ( !activeRunModes.contains(mode) ) {
+                    active = false;
+                    break;
+                }
+            }
+        }
+        return active;
+    }
+
+    /**
+     * Check whether this run mode is a special run mode
+     */
+    public boolean isSpecial() {
+        if ( runModes != null && runModes.length == 1 && 
runModes[0].startsWith(":") ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if this run mode is a specific, single run mode.
+     */
+    public boolean isRunMode(final String mode) {
+        if ( mode == null && this.runModes == null ) {
+            return true;
+        }
+        if ( mode != null
+             && this.runModes != null
+             && this.runModes.length == 1
+             && this.runModes[0].equals(mode) ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get or create a start level
+     */
+    public SSMStartLevel getOrCreateStartLevel(final int startLevel) {
+        for(final SSMStartLevel sl : this.startLevels) {
+            if ( sl.level == startLevel ) {
+                return sl;
+            }
+        }
+        final SSMStartLevel sl = new SSMStartLevel();
+        sl.level = startLevel;
+        this.startLevels.add(sl);
+        Collections.sort(this.startLevels, new Comparator<SSMStartLevel>() {
+
+            @Override
+            public int compare(SSMStartLevel o1, SSMStartLevel o2) {
+                if ( o1.level < o2.level ) {
+                    return -1;
+                } else if ( o1.level > o2.level ) {
+                    return 1;
+                }
+                return 0;
+            }
+        });
+        return sl;
+    }
+
+    /**
+     * Merge another run mode with this one.
+     */
+    public void merge(final SSMRunMode mode) {
+        for(final SSMStartLevel sl : mode.startLevels) {
+            // search for duplicates in other start levels
+            for(final SSMArtifact artifact : sl.artifacts) {
+                for(final SSMStartLevel mySL : this.startLevels) {
+                    if ( mySL.level == sl.level ) {
+                        continue;
+                    }
+                    final SSMArtifact myArtifact = mySL.search(artifact);
+                    if ( myArtifact != null ) {
+                        mySL.artifacts.remove(myArtifact);
+                    }
+                }
+            }
+
+            final SSMStartLevel mergeSL = this.getOrCreateStartLevel(sl.level);
+            mergeSL.merge(sl);
+        }
+        for(final SSMConfiguration config : mode.configurations) {
+            SSMConfiguration found = null;
+            for(final SSMConfiguration current : this.configurations) {
+                if ( config.factoryPid == null ) {
+                    if ( current.factoryPid == null && 
current.pid.equals(config.pid) ) {
+                        found = current;
+                        break;
+                    }
+                } else {
+                    if ( config.factoryPid.equals(current.factoryPid) && 
current.pid.equals(config.pid) ) {
+                        found = current;
+                        break;
+                    }
+                }
+            }
+            if ( found != null ) {
+                found.properties = config.properties;
+            } else {
+                this.configurations.add(config);
+            }
+        }
+        if ( this.settings == null && mode.settings != null ) {
+            this.settings = new SSMSettings();
+        }
+        if ( mode.settings != null ) {
+            this.settings.merge(mode.settings);
+        }
+    }
+
+    /**
+     * Search a configuration with a pid
+     */
+    public SSMConfiguration getConfiguration(final String pid) {
+        for(final SSMConfiguration c : this.configurations) {
+            if ( pid.equals(c.pid) ) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "CSRunMode [runModes=" + Arrays.toString(runModes)
+                + ", startLevels=" + startLevels + ", configurations="
+                + configurations + ", settings=" + settings + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMRunMode.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+
+/**
+ * The settings of a subsystem.
+ */
+public class SSMSettings {
+
+    public String properties;
+
+    /**
+     * validates the object and throws an IllegalStateException
+     * This object needs:
+     * - properties (non empty)
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        // check/correct values
+        if ( properties == null || properties.isEmpty() ) {
+            throw new IllegalStateException("settings");
+        }
+    }
+
+    public void merge(final SSMSettings other) {
+        if ( this.properties == null ) {
+            this.properties = other.properties;
+        } else {
+            this.properties = this.properties + "\n" + other.properties;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "CSSettings [properties=" + properties + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSettings.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A start level holds a set of bundles.
+ */
+public class SSMStartLevel {
+
+    public int level;
+
+    public final List<SSMArtifact> artifacts = new ArrayList<SSMArtifact>();
+
+    /**
+     * validates the object and throws an IllegalStateException
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        for(final SSMArtifact sl : this.artifacts) {
+            sl.validate();
+        }
+        if ( level < 0 ) {
+            throw new IllegalStateException("level");
+        }
+    }
+
+    /**
+     * Search an artifact with the same groupId, artifactId, version, type and 
classifier.
+     * Version is not considered.
+     */
+    public SSMArtifact search(final SSMArtifact template) {
+        SSMArtifact found = null;
+        for(final SSMArtifact current : this.artifacts) {
+            if ( current.groupId.equals(template.groupId)
+              && current.artifactId.equals(template.artifactId)
+              && current.classifier.equals(template.classifier)
+              && current.type.equals(template.type) ) {
+                found = current;
+                break;
+            }
+        }
+        return found;
+    }
+
+    public void merge(final SSMStartLevel other) {
+        for(final SSMArtifact a : other.artifacts) {
+            final SSMArtifact found = this.search(a);
+            if ( found != null ) {
+                found.version = a.version;
+            } else {
+                this.artifacts.add(a);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "CSStartLevel [level=" + level + ", artifacts=" + artifacts
+                + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A subsystem is a set of run modes and properties.
+ * The properties can be used for specifying artifact versions.
+ * At least it has a "global" run mode which describes the common subsystem.
+ */
+public class SSMSubsystem {
+
+    public final List<SSMRunMode> runModes = new ArrayList<SSMRunMode>();
+
+    public Map<String, String> properties = new HashMap<String, String>();
+
+    public SSMSubsystem() {
+        this.runModes.add(new SSMRunMode()); // global run mode
+    }
+
+    /**
+     * Find the run mode if available
+     * @param runModes
+     * @return The run mode or null.
+     */
+    private SSMRunMode findRunMode(final String[] runModes) {
+        SSMRunMode result = null;
+        for(final SSMRunMode current : this.runModes) {
+            if ( runModes == null && current.runModes == null ) {
+                result = current;
+                break;
+            }
+            if ( runModes != null && current.runModes != null ) {
+                final List<String> a = new 
ArrayList<String>(Arrays.asList(runModes));
+                final List<String> b = new 
ArrayList<String>(Arrays.asList(current.runModes));
+                Collections.sort(a);
+                Collections.sort(b);
+                if ( a.equals(b) ) {
+                    result = current;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Get the run mode if available
+     * @return The run mode or null
+     */
+    public SSMRunMode getRunMode(final String runMode) {
+       return findRunMode(new String[] {runMode});
+    }
+
+    /**
+     * Get or create the run mode.
+     */
+    public SSMRunMode getOrCreateRunMode(final String[] runModes) {
+        SSMRunMode result = findRunMode(runModes);
+        if ( result == null ) {
+            result = new SSMRunMode();
+            result.runModes = runModes;
+            this.runModes.add(result);
+            Collections.sort(this.runModes, new Comparator<SSMRunMode>() {
+
+                @Override
+                public int compare(final SSMRunMode o1, final SSMRunMode o2) {
+                    if ( o1.runModes == null ) {
+                        if ( o2.runModes == null ) {
+                            return 0;
+                        }
+                        return -1;
+                    }
+                    if ( o2.runModes == null ) {
+                        return 1;
+                    }
+                    final List<String> a = new 
ArrayList<String>(Arrays.asList(o1.runModes));
+                    final List<String> b = new 
ArrayList<String>(Arrays.asList(o2.runModes));
+                    Collections.sort(a);
+                    Collections.sort(b);
+
+                    return a.toString().compareTo(b.toString());
+                }
+            });
+        }
+        return result;
+    }
+
+    /**
+     * validates the object and throws an IllegalStateException
+     *
+     * @throws IllegalStateException
+     */
+    public void validate() {
+        for(final SSMRunMode runMode : this.runModes) {
+            runMode.validate();
+        }
+    }
+
+    /**
+     * Replace properties in the string.
+     *
+     * @throws IllegalArgumentException
+     */
+    public String getValue(final String v) {
+        String msg = v;
+        // check for variables
+        int pos = -1;
+        int start = 0;
+        while ( ( pos = msg.indexOf('$', start) ) != -1 ) {
+            if ( msg.length() > pos && msg.charAt(pos + 1) == '{' ) {
+                final int endPos = msg.indexOf('}', pos);
+                if ( endPos == -1 ) {
+                    start = pos + 1;
+                } else {
+                    final String name = msg.substring(pos + 2, endPos);
+                    final String value = this.properties.get(name);
+                    if ( value == null ) {
+                        throw new IllegalArgumentException("Unknown variable: 
" + name);
+                    }
+                    msg = msg.substring(0, pos) + value + msg.substring(endPos 
+ 1);
+                }
+            } else {
+                start = pos + 1;
+            }
+        }
+        return msg;
+    }
+
+    /**
+     * Merge two subsystems.
+     */
+    public void merge(final SSMSubsystem other) {
+        for(final SSMRunMode mode : other.runModes) {
+            final SSMRunMode mergeRunMode = 
this.getOrCreateRunMode(mode.runModes);
+            mergeRunMode.merge(mode);
+        }
+        this.properties.putAll(other.properties);
+    }
+
+    @Override
+    public String toString() {
+        return "SSMSubsystem [runModes=" + runModes + ", properties="
+                + properties + "]";
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/SSMSubsystem.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Version("1.0")
+package org.apache.sling.slingstart.model;
+
+import aQute.bnd.annotation.Version;
+

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/package-info.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,309 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model.xml;
+
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Stack;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.sling.slingstart.model.SSMArtifact;
+import org.apache.sling.slingstart.model.SSMConfiguration;
+import org.apache.sling.slingstart.model.SSMRunMode;
+import org.apache.sling.slingstart.model.SSMSettings;
+import org.apache.sling.slingstart.model.SSMSubsystem;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Simple XML parser for the model.
+ * It ignores all elements in a different namespace than the root element
+ */
+public class XMLSSMModelReader {
+
+    public enum MODE {
+        INIT(null, null),
+        SUBSYSTEM(INIT, "subsystem"),
+
+        PROPERTIES(SUBSYSTEM, "properties"),
+
+        STARTLEVEL(SUBSYSTEM, "startLevel"),
+        ARTIFACT(SUBSYSTEM, "artifact"),
+
+        STARTLEVEL_ARTIFACT(STARTLEVEL, "artifact"),
+
+        CONFIGURATION(SUBSYSTEM, "configuration"),
+        SETTINGS(SUBSYSTEM, "settings"),
+
+        RUNMODE(SUBSYSTEM, "runMode"),
+        RUNMODE_STARTLEVEL(RUNMODE, "startLevel"),
+        RUNMODE_ARTIFACT(RUNMODE, "artifact"),
+        RUNMODE_STARTLEVEL_ARTIFACT(RUNMODE_STARTLEVEL, "artifact"),
+
+        RUNMODE_CONFIGURATION(RUNMODE, "configuration"),
+        RUNMODE_SETTINGS(RUNMODE, "settings");
+
+        public final MODE fromMode;
+        public final String elementName;
+
+        MODE(final MODE fm, final String en) {
+            this.fromMode = fm;
+            this.elementName = en;
+        }
+    }
+
+    /**
+     * Reads the properties file
+     * The reader is not closed.
+     * @throws IOException
+     */
+    public static SSMSubsystem read(final Reader reader)
+    throws IOException {
+        try {
+            final SSMSubsystem result = new SSMSubsystem();
+
+            final SAXParserFactory spf = SAXParserFactory.newInstance();
+            spf.setNamespaceAware(true);
+            SAXParser saxParser = spf.newSAXParser();
+            XMLReader xmlReader = saxParser.getXMLReader();
+            xmlReader.setContentHandler(new ContentHandler() {
+
+                private final Stack<String> elementsStack = new 
Stack<String>();
+
+                /** The current parsing mode. */
+                private MODE mode = MODE.INIT;
+
+                /** String builder to get text from the document. */
+                private StringBuilder text;
+
+                /** The namespace for the read xml elements. */
+                private String namespace;
+
+                /** The run mode */
+                private SSMRunMode runMode;
+
+                /** Current startlevel */
+                private int startLevel;
+
+                /** Current configuration. */
+                private SSMConfiguration configuration;
+
+                @Override
+                public void startElement(final String uri,
+                        final String localName,
+                        final String qName,
+                        final Attributes atts)
+                throws SAXException {
+                    if ( this.mode == MODE.INIT ) {
+                        if ( MODE.SUBSYSTEM.elementName.equals(localName) ) {
+                            this.namespace = uri;
+                            this.mode = MODE.SUBSYSTEM;
+                            this.runMode = result.getOrCreateRunMode(null);
+                            this.startLevel = 0;
+                        } else {
+                            throw new SAXException("Unknown root element (" + 
localName + "). Document must start with " + MODE.SUBSYSTEM.elementName);
+                        }
+                    } else {
+                        if ( (uri == null && this.namespace == null) || (uri 
!= null && uri.equals(this.namespace)) ) {
+                            boolean found = false;
+                            for(final MODE m : MODE.values()) {
+                                if ( this.mode == m.fromMode && 
localName.equals(m.elementName) ) {
+                                    this.mode = m;
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if ( !found ) {
+                                throw new SAXException("Unknown element " + 
localName);
+                            }
+
+                            if ( this.mode == MODE.STARTLEVEL || this.mode == 
MODE.RUNMODE_STARTLEVEL) {
+                                int level = 0;
+                                final String levelVal = atts.getValue("level");
+                                if ( levelVal != null ) {
+                                    level = Integer.valueOf(levelVal);
+                                }
+                                this.startLevel = level;
+                            } else if ( this.mode == MODE.ARTIFACT || 
this.mode == MODE.RUNMODE_ARTIFACT || this.mode == MODE.STARTLEVEL_ARTIFACT || 
this.mode == MODE.RUNMODE_STARTLEVEL_ARTIFACT) {
+                                final SSMArtifact artifact = new SSMArtifact();
+                                
this.runMode.getOrCreateStartLevel(this.startLevel).artifacts.add(artifact);
+                                artifact.groupId = atts.getValue("groupId");
+                                artifact.artifactId = 
atts.getValue("artifactId");
+                                artifact.version = atts.getValue("version");
+                                artifact.type = atts.getValue("type");
+                                artifact.classifier = 
atts.getValue("classifier");
+                            } else if ( this.mode == MODE.CONFIGURATION || 
this.mode == MODE.RUNMODE_CONFIGURATION) {
+                                this.configuration = new SSMConfiguration();
+                                this.configuration.pid = atts.getValue("pid");
+                                this.configuration.factoryPid = 
atts.getValue("factory");
+                                
this.runMode.configurations.add(this.configuration);
+                                this.text = new StringBuilder();
+                            } else if ( this.mode == MODE.SETTINGS || 
this.mode == MODE.RUNMODE_SETTINGS) {
+                                if ( this.runMode.settings != null ) {
+                                    throw new SAXException("Duplicate settings 
section");
+                                }
+                                this.runMode.settings = new SSMSettings();
+                                this.text = new StringBuilder();
+
+                            } else if ( this.mode == MODE.RUNMODE ) {
+                                final String runMode = atts.getValue("modes");
+                                if ( runMode == null || 
runMode.trim().length() == 0 ) {
+                                    throw new SAXException("Required attribute 
runModes missing for runMode element");
+                                }
+                                this.runMode = 
result.getOrCreateRunMode(runMode.split(","));
+                                this.startLevel = 0;
+
+                            } else {
+                                this.text = new StringBuilder();
+                            }
+                        }
+                    }
+                    elementsStack.push(localName);
+                }
+
+                @Override
+                public void endElement(final String uri, final String 
localName, final String qName)
+                throws SAXException {
+                    final String openElement = this.elementsStack.pop();
+                    if ( !openElement.equals(localName) ) {
+                        throw new SAXException("Invalid document - expected 
closing " + openElement + " but received " + localName);
+                    }
+                    if ( (uri == null && this.namespace == null) || (uri != 
null && uri.equals(this.namespace)) ) {
+                        String textValue = (text != null ? text.toString() : 
null);
+                        if ( textValue != null ) {
+                            textValue = textValue.trim();
+                            if ( textValue.length() == 0 ) {
+                                textValue = null;
+                            }
+                        }
+                        text = null;
+                        boolean found = false;
+                        final MODE prevMode = this.mode;
+                        for(final MODE m : MODE.values()) {
+                            if ( this.mode == m && 
localName.equals(m.elementName) ) {
+                                this.mode = m.fromMode;
+                                found = true;
+                                break;
+                            }
+                        }
+                        if ( !found ) {
+                            throw new SAXException("Unknown element " + 
localName);
+                        }
+                        if ( prevMode == MODE.STARTLEVEL || prevMode == 
MODE.RUNMODE_STARTLEVEL ) {
+                            this.startLevel = 0;
+                        } else if ( prevMode == MODE.CONFIGURATION || prevMode 
== MODE.RUNMODE_CONFIGURATION ) {
+                            this.configuration.properties = textValue;
+                            this.configuration = null;
+                        } else if ( prevMode == MODE.SETTINGS || prevMode == 
MODE.RUNMODE_SETTINGS) {
+                            this.runMode.settings.properties = textValue;
+                        } else if ( prevMode == MODE.RUNMODE ) {
+                            this.runMode = result.getOrCreateRunMode(null);
+                            this.startLevel = 0;
+                        } else if ( prevMode == MODE.PROPERTIES ) {
+                            final LineNumberReader reader = new 
LineNumberReader(new StringReader(textValue));
+                            String line = null;
+                            try {
+                                while ( (line = reader.readLine()) != null ) {
+                                    final int pos = line.indexOf("=");
+                                    if ( pos == -1 || line.indexOf("=", pos + 
1 ) != -1 ) {
+                                        throw new SAXException("Invalid 
property definition: " + line);
+                                    }
+                                    result.properties.put(line.substring(0, 
pos), line.substring(pos + 1));
+                                }
+                            } catch (final IOException io) {
+                                throw new SAXException(io);
+                            }
+                        }
+                    }
+                }
+
+                @Override
+                public void characters(final char[] ch, final int start, final 
int length)
+                        throws SAXException {
+                    if ( text != null ) {
+                        text.append(ch, start, length);
+                    }
+                }
+
+                @Override
+                public void startDocument() throws SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void skippedEntity(final String name) throws 
SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void setDocumentLocator(final Locator locator) {
+                    // nothing to do
+                }
+
+                @Override
+                public void processingInstruction(final String target, final 
String data)
+                        throws SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void ignorableWhitespace(final char[] ch, final int 
start,final  int length)
+                throws SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void startPrefixMapping(final String prefix, final 
String uri)
+                throws SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void endPrefixMapping(final String prefix) throws 
SAXException {
+                    // nothing to do
+                }
+
+                @Override
+                public void endDocument() throws SAXException {
+                    // nothing to do
+                }
+
+            });
+            xmlReader.parse(new InputSource(reader));
+
+            try {
+                result.validate();
+            } catch ( final IllegalStateException ise) {
+                throw (IOException)new IOException("Invalid subsystem 
definition: " + ise.getMessage()).initCause(ise);
+            }
+            return result;
+        } catch ( final SAXException se) {
+            throw new IOException(se);
+        } catch ( final ParserConfigurationException pce ) {
+            throw new IOException(pce);
+        }
+    }
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.slingstart.model.xml;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.sling.slingstart.model.SSMArtifact;
+import org.apache.sling.slingstart.model.SSMConfiguration;
+import org.apache.sling.slingstart.model.SSMRunMode;
+import org.apache.sling.slingstart.model.SSMStartLevel;
+import org.apache.sling.slingstart.model.SSMSubsystem;
+
+/**
+ * Simple writer for the a model
+ */
+public class XMLSSMModelWriter {
+
+    private static void printRunModeAttribute(final PrintWriter pw, final 
SSMRunMode rmd) {
+        if ( rmd.runModes != null && rmd.runModes.length > 0 ) {
+            pw.print(" modes=\"");
+            boolean first = true;
+            for(final String mode : rmd.runModes) {
+                if ( first ) {
+                    first = false;
+                } else {
+                    pw.print(",");
+                }
+                pw.print(escapeXml(mode));
+            }
+            pw.print("\"");
+        }
+
+    }
+
+    private static String INDENT = "    ";
+
+
+    /**
+     * Writes the model to the writer.
+     * The writer is not closed.
+     * @param writer
+     * @param subystem
+     * @throws IOException
+     */
+    public static void write(final Writer writer, final SSMSubsystem subsystem)
+    throws IOException {
+        final PrintWriter pw = new PrintWriter(writer);
+        pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        pw.println("<subsystem>");
+
+        // properties
+        if ( subsystem.properties.size() > 0 ) {
+            pw.print(INDENT);
+            pw.println("<properties><![CDATA[");
+            for(final Map.Entry<String, String> entry : 
subsystem.properties.entrySet()) {
+                pw.print(INDENT);
+                pw.print(INDENT);
+                pw.print(entry.getKey());
+                pw.print("=");
+                pw.println(entry.getValue());
+            }
+            pw.print(INDENT);
+            pw.println("]]></properties>");
+        }
+        for(final SSMRunMode runMode : subsystem.runModes) {
+            // TODO - don't write out empty run modes
+            String indent = INDENT;
+            if ( runMode.runModes != null ) {
+                pw.print(indent);
+                pw.print("<runMode");
+                printRunModeAttribute(pw, runMode);
+                pw.println(">");
+                indent = indent + INDENT;
+            }
+
+            for(final SSMStartLevel startLevel : runMode.startLevels) {
+                if ( startLevel.artifacts.size() == 0 ) {
+                    continue;
+                }
+                if ( startLevel.level != 0 ) {
+                    pw.print(indent);
+                    pw.print("<startLevel");
+                    pw.print(" level=\"");
+                    pw.print(String.valueOf(startLevel.level));
+                    pw.print("\"");
+                    pw.println(">");
+                    indent += INDENT;
+                }
+                for(final SSMArtifact ad : startLevel.artifacts) {
+                    pw.print(indent);
+                    pw.print("<artifact groupId=\"");
+                    pw.print(escapeXml(ad.groupId));
+                    pw.print("\" artifactId=\"");
+                    pw.print(escapeXml(ad.artifactId));
+                    pw.print("\" version=\"");
+                    pw.print(escapeXml(ad.version));
+                    pw.print("\"");
+                    if ( !"jar".equals(ad.type) ) {
+                        pw.print(" type=\"");
+                        pw.print(escapeXml(ad.type));
+                        pw.print("\"");
+                    }
+                    if ( ad.classifier != null ) {
+                        pw.print(" classifier=\"");
+                        pw.print(escapeXml(ad.classifier));
+                        pw.print("\"");
+                    }
+                    pw.println("/>");
+                }
+                if ( startLevel.level != 0 ) {
+                    indent = indent.substring(0, indent.length() - 
INDENT.length());
+                    pw.print(indent);
+                    pw.println("</startLevel>");
+                }
+            }
+
+            for(final SSMConfiguration config : runMode.configurations) {
+                pw.print(indent);
+                pw.print("<configuration ");
+                if ( config.factoryPid != null ) {
+                    pw.print("factory=\"");
+                    pw.print(escapeXml(config.factoryPid));
+                    pw.print("\" ");
+                }
+                pw.print("pid=\"");
+                pw.print(escapeXml(config.pid));
+                pw.println("\"><![CDATA[");
+                pw.println(config.properties);
+                pw.print(indent);
+                pw.println("]]></configuration>");
+            }
+
+            if ( runMode.settings != null ) {
+                pw.print(indent);
+                pw.println("<settings><![CDATA[");
+                pw.println(runMode.settings.properties);
+                pw.print(indent);
+                pw.println("]]></settings>");
+            }
+
+            if ( runMode.runModes != null ) {
+                indent = indent.substring(0, indent.length() - 
INDENT.length());
+                pw.print(indent);
+                pw.println("</runMode>");
+            }
+        }
+
+        pw.println("</subsystem>");
+    }
+
+    /** Escape xml text */
+    private static String escapeXml(final String input) {
+        if (input == null) {
+            return null;
+        }
+
+        final StringBuilder b = new StringBuilder(input.length());
+        for(int i = 0;i  < input.length(); i++) {
+            final char c = input.charAt(i);
+            if(c == '&') {
+                b.append("&amp;");
+            } else if(c == '<') {
+                b.append("&lt;");
+            } else if(c == '>') {
+                b.append("&gt;");
+            } else if(c == '"') {
+                b.append("&quot;");
+            } else if(c == '\'') {
+                b.append("&apos;");
+            } else {
+                b.append(c);
+            }
+        }
+        return b.toString();
+    }
+
+}

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelWriter.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java?rev=1626138&view=auto
==============================================================================
--- 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
 (added)
+++ 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
 Fri Sep 19 08:07:31 2014
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Version("1.0")
+package org.apache.sling.slingstart.model.xml;
+
+import aQute.bnd.annotation.Version;
+

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/tooling/support/slingstart-model/src/main/java/org/apache/sling/slingstart/model/xml/package-info.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url


Reply via email to