You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:57:07 UTC

[sling-org-apache-sling-provisioning-model] 11/34: Add merger utility and variable replacement

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.provisioning.model-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-provisioning-model.git

commit 7bee16aa0a2e668f17a6929c57d4d3ffab3da905
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Sep 26 16:49:06 2014 +0000

    Add merger utility and variable replacement
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/slingstart-model@1627825 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/slingstart/model/SSMDeliverable.java     |  54 +++-------
 .../apache/sling/slingstart/model/SSMFeature.java  |  33 ------
 .../apache/sling/slingstart/model/SSMMerger.java   |  82 +++++++++++++++
 .../sling/slingstart/model/SSMStartLevel.java      |  10 --
 .../org/apache/sling/slingstart/model/SSMUtil.java | 115 +++++++++++++++++++++
 .../sling/slingstart/model/SSMValidator.java       |   4 +-
 .../slingstart/model/txt/TXTSSMModelReader.java    |   5 +
 .../slingstart/model/xml/XMLSSMModelReader.java    |   6 --
 8 files changed, 217 insertions(+), 92 deletions(-)

diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMDeliverable.java b/src/main/java/org/apache/sling/slingstart/model/SSMDeliverable.java
index a931981..472c40b 100644
--- a/src/main/java/org/apache/sling/slingstart/model/SSMDeliverable.java
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMDeliverable.java
@@ -33,10 +33,15 @@ import java.util.Map;
  */
 public class SSMDeliverable extends SSMTraceable {
 
+    /** All features. */
     private final List<SSMFeature> features = new ArrayList<SSMFeature>();
 
+    /** Variables. */
     private final Map<String, String> variables = new HashMap<String, String>();
 
+    /**
+     * Construct a new deliverable.
+     */
     public SSMDeliverable() {
         this.features.add(new SSMFeature(null)); // global features
     }
@@ -60,6 +65,7 @@ public class SSMDeliverable extends SSMTraceable {
 
     /**
      * Get the feature if available
+     * @param runmode The single run mode.
      * @return The feature or null
      */
     public SSMFeature getRunMode(final String runMode) {
@@ -68,6 +74,8 @@ public class SSMDeliverable extends SSMTraceable {
 
     /**
      * Get or create the feature.
+     * @param runModes The run modes.
+     * @return The feature for the given run modes.
      */
     public SSMFeature getOrCreateFeature(final String[] runModes) {
         SSMFeature result = findFeature(runModes);
@@ -79,49 +87,13 @@ public class SSMDeliverable extends SSMTraceable {
         return result;
     }
 
-    public List<SSMFeature> getFeatures() {
-        return this.features;
-    }
-
     /**
-     * Replace properties in the string.
-     *
-     * @throws IllegalArgumentException
+     * Return all features.
+     * The returned list is modifiable and directly modifies the model.
+     * @return The list of features.
      */
-    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.variables.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 deliverables.
-     */
-    public void merge(final SSMDeliverable other) {
-        for(final SSMFeature mode : other.features) {
-            final SSMFeature mergeFeature = this.getOrCreateFeature(mode.getRunModes());
-            mergeFeature.merge(mode);
-        }
-        this.variables.putAll(other.variables);
+    public List<SSMFeature> getFeatures() {
+        return this.features;
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMFeature.java b/src/main/java/org/apache/sling/slingstart/model/SSMFeature.java
index 0a8e175..d81cd6c 100644
--- a/src/main/java/org/apache/sling/slingstart/model/SSMFeature.java
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMFeature.java
@@ -19,7 +19,6 @@ package org.apache.sling.slingstart.model;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -133,38 +132,6 @@ public class SSMFeature
     }
 
     /**
-     * Merge another feature with this one.
-     */
-    public void merge(final SSMFeature mode) {
-        for(final SSMStartLevel sl : mode.startLevels) {
-            // search for duplicates in other start levels
-            for(final SSMArtifact artifact : sl.getArtifacts()) {
-                for(final SSMStartLevel mySL : this.startLevels) {
-                    if ( mySL.getLevel() == sl.getLevel() ) {
-                        continue;
-                    }
-                    final SSMArtifact myArtifact = mySL.search(artifact);
-                    if ( myArtifact != null ) {
-                        mySL.getArtifacts().remove(myArtifact);
-                    }
-                }
-            }
-
-            final SSMStartLevel mergeSL = this.getOrCreateStartLevel(sl.getLevel());
-            mergeSL.merge(sl);
-        }
-        for(final SSMConfiguration config : mode.configurations) {
-            final SSMConfiguration found = getOrCreateConfiguration(config.getPid(), config.getFactoryPid());
-            final Enumeration<String> e = config.getProperties().keys();
-            while ( e.hasMoreElements() ) {
-                final String key = e.nextElement();
-                found.getProperties().put(key, config.getProperties().get(key));
-            }
-        }
-        this.settings.putAll(mode.settings);
-    }
-
-    /**
      * Search a configuration with a pid
      */
     public SSMConfiguration getConfiguration(final String pid) {
diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMMerger.java b/src/main/java/org/apache/sling/slingstart/model/SSMMerger.java
new file mode 100644
index 0000000..09e9ad8
--- /dev/null
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMMerger.java
@@ -0,0 +1,82 @@
+/*
+ * 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.Enumeration;
+
+
+/**
+ * Merge two models
+ */
+public abstract class SSMMerger {
+
+    /**
+     * Merge the additional model into the base model.
+     * @param base The base model.
+     * @param additional The additional model.
+     */
+    public static void merge(final SSMDeliverable base, final SSMDeliverable additional) {
+        // features
+        for(final SSMFeature additionlFeature : additional.getFeatures()) {
+            final SSMFeature baseFeature = base.getOrCreateFeature(additionlFeature.getRunModes());
+
+            // start levels
+            for(final SSMStartLevel additionalStartLevel : additionlFeature.getStartLevels()) {
+                // search for duplicates in other start levels
+                for(final SSMArtifact artifact : additionalStartLevel.getArtifacts()) {
+                    for(final SSMStartLevel mySL : baseFeature.getStartLevels()) {
+                        if ( mySL.getLevel() == additionalStartLevel.getLevel() ) {
+                            continue;
+                        }
+                        final SSMArtifact myArtifact = mySL.search(artifact);
+                        if ( myArtifact != null ) {
+                            mySL.getArtifacts().remove(myArtifact);
+                        }
+                    }
+                }
+
+                // now merge current level
+                final SSMStartLevel baseStartLevel = baseFeature.getOrCreateStartLevel(additionalStartLevel.getLevel());
+
+                // artifacts
+                for(final SSMArtifact a : additionalStartLevel.getArtifacts()) {
+                    final SSMArtifact found = baseStartLevel.search(a);
+                    if ( found != null ) {
+                        baseStartLevel.getArtifacts().remove(found);
+                    }
+                    baseStartLevel.getArtifacts().add(a);
+                }
+            }
+
+            // configurations
+            for(final SSMConfiguration config : additionlFeature.getConfigurations()) {
+                final SSMConfiguration found = baseFeature.getOrCreateConfiguration(config.getPid(), config.getFactoryPid());
+                final Enumeration<String> e = config.getProperties().keys();
+                while ( e.hasMoreElements() ) {
+                    final String key = e.nextElement();
+                    found.getProperties().put(key, config.getProperties().get(key));
+                }
+            }
+
+            // settings
+            baseFeature.getSettings().putAll(additionlFeature.getSettings());
+        }
+
+        // variables
+        base.getVariables().putAll(additional.getVariables());
+    }
+}
diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java b/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
index 572bab0..dbad45e 100644
--- a/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMStartLevel.java
@@ -60,16 +60,6 @@ public class SSMStartLevel extends SSMTraceable
         return found;
     }
 
-    public void merge(final SSMStartLevel other) {
-        for(final SSMArtifact a : other.artifacts) {
-            final SSMArtifact found = this.search(a);
-            if ( found != null ) {
-                this.artifacts.remove(found);
-            }
-            this.artifacts.add(a);
-        }
-    }
-
     @Override
     public int compareTo(final SSMStartLevel o) {
         if ( this.level < o.level ) {
diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMUtil.java b/src/main/java/org/apache/sling/slingstart/model/SSMUtil.java
new file mode 100644
index 0000000..e600690
--- /dev/null
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMUtil.java
@@ -0,0 +1,115 @@
+/*
+ * 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.Enumeration;
+import java.util.Map;
+
+/**
+ * Utility methods
+ */
+public abstract class SSMUtil {
+
+    /**
+     * Replace all variables in the model and return a new model with the replaced values.
+     * @param base The base model.
+     * @return The model with replaced variables.
+     * @throws IllegalArgumentException If a variable can't be replaced.
+     */
+    public static SSMDeliverable getEffectiveModel(final SSMDeliverable base) {
+        final SSMDeliverable result = new SSMDeliverable();
+        result.setComment(base.getComment());
+        result.setLocation(base.getLocation());
+        result.getVariables().putAll(base.getVariables());
+
+        for(final SSMFeature feature : base.getFeatures()) {
+            final SSMFeature newFeature = result.getOrCreateFeature(feature.getRunModes());
+            newFeature.setComment(feature.getComment());
+            newFeature.setLocation(feature.getLocation());
+
+            for(final SSMStartLevel startLevel : feature.getStartLevels()) {
+                final SSMStartLevel newStartLevel = newFeature.getOrCreateStartLevel(startLevel.getLevel());
+                newStartLevel.setComment(startLevel.getComment());
+                newStartLevel.setLocation(startLevel.getLocation());
+
+                for(final SSMArtifact artifact : startLevel.getArtifacts()) {
+                    final SSMArtifact newArtifact = new SSMArtifact(replace(base, artifact.getGroupId()),
+                            replace(base, artifact.getArtifactId()),
+                            replace(base, artifact.getVersion()),
+                            replace(base, artifact.getClassifier()),
+                            replace(base, artifact.getType()));
+                    newArtifact.setComment(artifact.getComment());
+                    newArtifact.setLocation(artifact.getLocation());
+
+                    newStartLevel.getArtifacts().add(newArtifact);
+                }
+            }
+
+            for(final SSMConfiguration config : feature.getConfigurations()) {
+                final SSMConfiguration newConfig = new SSMConfiguration(config.getPid(), config.getFactoryPid());
+                newConfig.setComment(config.getComment());
+                newConfig.setLocation(config.getLocation());
+
+                final Enumeration<String> i = config.getProperties().keys();
+                while ( i.hasMoreElements() ) {
+                    final String key = i.nextElement();
+                    newConfig.getProperties().put(key, config.getProperties().get(key));
+                }
+
+                newFeature.getConfigurations().add(newConfig);
+            }
+
+            for(final Map.Entry<String, String> entry : feature.getSettings().entrySet() ) {
+                newFeature.getSettings().put(entry.getKey(), replace(base, entry.getValue()));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Replace properties in the string.
+     *
+     * @throws IllegalArgumentException
+     */
+    private static String replace(final SSMDeliverable base, final String v) {
+        if ( v == null ) {
+            return null;
+        }
+        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 = base.getVariables().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;
+    }
+}
diff --git a/src/main/java/org/apache/sling/slingstart/model/SSMValidator.java b/src/main/java/org/apache/sling/slingstart/model/SSMValidator.java
index 1ccb94f..b5ee003 100644
--- a/src/main/java/org/apache/sling/slingstart/model/SSMValidator.java
+++ b/src/main/java/org/apache/sling/slingstart/model/SSMValidator.java
@@ -23,14 +23,14 @@ import java.util.Map;
 /**
  * Validate a complete model.
  */
-public class SSMValidator {
+public abstract class SSMValidator {
 
     /**
      * Validates the model.
      * @param model
      * @return
      */
-    public Map<SSMTraceable, String> validate(final SSMDeliverable model) {
+    public static Map<SSMTraceable, String> validate(final SSMDeliverable model) {
         final Map<SSMTraceable, String> errors = new HashMap<SSMTraceable, String>();
 
         for(final SSMFeature feature : model.getFeatures() ) {
diff --git a/src/main/java/org/apache/sling/slingstart/model/txt/TXTSSMModelReader.java b/src/main/java/org/apache/sling/slingstart/model/txt/TXTSSMModelReader.java
index c41262d..bd439bd 100644
--- a/src/main/java/org/apache/sling/slingstart/model/txt/TXTSSMModelReader.java
+++ b/src/main/java/org/apache/sling/slingstart/model/txt/TXTSSMModelReader.java
@@ -142,6 +142,10 @@ public class TXTSSMModelReader {
             } else if ( trimmedLine.startsWith("config:FELIX ") || trimmedLine.startsWith("config: ") ) {
                 checkConfig();
 
+                if ( feature == null ) {
+                    throw new IOException("configuration outside of feature in line " + this.lineNumberReader.getLineNumber());
+                }
+
                 mode = MODE.CONFIGURATION;
                 final int factoryPos = params.indexOf('-');
                 if ( factoryPos == -1 ) {
@@ -150,6 +154,7 @@ public class TXTSSMModelReader {
                     config = new SSMConfiguration(params.substring(pos + 1), params.substring(0, pos));
                 }
                 this.init(config);
+                feature.getConfigurations().add(config);
                 configBuilder = new StringBuilder();
                 configFelixFormat = trimmedLine.startsWith("config:FELIX ");
 
diff --git a/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java b/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
index bec89cc..a95665a 100644
--- a/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
+++ b/src/main/java/org/apache/sling/slingstart/model/xml/XMLSSMModelReader.java
@@ -36,8 +36,6 @@ import org.apache.sling.slingstart.model.SSMArtifact;
 import org.apache.sling.slingstart.model.SSMConfiguration;
 import org.apache.sling.slingstart.model.SSMDeliverable;
 import org.apache.sling.slingstart.model.SSMFeature;
-import org.apache.sling.slingstart.model.SSMTraceable;
-import org.apache.sling.slingstart.model.SSMValidator;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
@@ -348,10 +346,6 @@ public class XMLSSMModelReader {
             });
             xmlReader.parse(new InputSource(reader));
 
-            final Map<SSMTraceable, String> errors = new SSMValidator().validate(result);
-            if ( errors != null ) {
-                throw new IOException("Invalid model definition: " + errors);
-            }
             return result;
         } catch ( final SAXException se) {
             throw new IOException(se);

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.