SLING-7732 Feature Model Converter ignores inheritance when converting to provisioning model
Unit test included.
diff --git a/src/main/java/org/apache/sling/feature/modelconverter/FeatureToProvisioning.java b/src/main/java/org/apache/sling/feature/modelconverter/FeatureToProvisioning.java
index 9b92ad8..d902ab6 100644
--- a/src/main/java/org/apache/sling/feature/modelconverter/FeatureToProvisioning.java
+++ b/src/main/java/org/apache/sling/feature/modelconverter/FeatureToProvisioning.java
@@ -25,6 +25,9 @@
import org.apache.sling.feature.Extensions;
import org.apache.sling.feature.FeatureConstants;
import org.apache.sling.feature.KeyValueMap;
+import org.apache.sling.feature.builder.BuilderContext;
+import org.apache.sling.feature.builder.FeatureBuilder;
+import org.apache.sling.feature.builder.FeatureProvider;
import org.apache.sling.feature.io.ArtifactManager;
import org.apache.sling.feature.io.IOUtils;
import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
@@ -61,7 +64,7 @@
static final String PROVISIONING_MODEL_NAME_VARIABLE = "provisioning.model.name";
static final String PROVISIONING_RUNMODES = "provisioning.runmodes";
- public static void convert(File inputFile, File outputFile, ArtifactManager am) throws IOException {
+ public static void convert(File inputFile, File outputFile, ArtifactManager am, File ... additionalInputFiles) throws IOException {
if (outputFile.exists()) {
if (outputFile.lastModified() > inputFile.lastModified()) {
LOGGER.debug("Skipping the generation of {} as this file already exists and is newer.", outputFile);
@@ -70,6 +73,9 @@
}
org.apache.sling.feature.Feature feature = IOUtils.getFeature(inputFile.getAbsolutePath(), am, SubstituteVariables.NONE);
+ if (feature.getIncludes().size() > 0) {
+ feature = handleIncludes(feature, additionalInputFiles, am);
+ }
Object featureNameVar = feature.getVariables().remove(PROVISIONING_MODEL_NAME_VARIABLE);
String featureName;
@@ -90,6 +96,23 @@
feature.getFrameworkProperties(), feature.getExtensions(), outputFile.getAbsolutePath(), runModes);
}
+ private static org.apache.sling.feature.Feature handleIncludes(org.apache.sling.feature.Feature feature, File[] additionalFiles, ArtifactManager am) throws IOException {
+ Map<ArtifactId, org.apache.sling.feature.Feature> features = new HashMap<>();
+
+ for (File f : additionalFiles) {
+ org.apache.sling.feature.Feature af = IOUtils.getFeature(f.getAbsolutePath(), am, SubstituteVariables.NONE);
+ features.put(af.getId(), af);
+ }
+
+ BuilderContext bc = new BuilderContext(new FeatureProvider() {
+ @Override
+ public org.apache.sling.feature.Feature provide(ArtifactId id) {
+ return features.get(id);
+ }
+ });
+ return FeatureBuilder.assemble(feature, bc);
+ }
+
/*
public static void convert(List<File> files, String output, boolean createApp, ArtifactManager am) throws Exception {
try (FeatureResolver fr = null) { // TODO we could use the resolver: new FrameworkResolver(am)
diff --git a/src/test/java/org/apache/sling/feature/modelconverter/ModelConverterTest.java b/src/test/java/org/apache/sling/feature/modelconverter/ModelConverterTest.java
index 263d479..0c66e96 100644
--- a/src/test/java/org/apache/sling/feature/modelconverter/ModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/modelconverter/ModelConverterTest.java
@@ -183,6 +183,12 @@
}
@Test
+ public void testSimpleInheritsToProvModel() throws Exception {
+ testConvertToProvisioningModel("/simple.json", "/simple.txt", "/simple_inherits.json");
+ testConvertToProvisioningModel("/simple.json", "/simple.txt", "/simple.json", "/simple_inherits.json");
+ }
+
+ @Test
public void testSimple2ToProvModel() throws Exception {
testConvertToProvisioningModel("/simple2.json", "/simple2.txt");
}
@@ -321,11 +327,15 @@
assertFeaturesEqual(expected, actual);
}
- public void testConvertToProvisioningModel(String originalJSON, String expectedProvModel) throws URISyntaxException, IOException {
+ public void testConvertToProvisioningModel(String originalJSON, String expectedProvModel, String ... additionalContextFiles) throws URISyntaxException, IOException {
File inFile = new File(getClass().getResource(originalJSON).toURI());
File outFile = new File(tempDir.toFile(), expectedProvModel + ".generated");
+ List<File> addFiles = new ArrayList<>();
+ for (String af : additionalContextFiles) {
+ addFiles.add(new File(getClass().getResource(af).toURI()));
+ }
- FeatureToProvisioning.convert(inFile, outFile, artifactManager);
+ FeatureToProvisioning.convert(inFile, outFile, artifactManager, addFiles.toArray(new File[] {}));
File expectedFile = new File(getClass().getResource(expectedProvModel).toURI());
Model expected = readProvisioningModel(expectedFile);
diff --git a/src/test/resources/simple_inherits.json b/src/test/resources/simple_inherits.json
new file mode 100644
index 0000000..02c4e20
--- /dev/null
+++ b/src/test/resources/simple_inherits.json
@@ -0,0 +1,11 @@
+{
+ "id":"generated:simple-inherits:1.0.0",
+ "includes": [
+ {
+ "id": "generated:simple:1.0.0"
+ }
+ ],
+ "bundles":[
+ "org.apache.sling/org.apache.sling.commons.log/5.1.0"
+ ]
+}
diff --git a/src/test/resources/simple_inherits.txt b/src/test/resources/simple_inherits.txt
new file mode 100644
index 0000000..445908c
--- /dev/null
+++ b/src/test/resources/simple_inherits.txt
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+# The :boot feature contains all things to bootstrap the installation.
+#
+[feature name=simple-inherits]
+
+[artifacts]
+ org.apache.aries/org.apache.aries.util/1.1.3
+ org.apache.sling/org.apache.sling.commons.log/5.1.0