This is an automated email from the ASF dual-hosted git repository. davidb pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-modelconverter.git
commit 9398062a3c6d447ebb1e89a3847a7adea9a92049 Author: David Bosschaert <david.bosscha...@gmail.com> AuthorDate: Tue Mar 20 14:14:05 2018 +0000 Preserve variables when converting prov model to feature --- .../modelconverter/impl/ProvisioningToFeature.java | 70 +++++++-------- .../modelconverter/impl/ModelConverterTest.java | 99 ++++++++++++++++++++-- 2 files changed, 129 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java b/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java index 0df66db..a521780 100644 --- a/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java +++ b/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java @@ -104,24 +104,22 @@ public class ProvisioningToFeature { Model model = null; for(final File initFile : files) { try { - model = processModel(model, initFile, includeModelInfo); + model = processModel(model, initFile, includeModelInfo, + new ResolverOptions().variableResolver(new VariableResolver() { + @Override + public String resolve(final Feature feature, final String name) { + // Keep variables as-is in the model + return "${" + name + "}"; + } + }) + ); } catch ( final IOException iae) { LOGGER.error("Unable to read provisioning model {} : {}", initFile, iae.getMessage(), iae); System.exit(1); } } - final Model effectiveModel = ModelUtility.getEffectiveModel(model, new ResolverOptions().variableResolver(new VariableResolver() { - - @Override - public String resolve(Feature feature, String name) { - if ( "sling.home".equals(name) ) { - return "${sling.home}"; - } - return feature.getVariables().get(name); - } - })); - final Map<Traceable, String> errors = ModelUtility.validate(effectiveModel); + final Map<Traceable, String> errors = ModelUtility.validate(model); if ( errors != null ) { LOGGER.error("Invalid assembled provisioning model."); for(final Map.Entry<Traceable, String> entry : errors.entrySet()) { @@ -129,11 +127,11 @@ public class ProvisioningToFeature { } System.exit(1); } - final Set<String> modes = calculateRunModes(effectiveModel, runModes); + final Set<String> modes = calculateRunModes(model, runModes); - removeInactiveFeaturesAndRunModes(effectiveModel, modes); + removeInactiveFeaturesAndRunModes(model, modes); - return effectiveModel; + return model; } /** @@ -145,19 +143,22 @@ public class ProvisioningToFeature { * @throws IOException If reading fails */ private static Model processModel(Model model, - final File modelFile, boolean includeModelInfo) throws IOException { + File modelFile, boolean includeModelInfo) throws IOException { + return processModel(model, modelFile, includeModelInfo, + new ResolverOptions().variableResolver(new VariableResolver() { + @Override + public String resolve(final Feature feature, final String name) { + return name; + } + }) + ); + } + + private static Model processModel(Model model, + File modelFile, boolean includeModelInfo, ResolverOptions options) throws IOException { LOGGER.info("- reading model {}", modelFile); final Model nextModel = readProvisioningModel(modelFile); - // resolve references to other models - final ResolverOptions options = new ResolverOptions().variableResolver(new VariableResolver() { - - @Override - public String resolve(final Feature feature, final String name) { - return name; - } - }); - final Model effectiveModel = ModelUtility.getEffectiveModel(nextModel, options); for(final Feature feature : effectiveModel.getFeatures()) { @@ -210,11 +211,10 @@ public class ProvisioningToFeature { /** * Read the provisioning model */ - public static Model readProvisioningModel(final File file) + private static Model readProvisioningModel(final File file) throws IOException { try (final FileReader is = new FileReader(file)) { - final Model m = ModelReader.read(is, file.getAbsolutePath()); - return m; + return ModelReader.read(is, file.getAbsolutePath()); } } @@ -393,14 +393,14 @@ public class ProvisioningToFeature { cpExtension.getArtifacts().add(newArtifact); } else { int startLevel = group.getStartLevel(); - if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) { - startLevel = 1; - } else if ( startLevel == 0 ) { - startLevel = 20; + if ( startLevel == 0) { + if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) { + startLevel = 1; + } else if ( startLevel == 0 ) { + startLevel = 20; + } } - - // TODO this is probably not correct - // newArtifact.getMetadata().put(org.apache.sling.feature.Artifact.KEY_START_ORDER, String.valueOf(startLevel)); + newArtifact.getMetadata().put("start-level", String.valueOf(startLevel)); bundles.add(newArtifact); } diff --git a/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java b/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java index 1572e9a..bf35578 100644 --- a/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java +++ b/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java @@ -16,8 +16,12 @@ */ package org.apache.sling.feature.modelconverter.impl; +import org.apache.sling.feature.Bundles; +import org.apache.sling.feature.Configurations; import org.apache.sling.feature.support.ArtifactManager; import org.apache.sling.feature.support.ArtifactManagerConfig; +import org.apache.sling.feature.support.FeatureUtil; +import org.apache.sling.feature.support.json.FeatureJSONReader.SubstituteVariables; import org.apache.sling.provisioning.model.Artifact; import org.apache.sling.provisioning.model.ArtifactGroup; import org.apache.sling.provisioning.model.Configuration; @@ -27,11 +31,13 @@ import org.apache.sling.provisioning.model.Model; import org.apache.sling.provisioning.model.ModelConstants; import org.apache.sling.provisioning.model.RunMode; import org.apache.sling.provisioning.model.Section; +import org.apache.sling.provisioning.model.io.ModelReader; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -43,6 +49,7 @@ import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -76,10 +83,10 @@ public class ModelConverterTest { testConvertToProvisioningModel("/boot.json", "/boot.txt"); } - /* @Test + @Test public void testBootToFeature() throws Exception { testConvertToFeature("/boot.txt", "/boot.json"); - } */ + } @Test public void testOak() throws Exception { @@ -90,7 +97,13 @@ public class ModelConverterTest { File inFile = new File(getClass().getResource(originalProvModel).toURI()); File outFile = new File(tempDir.toFile(), expectedJSON + ".generated"); - ProvisioningToFeature.convert(inFile, outFile.getAbsolutePath()); + String outPath = outFile.getAbsolutePath(); + ProvisioningToFeature.convert(inFile, outPath); + + String expectedFile = new File(getClass().getResource(expectedJSON).toURI()).getAbsolutePath(); + org.apache.sling.feature.Feature expected = FeatureUtil.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE); + org.apache.sling.feature.Feature actual = FeatureUtil.getFeature(outPath, artifactManager, SubstituteVariables.NONE); + assertFeaturesEqual(expected, actual); } public void testConvertToProvisioningModel(String originalJSON, String expectedProvModel) throws URISyntaxException, IOException { @@ -101,11 +114,63 @@ public class ModelConverterTest { artifactManager); File expectedFile = new File(getClass().getResource(expectedProvModel).toURI()); - Model expected = ProvisioningToFeature.readProvisioningModel(expectedFile); - Model actual = ProvisioningToFeature.readProvisioningModel(outFile); + Model expected = readProvisioningModel(expectedFile); + Model actual = readProvisioningModel(outFile); assertModelsEqual(expected, actual); } + private static Model readProvisioningModel(File modelFile) throws IOException { + try (final FileReader is = new FileReader(modelFile)) { + return ModelReader.read(is, modelFile.getAbsolutePath()); + } + } + + private void assertFeaturesEqual(org.apache.sling.feature.Feature expected, org.apache.sling.feature.Feature actual) { + assertEquals(expected.getTitle(), actual.getTitle()); + assertEquals(expected.getDescription(), actual.getDescription()); + assertEquals(expected.getVendor(), actual.getVendor()); + assertEquals(expected.getLicense(), actual.getLicense()); + + assertFeatureKVMapEquals(expected.getVariables(), actual.getVariables()); + assertBundlesEqual(expected.getBundles(), actual.getBundles()); + assertConfigurationsEqual(expected.getConfigurations(), actual.getConfigurations()); + assertFeatureKVMapEquals(expected.getFrameworkProperties(), actual.getFrameworkProperties()); + + // Ignore caps and reqs, includes and extensions here since they cannot come from the prov model. + } + + private void assertBundlesEqual(Bundles expected, Bundles actual) { + for (Iterator<org.apache.sling.feature.Artifact> it = expected.iterator(); it.hasNext(); ) { + org.apache.sling.feature.Artifact ex = it.next(); + + boolean found = false; + for (Iterator<org.apache.sling.feature.Artifact> it2 = actual.iterator(); it2.hasNext(); ) { + org.apache.sling.feature.Artifact ac = it2.next(); + if (ac.getId().equals(ex.getId())) { + found = true; + assertFeatureKVMapEquals(ex.getMetadata(), ac.getMetadata()); + } + } + assertTrue(found); + } + } + + private void assertConfigurationsEqual(Configurations expected, Configurations actual) { + for (Iterator<org.apache.sling.feature.Configuration> it = expected.iterator(); it.hasNext(); ) { + org.apache.sling.feature.Configuration ex = it.next(); + + boolean found = false; + for (Iterator<org.apache.sling.feature.Configuration> it2 = actual.iterator(); it2.hasNext(); ) { + org.apache.sling.feature.Configuration ac = it2.next(); + if (ac.getPid().equals(ex.getPid())) { + found = true; + assertEquals(ex.getProperties(), ac.getProperties()); + } + } + assertTrue(found); + } + } + private void assertModelsEqual(Model expected, Model actual) { for (int i=0; i<expected.getFeatures().size(); i++) { Feature expectedFeature = expected.getFeatures().get(i); @@ -189,6 +254,15 @@ public class ModelConverterTest { } found = true; + if (cfg1.getFactoryPid() == null) { + if (cfg2.getFactoryPid() != null) + return false; + } else { + if (!cfg1.getFactoryPid().equals(cfg2.getFactoryPid())) { + return false; + } + } + Map<String, Object> m1 = cfgMap(cfg1.getProperties()); Map<String, Object> m2 = cfgMap(cfg2.getProperties()); if (!m1.equals(m2)) { @@ -240,6 +314,16 @@ public class ModelConverterTest { return m; } + private Map<String, String> featureKvToMap(org.apache.sling.feature.KeyValueMap kvm) { + Map<String, String> m = new HashMap<>(); + + for (Map.Entry<String, String> entry : kvm) { + m.put(entry.getKey(), entry.getValue()); + } + + return m; + } + private boolean artifactGroupsEquals(String featureName, ArtifactGroup g1, ArtifactGroup g2) { int sl1 = effectiveStartLevel(featureName, g1.getStartLevel()); int sl2 = effectiveStartLevel(featureName, g2.getStartLevel()); @@ -276,6 +360,11 @@ public class ModelConverterTest { assertEquals(kvToMap(expected), kvToMap(actual)); } + private void assertFeatureKVMapEquals(org.apache.sling.feature.KeyValueMap expected, + org.apache.sling.feature.KeyValueMap actual) { + assertEquals(featureKvToMap(expected), featureKvToMap(actual)); + } + private void assertSectionsEqual(List<Section> expected, List<Section> actual) { assertEquals(expected.size(), actual.size()); -- To stop receiving notification emails like this one, please contact dav...@apache.org.