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.1.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-provisioning-model.git
commit 523138f61b3f6a23110a7560de88084c3a79a6c8 Author: Carsten Ziegeler <cziege...@apache.org> AuthorDate: Thu Mar 5 12:20:27 2015 +0000 SLING-4473 : Provide a way to remove settings, artifacts and features through a model SLING-4475 : Artifact is twice in feature after merge git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/provisioning-model@1664323 13f79535-47bb-0310-9956-ffa450edef68 --- .../sling/provisioning/model/KeyValueMap.java | 19 ++++++ .../sling/provisioning/model/ModelConstants.java | 6 ++ .../sling/provisioning/model/ModelUtility.java | 59 +++++++++++++++++- .../sling/provisioning/model/io/ModelReader.java | 1 - .../sling/provisioning/model/package-info.java | 2 +- .../sling/provisioning/model/ModelUtilityTest.java | 66 ++++++++++++++++++++ .../org/apache/sling/provisioning/model/U.java | 70 ++++++++++++++++++---- src/test/resources/merge/artifact-base.txt | 4 ++ src/test/resources/merge/artifact-merge.txt | 4 ++ src/test/resources/merge/remove-base.txt | 25 ++++++++ src/test/resources/merge/remove-merge.txt | 12 ++++ 11 files changed, 252 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/apache/sling/provisioning/model/KeyValueMap.java b/src/main/java/org/apache/sling/provisioning/model/KeyValueMap.java index 7e64732..010d684 100644 --- a/src/main/java/org/apache/sling/provisioning/model/KeyValueMap.java +++ b/src/main/java/org/apache/sling/provisioning/model/KeyValueMap.java @@ -50,6 +50,16 @@ public class KeyValueMap<T> } /** + * Remove an item from the map + * @param key The key of the item. + * @return The previously stored value for the key or {@code null}. + * @since 1.1 + */ + public T remove(final String key) { + return this.properties.remove(key); + } + + /** * Put all items from the other map in this map * @param map The other map */ @@ -74,4 +84,13 @@ public class KeyValueMap<T> public String toString() { return properties.toString(); } + + /** + * Get the size of the map. + * @return The size of the map. + * @since 1.1 + */ + public int size() { + return this.properties.size(); + } } diff --git a/src/main/java/org/apache/sling/provisioning/model/ModelConstants.java b/src/main/java/org/apache/sling/provisioning/model/ModelConstants.java index d3020f9..e5e74dd 100644 --- a/src/main/java/org/apache/sling/provisioning/model/ModelConstants.java +++ b/src/main/java/org/apache/sling/provisioning/model/ModelConstants.java @@ -62,4 +62,10 @@ public abstract class ModelConstants { /** Default start level value */ public static final int DEFAULT_START_LEVEL = 0; + + /** + * Name of the run mode to remove things from the base model. + * @since 1.1 + */ + public static final String RUN_MODE_REMOVE = ":remove"; } 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 82c129f..4b4ce7b 100644 --- a/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java +++ b/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java @@ -50,7 +50,62 @@ public abstract class ModelUtility { // run modes for(final RunMode runMode : feature.getRunModes()) { - final RunMode baseRunMode = baseFeature.getOrCreateRunMode(runMode.getNames()); + // check for special remove run mode + String names[] = runMode.getNames(); + if ( names != null ) { + int removeIndex = -1; + int index = 0; + for(final String name : names) { + if ( name.equals(ModelConstants.RUN_MODE_REMOVE) ) { + removeIndex = index; + break; + } + index++; + } + if ( removeIndex != -1 ) { + String[] newNames = null; + if ( names.length > 1 ) { + newNames = new String[names.length - 1]; + index = 0; + for(final String name : names) { + if ( !name.equals(ModelConstants.RUN_MODE_REMOVE) ) { + newNames[index++] = name; + } + } + } + names = newNames; + final RunMode baseRunMode = baseFeature.getRunMode(names); + if ( baseRunMode != null ) { + + // artifact groups + for(final ArtifactGroup group : runMode.getArtifactGroups()) { + for(final Artifact artifact : group) { + for(final ArtifactGroup searchGroup : baseRunMode.getArtifactGroups()) { + final Artifact found = searchGroup.search(artifact); + if ( found != null ) { + searchGroup.remove(found); + } + } + } + } + + // configurations + for(final Configuration config : runMode.getConfigurations()) { + final Configuration found = baseRunMode.getConfiguration(config.getPid(), config.getFactoryPid()); + if ( found != null ) { + baseRunMode.getConfigurations().remove(found); + } + } + + // settings + for(final Map.Entry<String, String> entry : runMode.getSettings() ) { + baseRunMode.getSettings().remove(entry.getKey()); + } + } + continue; + } + } + final RunMode baseRunMode = baseFeature.getOrCreateRunMode(names); // artifact groups for(final ArtifactGroup group : runMode.getArtifactGroups()) { @@ -58,7 +113,7 @@ public abstract class ModelUtility { for(final Artifact artifact : group) { for(final ArtifactGroup searchGroup : baseRunMode.getArtifactGroups()) { - final Artifact found = baseGroup.search(artifact); + final Artifact found = searchGroup.search(artifact); if ( found != null ) { searchGroup.remove(found); } diff --git a/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java b/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java index 8786a13..903a578 100644 --- a/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java +++ b/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java @@ -256,7 +256,6 @@ public class ModelReader { if ( factoryPos == -1 ) { pid = configId; factoryPid = null; - config = new Configuration(configId, null); } else { pid = configId.substring(factoryPos + 1); factoryPid = configId.substring(0, factoryPos); diff --git a/src/main/java/org/apache/sling/provisioning/model/package-info.java b/src/main/java/org/apache/sling/provisioning/model/package-info.java index 5e50b7f..7e587ef 100644 --- a/src/main/java/org/apache/sling/provisioning/model/package-info.java +++ b/src/main/java/org/apache/sling/provisioning/model/package-info.java @@ -17,7 +17,7 @@ * under the License. */ -@Version("1.0") +@Version("1.1.0") package org.apache.sling.provisioning.model; import aQute.bnd.annotation.Version; diff --git a/src/test/java/org/apache/sling/provisioning/model/ModelUtilityTest.java b/src/test/java/org/apache/sling/provisioning/model/ModelUtilityTest.java new file mode 100644 index 0000000..c3b4547 --- /dev/null +++ b/src/test/java/org/apache/sling/provisioning/model/ModelUtilityTest.java @@ -0,0 +1,66 @@ +/* + * 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.assertNotNull; + +import java.util.List; + +import org.junit.Test; + +public class ModelUtilityTest { + + @Test public void mergeArtifactsTest() throws Exception { + final Model model = U.readCompleteTestModel(new String[] {"merge/artifact-base.txt", + "merge/artifact-merge.txt"}); + + // model should now have one artifact + assertNotNull(model.getFeature("f")); + assertNotNull(model.getFeature("f").getRunMode()); + assertNotNull(model.getFeature("f").getRunMode().getArtifactGroup(3)); + assertNotNull(model.getFeature("f").getRunMode().getArtifactGroup(5)); + U.assertArtifactsInGroup(model.getFeature("f").getRunMode().getArtifactGroup(5), 0); + final List<Artifact> list = U.assertArtifactsInGroup(model.getFeature("f").getRunMode().getArtifactGroup(3), 1); + + U.assertArtifact(list.get(0), "g", "a", "2.0.0", "jar", null); + } + + @Test public void removeTest() throws Exception { + final Model model = U.readCompleteTestModel(new String[] {"merge/remove-base.txt", + "merge/remove-merge.txt"}); + + assertNotNull(model.getFeature("f")); + assertNotNull(model.getFeature("f").getRunMode()); + assertNotNull(model.getFeature("f").getRunMode().getArtifactGroup(5)); + assertNotNull(model.getFeature("f").getRunMode().getArtifactGroup(7)); + + final List<Artifact> group5 = U.assertArtifactsInGroup(model.getFeature("f").getRunMode().getArtifactGroup(5), 1); + U.assertArtifact(group5.get(0), "g", "a", "1.0.0", "jar", null); + + final List<Artifact> group7 = U.assertArtifactsInGroup(model.getFeature("f").getRunMode().getArtifactGroup(7), 1); + U.assertArtifact(group7.get(0), "g", "c", "1.0.0", "jar", null); + + final List<Configuration> cfgs = U.assertConfigurationsInRunMode(model.getFeature("f").getRunMode(), 2); + assertEquals("org.sling.service.A", cfgs.get(0).getPid()); + assertEquals("org.sling.service.C", cfgs.get(1).getPid()); + + assertEquals(2, model.getFeature("f").getRunMode().getSettings().size()); + assertEquals("a", model.getFeature("f").getRunMode().getSettings().get("key.a")); + assertEquals("c", model.getFeature("f").getRunMode().getSettings().get("key.c")); + } +} diff --git a/src/test/java/org/apache/sling/provisioning/model/U.java b/src/test/java/org/apache/sling/provisioning/model/U.java index a49f2f2..f2a5756 100644 --- a/src/test/java/org/apache/sling/provisioning/model/U.java +++ b/src/test/java/org/apache/sling/provisioning/model/U.java @@ -18,33 +18,43 @@ package org.apache.sling.provisioning.model; import static org.apache.sling.provisioning.model.ModelConstants.DEFAULT_RUN_MODE; import static org.apache.sling.provisioning.model.ModelConstants.DEFAULT_START_LEVEL; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.InputStreamReader; import java.io.Reader; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.apache.sling.provisioning.model.io.ModelReader; /** Test utilities */ public class U { - - public static final String[] TEST_MODEL_FILENAMES = + + public static final String[] TEST_MODEL_FILENAMES = new String[] {"boot.txt", "example.txt", "main.txt", "oak.txt"}; - + public static void assertArtifact(ArtifactGroup g, String mvnUrl) { final Artifact a = Artifact.fromMvnUrl(mvnUrl); if(!g.items.contains(a)) { fail("Expecting ArtifactGroup to contain '" + mvnUrl + "': " + g); } } - - /** Read our test model by merging our TEST_MODEL_FILENAMES */ + + /** Read our test model by merging our TEST_MODEL_FILENAMES */ public static Model readCompleteTestModel() throws Exception { + return readCompleteTestModel(TEST_MODEL_FILENAMES); + } + + /** Read the complete model from that names */ + public static Model readCompleteTestModel(final String[] names) throws Exception { final Model result = new Model(); - for(final String name : TEST_MODEL_FILENAMES) { + for(final String name : names) { final Reader reader = new InputStreamReader(U.class.getResourceAsStream("/" + name), "UTF-8"); try { final Model current = ModelReader.read(reader, name); @@ -64,7 +74,7 @@ public class U { } return result; } - + public static ArtifactGroup getGroup(Model m, String feature, String runMode, int startLevel) { final Feature f = m.getFeature(feature); assertNotNull(f); @@ -74,7 +84,7 @@ public class U { assertNotNull(g); return g; } - + /** Verify that m matches what we expect after * reading and merging our test files. */ @@ -83,13 +93,13 @@ public class U { for(String name : f) { assertNotNull("Expecting feature to be present:" + name, m.getFeature(name)); } - + { final ArtifactGroup g = getGroup(m, "example", DEFAULT_RUN_MODE, DEFAULT_START_LEVEL); U.assertArtifact(g, "mvn:commons-collections/commons-collections/3.2.1/jar"); U.assertArtifact(g, "mvn:org.example/jar-is-default/1.2/jar"); } - + { final ArtifactGroup g = getGroup(m, "example", "jackrabbit", 15); if(variablesAlreadyResolved) { @@ -98,7 +108,7 @@ public class U { U.assertArtifact(g, "mvn:org.apache.sling/org.apache.sling.jcr.jackrabbit.server/${jackrabbit.version}/jar"); } } - + { final ArtifactGroup g = getGroup(m, ":boot", DEFAULT_RUN_MODE, DEFAULT_START_LEVEL); if(variablesAlreadyResolved) { @@ -107,7 +117,43 @@ public class U { U.assertArtifact(g, "mvn:org.apache.sling/org.apache.sling.fragment.ws/${ws.version}/jar"); } } - + } + public static void assertArtifact(final Artifact artifact, + final String groupId, final String artifactId, final String version, final String type, final String classifier) { + assertNotNull(artifact); + assertEquals(groupId, artifact.getGroupId()); + assertEquals(artifactId, artifact.getArtifactId()); + assertEquals(version, artifact.getVersion()); + assertEquals(type, artifact.getType()); + assertEquals(classifier, artifact.getClassifier()); + } + + public static List<Artifact> assertArtifactsInGroup(final ArtifactGroup group, final int size) { + final List<Artifact> result = new ArrayList<Artifact>(); + if ( size == 0 ) { + assertTrue("Group should be empty", group.isEmpty()); + } else { + assertFalse("Group should not be empty", group.isEmpty()); + } + for(final Artifact a : group) { + result.add(a); + } + assertEquals("Unexpected size of group: ", size, result.size()); + return result; + } + + public static List<Configuration> assertConfigurationsInRunMode(final RunMode runmode, final int size) { + final List<Configuration> result = new ArrayList<Configuration>(); + if ( size == 0 ) { + assertTrue("Configurations should be empty", runmode.getConfigurations().isEmpty()); + } else { + assertFalse("Configurations should not be empty", runmode.getConfigurations().isEmpty()); + } + for(final Configuration a : runmode.getConfigurations()) { + result.add(a); + } + assertEquals("Unexpected size of configurations: ", size, result.size()); + return result; } } diff --git a/src/test/resources/merge/artifact-base.txt b/src/test/resources/merge/artifact-base.txt new file mode 100644 index 0000000..8e309d1 --- /dev/null +++ b/src/test/resources/merge/artifact-base.txt @@ -0,0 +1,4 @@ +[feature name=f] + +[artifacts startLevel=5] + g/a/1.0.0 \ No newline at end of file diff --git a/src/test/resources/merge/artifact-merge.txt b/src/test/resources/merge/artifact-merge.txt new file mode 100644 index 0000000..f395b96 --- /dev/null +++ b/src/test/resources/merge/artifact-merge.txt @@ -0,0 +1,4 @@ +[feature name=f] + +[artifacts startLevel=3] + g/a/2.0.0 \ No newline at end of file diff --git a/src/test/resources/merge/remove-base.txt b/src/test/resources/merge/remove-base.txt new file mode 100644 index 0000000..e5c25b2 --- /dev/null +++ b/src/test/resources/merge/remove-base.txt @@ -0,0 +1,25 @@ +[feature name=f] + +[artifacts startLevel=5] + g/a/1.0.0 + g/b/1.0.0 + +[artifacts startLevel=7] + g/c/1.0.0 + g/d/1.0.0 + +[configurations] + org.sling.service.A + name="A" + + org.sling.service.B + name="B" + + org.sling.service.C + name="C" + +[settings] + key.a=a + key.b=b + key.c=c + \ No newline at end of file diff --git a/src/test/resources/merge/remove-merge.txt b/src/test/resources/merge/remove-merge.txt new file mode 100644 index 0000000..ad4c541 --- /dev/null +++ b/src/test/resources/merge/remove-merge.txt @@ -0,0 +1,12 @@ +[feature name=f] + +[artifacts runModes=:remove] + g/b/2.0.0 + g/d/1.0.0 + +[configurations runModes=:remove] + org.sling.service.B + +[settings runModes=:remove] + key.b=remove + \ No newline at end of file -- To stop receiving notification emails like this one, please contact "commits@sling.apache.org" <commits@sling.apache.org>.