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:58:06 UTC
[sling-org-apache-sling-provisioning-model] 08/16: SLING-4879
refactor model processing logic from ModelUtility#getEffectiveModel into
separate class to make it reusable
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.3.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-provisioning-model.git
commit 6a392fa3ab5e6809a2806c57476ce9e363ffdb17
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Tue Jul 14 09:04:19 2015 +0000
SLING-4879 refactor model processing logic from ModelUtility#getEffectiveModel into separate class to make it reusable
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/provisioning-model@1690878 13f79535-47bb-0310-9956-ffa450edef68
---
.../model/EffectiveModelProcessor.java | 77 ++++++++
.../sling/provisioning/model/ModelProcessor.java | 105 ++++++++++
.../sling/provisioning/model/ModelUtility.java | 92 ++-------
.../provisioning/model/ModelProcessorTest.java | 212 +++++++++++++++++++++
4 files changed, 407 insertions(+), 79 deletions(-)
diff --git a/src/main/java/org/apache/sling/provisioning/model/EffectiveModelProcessor.java b/src/main/java/org/apache/sling/provisioning/model/EffectiveModelProcessor.java
new file mode 100644
index 0000000..e52c6c2
--- /dev/null
+++ b/src/main/java/org/apache/sling/provisioning/model/EffectiveModelProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.provisioning.model;
+
+import java.util.Map.Entry;
+
+import org.apache.sling.provisioning.model.ModelUtility.ResolverOptions;
+import org.apache.sling.provisioning.model.ModelUtility.VariableResolver;
+
+class EffectiveModelProcessor extends ModelProcessor {
+
+ private final ResolverOptions options;
+
+ public EffectiveModelProcessor(ResolverOptions options) {
+ if (options == null) {
+ throw new IllegalArgumentException("Resolver options is null");
+ }
+ this.options = options;
+ }
+
+ @Override
+ protected Artifact processArtifact(Artifact artifact, Feature newFeature, RunMode newRunMode) {
+ final String groupId = ModelUtility.replace(newFeature, artifact.getGroupId(), options.getVariableResolver());
+ final String artifactId = ModelUtility.replace(newFeature, artifact.getArtifactId(), options.getVariableResolver());
+ final String version = ModelUtility.replace(newFeature, artifact.getVersion(), options.getVariableResolver());
+ final String classifier = ModelUtility.replace(newFeature, artifact.getClassifier(), options.getVariableResolver());
+ final String type = ModelUtility.replace(newFeature, artifact.getType(), options.getVariableResolver());
+ final String resolvedVersion = ModelUtility.resolveArtifactVersion(groupId, artifactId, version, classifier, type,
+ options.getArtifactVersionResolver());
+ return new Artifact(groupId, artifactId, resolvedVersion, classifier, type);
+ }
+
+ @Override
+ protected Configuration processConfiguration(Configuration config, Feature newFeature, RunMode newRunMode) {
+ Configuration newConfig = new Configuration(config.getPid(), config.getFactoryPid());
+ ModelUtility.getProcessedConfiguration(newFeature, newConfig, config, options.getVariableResolver());
+ return newConfig;
+ }
+
+ @Override
+ protected KeyValueMap<String> processSettings(KeyValueMap<String> settings, final Feature newFeature, final RunMode newRunMode) {
+ KeyValueMap<String> newSettings = new KeyValueMap<String>();
+ for (final Entry<String, String> entry : settings) {
+ newSettings.put(entry.getKey(), ModelUtility.replace(newFeature, entry.getValue(),
+ new VariableResolver() {
+ @Override
+ public String resolve(final Feature feature, final String name) {
+ if ( "sling.home".equals(name) ) {
+ return "${sling.home}";
+ }
+ if ( options.getVariableResolver() != null ) {
+ return options.getVariableResolver().resolve(newFeature, name);
+ }
+ return newFeature.getVariables().get(name);
+ }
+ }));
+ }
+ return newSettings;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java b/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java
new file mode 100644
index 0000000..59b952f
--- /dev/null
+++ b/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java
@@ -0,0 +1,105 @@
+/*
+ * 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.provisioning.model;
+
+import java.util.Enumeration;
+
+/**
+ * Allows to process a value. A new value is created and for each part in the model a process
+ * method is called. Subclasses can overwrite those methods to inject specific behavior.
+ * The processor itself does not change anything in the model.
+ */
+class ModelProcessor {
+
+ /**
+ * Creates a copy of the model and calls a process method for each part found in the model.
+ * This allows to modify the parts content (e.g. replace variables), but not to add or remove parts.
+ * @param model The base model.
+ * @return The processed and copied model.
+ */
+ public final Model process(final Model model) {
+ final Model result = new Model();
+ result.setLocation(model.getLocation());
+
+ for(final Feature feature : model.getFeatures()) {
+ final Feature newFeature = result.getOrCreateFeature(feature.getName());
+ newFeature.setComment(feature.getComment());
+ newFeature.setLocation(feature.getLocation());
+
+ newFeature.getVariables().setComment(feature.getVariables().getComment());
+ newFeature.getVariables().setLocation(feature.getVariables().getLocation());
+ newFeature.getVariables().putAll(processVariables(feature.getVariables(), feature));
+
+ for(final RunMode runMode : feature.getRunModes()) {
+ final RunMode newRunMode = newFeature.getOrCreateRunMode(runMode.getNames());
+ newRunMode.setLocation(runMode.getLocation());
+
+ for(final ArtifactGroup group : runMode.getArtifactGroups()) {
+ final ArtifactGroup newGroup = newRunMode.getOrCreateArtifactGroup(group.getStartLevel());
+ newGroup.setComment(group.getComment());
+ newGroup.setLocation(group.getLocation());
+
+ for(final Artifact artifact : group) {
+ final Artifact newArtifact = processArtifact(artifact, newFeature, newRunMode);
+ newArtifact.setComment(artifact.getComment());
+ newArtifact.setLocation(artifact.getLocation());
+ newGroup.add(newArtifact);
+ }
+ }
+
+ newRunMode.getConfigurations().setComment(runMode.getConfigurations().getComment());
+ newRunMode.getConfigurations().setLocation(runMode.getConfigurations().getLocation());
+ for(final Configuration config : runMode.getConfigurations()) {
+ final Configuration processedConfig = processConfiguration(config, newFeature, newRunMode);
+ final Configuration newConfig = newRunMode.getOrCreateConfiguration(processedConfig.getPid(), processedConfig.getFactoryPid());
+ newConfig.setLocation(config.getLocation());
+ newConfig.setComment(config.getComment());
+ final Enumeration<String> i = processedConfig.getProperties().keys();
+ while ( i.hasMoreElements() ) {
+ final String key = i.nextElement();
+ newConfig.getProperties().put(key, processedConfig.getProperties().get(key));
+ }
+ }
+
+ newRunMode.getSettings().setComment(runMode.getSettings().getComment());
+ newRunMode.getSettings().setLocation(runMode.getSettings().getLocation());
+ newRunMode.getSettings().putAll(processSettings(runMode.getSettings(), newFeature, newRunMode));
+ }
+
+ }
+ return result;
+ }
+
+ protected KeyValueMap<String> processVariables(KeyValueMap<String> variables, Feature feature) {
+ return variables;
+ }
+
+ protected Artifact processArtifact(Artifact artifact, Feature newFeature, RunMode newRunMode) {
+ return artifact;
+ }
+
+ protected Configuration processConfiguration(Configuration config, Feature newFeature, RunMode newRunMode) {
+ return config;
+ }
+
+ protected KeyValueMap<String> processSettings(KeyValueMap<String> settings, Feature newFeature, RunMode newRunMode) {
+ return settings;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java b/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java
index 598e70e..09428de 100644
--- a/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java
+++ b/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java
@@ -314,24 +314,25 @@ public abstract class ModelUtility {
/**
* Replace all variables in the model and return a new model with the replaced values.
* @param model The base model.
+ * @param resolver Optional variable resolver.
* @return The model with replaced variables.
* @throws IllegalArgumentException If a variable can't be replaced or configuration properties can't be parsed
+ * @deprecated Use {@link #getEffectiveModel(Model)} or {@link #getEffectiveModel(Model, ResolverOptions)} instead
*/
- public static Model getEffectiveModel(final Model model) {
- return getEffectiveModel(model, new ResolverOptions());
+ @Deprecated
+ public static Model getEffectiveModel(final Model model, final VariableResolver resolver) {
+ return getEffectiveModel(model, new ResolverOptions().variableResolver(resolver));
}
/**
* Replace all variables in the model and return a new model with the replaced values.
* @param model The base model.
- * @param resolver Optional variable resolver.
* @return The model with replaced variables.
* @throws IllegalArgumentException If a variable can't be replaced or configuration properties can't be parsed
- * @deprecated Use {@link #getEffectiveModel(Model, ResolverOptions)} instead
+ * @since 1.3
*/
- @Deprecated
- public static Model getEffectiveModel(final Model model, final VariableResolver resolver) {
- return getEffectiveModel(model, new ResolverOptions().variableResolver(resolver));
+ public static Model getEffectiveModel(final Model model) {
+ return getEffectiveModel(model, new ResolverOptions());
}
/**
@@ -340,79 +341,11 @@ public abstract class ModelUtility {
* @param options Resolver options.
* @return The model with replaced variables.
* @throws IllegalArgumentException If a variable can't be replaced or configuration properties can't be parsed
+ * @since 1.3
*/
public static Model getEffectiveModel(final Model model, final ResolverOptions options) {
- if (options == null) {
- throw new IllegalArgumentException("Resolver options is null");
- }
-
- final Model result = new Model();
- result.setLocation(model.getLocation());
-
- for(final Feature feature : model.getFeatures()) {
- final Feature newFeature = result.getOrCreateFeature(feature.getName());
- newFeature.setComment(feature.getComment());
- newFeature.setLocation(feature.getLocation());
-
- newFeature.getVariables().setComment(feature.getVariables().getComment());
- newFeature.getVariables().setLocation(feature.getVariables().getLocation());
- newFeature.getVariables().putAll(feature.getVariables());
-
- for(final RunMode runMode : feature.getRunModes()) {
- final RunMode newRunMode = newFeature.getOrCreateRunMode(runMode.getNames());
- newRunMode.setLocation(runMode.getLocation());
-
- for(final ArtifactGroup group : runMode.getArtifactGroups()) {
- final ArtifactGroup newGroup = newRunMode.getOrCreateArtifactGroup(group.getStartLevel());
- newGroup.setComment(group.getComment());
- newGroup.setLocation(group.getLocation());
-
- for(final Artifact artifact : group) {
- final String groupId = replace(newFeature, artifact.getGroupId(), options.getVariableResolver());
- final String artifactId = replace(newFeature, artifact.getArtifactId(), options.getVariableResolver());
- final String version = replace(newFeature, artifact.getVersion(), options.getVariableResolver());
- final String classifier = replace(newFeature, artifact.getClassifier(), options.getVariableResolver());
- final String type = replace(newFeature, artifact.getType(), options.getVariableResolver());
- final String resolvedVersion = resolveArtifactVersion(groupId, artifactId, version, classifier, type,
- options.getArtifactVersionResolver());
- final Artifact newArtifact = new Artifact(groupId, artifactId, resolvedVersion, classifier, type);
- newArtifact.setComment(artifact.getComment());
- newArtifact.setLocation(artifact.getLocation());
-
- newGroup.add(newArtifact);
- }
- }
-
- newRunMode.getConfigurations().setComment(runMode.getConfigurations().getComment());
- newRunMode.getConfigurations().setLocation(runMode.getConfigurations().getLocation());
- for(final Configuration config : runMode.getConfigurations()) {
- final Configuration newConfig = newRunMode.getOrCreateConfiguration(config.getPid(), config.getFactoryPid());
-
- getProcessedConfiguration(newFeature, newConfig, config, options.getVariableResolver());
- }
-
- newRunMode.getSettings().setComment(runMode.getSettings().getComment());
- newRunMode.getSettings().setLocation(runMode.getSettings().getLocation());
- for(final Map.Entry<String, String> entry : runMode.getSettings() ) {
- newRunMode.getSettings().put(entry.getKey(), replace(newFeature, entry.getValue(),
- new VariableResolver() {
-
- @Override
- public String resolve(final Feature feature, final String name) {
- if ( "sling.home".equals(name) ) {
- return "${sling.home}";
- }
- if ( options.getVariableResolver() != null ) {
- return options.getVariableResolver().resolve(newFeature, name);
- }
- return newFeature.getVariables().get(name);
- }
- }));
- }
- }
-
- }
- return result;
+ ModelProcessor processor = new EffectiveModelProcessor(options);
+ return processor.process(model);
}
/**
@@ -554,7 +487,7 @@ public abstract class ModelUtility {
return errors;
}
- private static void getProcessedConfiguration(
+ static void getProcessedConfiguration(
final Feature feature,
final Configuration newConfig,
final Configuration config,
@@ -637,4 +570,5 @@ public abstract class ModelUtility {
}
}
}
+
}
diff --git a/src/test/java/org/apache/sling/provisioning/model/ModelProcessorTest.java b/src/test/java/org/apache/sling/provisioning/model/ModelProcessorTest.java
new file mode 100644
index 0000000..629568b
--- /dev/null
+++ b/src/test/java/org/apache/sling/provisioning/model/ModelProcessorTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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.provisioning.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ModelProcessorTest {
+
+ private Model testModel;
+ private ModelProcessor underTest;
+
+ @Before
+ public void setUp() {
+ testModel = new Model();
+ testModel.setLocation("LocM1");
+
+ Feature feature1 = testModel.getOrCreateFeature("feature1");
+ feature1.setLocation("LocF1");
+ feature1.setComment("ComF1");
+ feature1.getVariables().setLocation("LocFV1");
+ feature1.getVariables().setComment("ComFV1");
+ feature1.getVariables().put("k1", "v1");
+ feature1.getVariables().put("k2", "v2");
+
+ RunMode runMode11 = feature1.getOrCreateRunMode(new String[] { "rm1", "rm2"});
+ runMode11.setLocation("LocRM11");
+
+ RunMode runMode12 = feature1.getOrCreateRunMode(new String[] { "rm2"});
+ ArtifactGroup group12 = runMode12.getOrCreateArtifactGroup(10);
+ group12.setLocation("LocRMG11");
+ group12.setComment("ComRMG11");
+
+ group12.add(new Artifact("g1", "a1", "v1", "c1", "t1"));
+ group12.add(new Artifact("g2", "a2", "v2", null, null));
+
+ runMode12.getConfigurations().setLocation("LocConf12");
+ runMode12.getConfigurations().setComment("ComConf12");
+
+ Configuration conf121 = runMode12.getOrCreateConfiguration("pid1", null);
+ conf121.setLocation("LocConf121");
+ conf121.setComment("ComConf121");
+ conf121.getProperties().put("conf1", "v1");
+ conf121.getProperties().put("conf2", "v2");
+
+ Configuration conf122 = runMode12.getOrCreateConfiguration("pid2", "fac2");
+ conf122.setLocation("LocConf122");
+ conf122.setComment("ComConf122");
+ conf122.getProperties().put("conf3", "v3");
+
+ runMode12.getSettings().setLocation("LocSet12");
+ runMode12.getSettings().setComment("ComSet12");
+
+ runMode12.getSettings().put("set1", "v1");
+ runMode12.getSettings().put("set2", "v2");
+
+ Feature feature2 = testModel.getOrCreateFeature("feature1");
+
+ RunMode runMode21 = feature2.getOrCreateRunMode(new String[0]);
+ ArtifactGroup group21 = runMode21.getOrCreateArtifactGroup(20);
+ group21.add(new Artifact("g3", "a3", null, null, null));
+
+ underTest = new TestModelProcessor();
+ }
+
+ @Test
+ public void testProcess() {
+ Model model = underTest.process(testModel);
+
+ assertEquals("LocM1", model.getLocation());
+
+ Feature feature1 = model.getFeature("feature1");
+ assertNotNull(feature1);
+ assertEquals("LocF1", feature1.getLocation());
+ assertEquals("ComF1", feature1.getComment());
+ assertEquals("LocFV1", feature1.getVariables().getLocation());
+ assertEquals("ComFV1", feature1.getVariables().getComment());
+ assertEquals("#v1", feature1.getVariables().get("k1"));
+ assertEquals("#v2", feature1.getVariables().get("k2"));
+
+ RunMode runMode11 = feature1.getRunMode("rm1", "rm2");
+ assertNotNull(runMode11);
+ assertEquals("LocRM11", runMode11.getLocation());
+
+ RunMode runMode12 = feature1.getRunMode(new String[] { "rm2"});
+ assertNotNull(runMode12);
+
+ ArtifactGroup group12 = runMode12.getArtifactGroup(10);
+ assertNotNull(group12);
+ assertEquals("LocRMG11", group12.getLocation());
+ assertEquals("ComRMG11", group12.getComment());
+
+ Iterator<Artifact> artifacts = group12.iterator();
+ Artifact artifact1 = artifacts.next();
+ assertEquals("#g1", artifact1.getGroupId());
+ assertEquals("#a1", artifact1.getArtifactId());
+ assertEquals("#v1", artifact1.getVersion());
+ assertEquals("#c1", artifact1.getClassifier());
+ assertEquals("#t1", artifact1.getType());
+
+ Artifact artifact2 = artifacts.next();
+ assertEquals("#g2", artifact2.getGroupId());
+ assertEquals("#a2", artifact2.getArtifactId());
+ assertEquals("#v2", artifact2.getVersion());
+
+ assertFalse(artifacts.hasNext());
+
+ assertEquals("LocConf12", runMode12.getConfigurations().getLocation());
+ assertEquals("ComConf12", runMode12.getConfigurations().getComment());
+
+ Configuration conf121 = runMode12.getConfiguration("pid1", null);
+ assertEquals("LocConf121", conf121.getLocation());
+ assertEquals("ComConf121", conf121.getComment());
+ assertEquals("#v1", conf121.getProperties().get("conf1"));
+ assertEquals("#v2", conf121.getProperties().get("conf2"));
+
+ Configuration conf122 = runMode12.getConfiguration("pid2", "fac2");
+ assertEquals("LocConf122", conf122.getLocation());
+ assertEquals("ComConf122", conf122.getComment());
+ assertEquals("#v3", conf122.getProperties().get("conf3"));
+
+ assertEquals("LocSet12", runMode12.getSettings().getLocation());
+ assertEquals("ComSet12", runMode12.getSettings().getComment());
+ assertEquals("#v1", runMode12.getSettings().get("set1"));
+ assertEquals("#v2", runMode12.getSettings().get("set2"));
+
+ Feature feature2 = model.getFeature("feature1");
+ assertNotNull(feature2);
+
+ RunMode runMode21 = feature2.getRunMode();
+ assertNotNull(runMode21);
+
+ ArtifactGroup group21 = runMode21.getArtifactGroup(20);
+ assertNotNull(group21);
+
+ artifacts = group21.iterator();
+ Artifact artifact3 = artifacts.next();
+ assertEquals("#g3", artifact3.getGroupId());
+ assertEquals("#a3", artifact3.getArtifactId());
+ assertFalse(artifacts.hasNext());
+ }
+
+
+ static final class TestModelProcessor extends ModelProcessor {
+
+ @Override
+ protected KeyValueMap<String> processVariables(KeyValueMap<String> variables, Feature feature) {
+ KeyValueMap<String> newVars = new KeyValueMap<String>();
+ for (Entry<String, String> entry : variables) {
+ newVars.put(entry.getKey(), "#" + entry.getValue());
+ }
+ return newVars;
+ }
+
+ @Override
+ protected Artifact processArtifact(Artifact artifact, Feature feature, RunMode runMode) {
+ Artifact newArtifact = new Artifact(
+ "#" + artifact.getGroupId(),
+ "#" + artifact.getArtifactId(),
+ "#" + artifact.getVersion(),
+ "#" + artifact.getClassifier(),
+ "#" + artifact.getType());
+ return newArtifact;
+ }
+
+ @Override
+ protected Configuration processConfiguration(Configuration configuration, Feature feature, RunMode runMode) {
+ Configuration newConfig = new Configuration(configuration.getPid(), configuration.getFactoryPid());
+ final Enumeration<String> i = configuration.getProperties().keys();
+ while ( i.hasMoreElements() ) {
+ final String key = i.nextElement();
+ newConfig.getProperties().put(key, "#" + configuration.getProperties().get(key));
+ }
+ return newConfig;
+ }
+
+ @Override
+ protected KeyValueMap<String> processSettings(KeyValueMap<String> settings, Feature feature, RunMode runMode) {
+ KeyValueMap<String> newSettings = new KeyValueMap<String>();
+ for (Entry<String, String> entry : settings) {
+ newSettings.put(entry.getKey(), "#" + entry.getValue());
+ }
+ return newSettings;
+ }
+
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.