Merge branch 'master' into SLING-8569
diff --git a/pom.xml b/pom.xml
index bc50bb7..38bef2a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
</parent>
<artifactId>org.apache.sling.feature.cpconverter</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>0.0.1-T20190704160700-937c5fd</version>
<name>Apache Sling Content Package to Feature Model converter</name>
<description>Content Package to Feature Model converter tools for Apache Sling</description>
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
index 83fc5d3..ec874b3 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
@@ -47,6 +47,7 @@
import org.apache.sling.feature.cpconverter.handlers.EntryHandlersManager;
import org.apache.sling.feature.cpconverter.handlers.NodeTypesEntryHandler;
import org.apache.sling.feature.cpconverter.vltpkg.BaseVaultPackageScanner;
+import org.apache.sling.feature.cpconverter.vltpkg.PackagesEventsEmitter;
import org.apache.sling.feature.cpconverter.vltpkg.RecollectorVaultPackageScanner;
import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
@@ -76,6 +77,8 @@
private RecollectorVaultPackageScanner recollectorVaultPackageScanner;
+ private PackagesEventsEmitter emitter;
+
public ContentPackage2FeatureModelConverter() {
this(false);
}
@@ -126,6 +129,11 @@
return mainPackageAssembler;
}
+ public ContentPackage2FeatureModelConverter setEmitter(PackagesEventsEmitter emitter) {
+ this.emitter = emitter;
+ return this;
+ }
+
public void convert(File...contentPackages) throws Exception {
requireNonNull(contentPackages , "Null content-package(s) can not be converted.");
secondPass(firstPass(contentPackages));
@@ -166,8 +174,11 @@
}
protected void secondPass(Collection<VaultPackage> orderedContentPackages) throws Exception {
+ emitter.start();
+
for (VaultPackage vaultPackage : orderedContentPackages) {
try {
+ emitter.startPackage(vaultPackage);
mainPackageAssembler = VaultPackageAssembler.create(vaultPackage);
assemblers.add(mainPackageAssembler);
@@ -196,6 +207,7 @@
logger.info("Conversion complete!");
featuresManager.serialize();
+ emitter.endPackage();
} finally {
aclManager.reset();
assemblers.clear();
@@ -207,6 +219,8 @@
}
}
}
+
+ emitter.end();
}
private void orderDependencies(Map<PackageId, VaultPackage> idFileMap,
@@ -239,6 +253,8 @@
return;
}
+ emitter.startSubPackage(path, vaultPackage);
+
ArtifactId packageId = toArtifactId(vaultPackage);
VaultPackageAssembler clonedPackage = VaultPackageAssembler.create(vaultPackage);
@@ -261,6 +277,8 @@
// restore the previous assembler
mainPackageAssembler = handler;
+
+ emitter.endSubPackage();
}
protected boolean isSubContentPackageIncluded(String path) {
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java b/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
index ac4b92b..b1e0d4d 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
@@ -27,6 +27,7 @@
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.filtering.RegexBasedResourceFilter;
import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager;
+import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,7 +118,8 @@
properties))
.setBundlesDeployer(new DefaultArtifactsDeployer(artifactsOutputDirectory))
.setEntryHandlersManager(new DefaultEntryHandlersManager())
- .setAclManager(new DefaultAclManager());
+ .setAclManager(new DefaultAclManager())
+ .setEmitter(DefaultPackagesEventsEmitter.open(featureModelsOutputDirectory));
if (filteringPatterns != null && filteringPatterns.length > 0) {
RegexBasedResourceFilter filter = new RegexBasedResourceFilter();
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/DefaultPackagesEventsEmitter.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/DefaultPackagesEventsEmitter.java
new file mode 100644
index 0000000..30d1d49
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/DefaultPackagesEventsEmitter.java
@@ -0,0 +1,150 @@
+/*
+ * 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.feature.cpconverter.vltpkg;
+
+import static java.util.stream.Collectors.joining;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.Date;
+import java.util.Stack;
+
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.VaultPackage;
+
+/**
+ * Writes a CSV file <code>containerFile,packageId,packageType[,parentId,pathInParent]</code>
+ */
+public final class DefaultPackagesEventsEmitter implements PackagesEventsEmitter {
+
+ private static final String FILENAME = "content-packages.csv";
+
+ private static final String PATH_SEPARATOR_CHAR = "!";
+
+ public static DefaultPackagesEventsEmitter open(File featureModelsOutputDirectory) throws IOException {
+ if (!featureModelsOutputDirectory.exists()) {
+ featureModelsOutputDirectory.mkdirs();
+ }
+
+ File contentPackagesFiles = new File(featureModelsOutputDirectory, FILENAME);
+ return new DefaultPackagesEventsEmitter(new FileWriter(contentPackagesFiles));
+ }
+
+ private final Stack<String> paths = new Stack<>();
+
+ private final Stack<PackageId> hierarchy = new Stack<>();
+
+ private final PrintWriter writer;
+
+ private VaultPackage current;
+
+ protected DefaultPackagesEventsEmitter(Writer writer) {
+ this.writer = new PrintWriter(writer, true);
+ }
+
+ @Override
+ public void start() {
+ writer.printf("# File created on %s by the Apache Sling Content Package to Sling Feature converter%n", new Date())
+ .printf("# content-package path, content-package ID, content-package type, content-package parent ID, path in parent content-package, absolute path%n");
+ }
+
+ @Override
+ public void end() {
+ writer.close();
+ paths.clear();
+ hierarchy.clear();
+ }
+
+ @Override
+ public void startPackage(VaultPackage vaultPackage) {
+ paths.add(vaultPackage.getFile().getAbsolutePath());
+ hierarchy.add(vaultPackage.getId());
+ current = vaultPackage;
+
+ writer.printf("%s,%s,%s,,,%n",
+ paths.peek(),
+ hierarchy.peek(),
+ detectPackageType(vaultPackage));
+ }
+
+ @Override
+ public void endPackage() {
+ paths.pop();
+ hierarchy.pop();
+ }
+
+ @Override
+ public void startSubPackage(String path, VaultPackage vaultPackage) {
+ paths.add(path);
+ String absolutePath = paths.stream().collect(joining(PATH_SEPARATOR_CHAR));
+
+ writer.printf("%s,%s,%s,%s,%s,%s%n",
+ current.getFile().getAbsolutePath(),
+ vaultPackage.getId(),
+ detectPackageType(vaultPackage),
+ hierarchy.peek(),
+ path,
+ absolutePath);
+
+ hierarchy.add(vaultPackage.getId());
+ }
+
+ @Override
+ public void endSubPackage() {
+ endPackage();
+ }
+
+ private static PackageType detectPackageType(VaultPackage vaultPackage) {
+ PackageType packageType = vaultPackage.getPackageType();
+ if (packageType != null) {
+ return packageType;
+ }
+
+ // borrowed from org.apache.jackrabbit.vault.fs.io.AbstractExporter
+ WorkspaceFilter filter = vaultPackage.getMetaInf().getFilter();
+
+ boolean hasApps = false;
+ boolean hasOther = false;
+ for (PathFilterSet p : filter.getFilterSets()) {
+ if ("cleanup".equals(p.getType())) {
+ continue;
+ }
+ String root = p.getRoot();
+ if ("/apps".equals(root)
+ || root.startsWith("/apps/")
+ || "/libs".equals(root)
+ || root.startsWith("/libs/")) {
+ hasApps = true;
+ } else {
+ hasOther = true;
+ }
+ }
+ if (hasApps && !hasOther) {
+ return PackageType.APPLICATION;
+ } else if (hasOther && !hasApps) {
+ return PackageType.CONTENT;
+ }
+ return PackageType.MIXED;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitter.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitter.java
new file mode 100644
index 0000000..a854b06
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.feature.cpconverter.vltpkg;
+
+import org.apache.jackrabbit.vault.packaging.VaultPackage;
+
+public interface PackagesEventsEmitter {
+
+ void start();
+
+ void end();
+
+ void startPackage(VaultPackage vaultPackage);
+
+ void endPackage();
+
+ void startSubPackage(String path, VaultPackage vaultPackage);
+
+ void endSubPackage();
+
+}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
index 617a6c2..f8808c7 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -47,6 +47,7 @@
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.filtering.RegexBasedResourceFilter;
import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager;
+import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;
import org.apache.sling.feature.io.json.FeatureJSONReader;
import org.junit.After;
import org.junit.Before;
@@ -117,6 +118,7 @@
converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null))
.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
+ .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
.convert(packageFile);
verifyFeatureFile(outputDirectory,
@@ -274,6 +276,7 @@
converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null))
.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
+ .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
.convert(packageFile);
}
@@ -294,6 +297,7 @@
converter.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
.setFeaturesManager(new DefaultFeaturesManager(false, 5, outputDirectory, null, null))
+ .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
.convert(packageFile);
String pid = "this.is.just.a.pid";
@@ -311,6 +315,7 @@
String overrideId = "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0:${project.version}";
converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, overrideId, null))
.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
+ .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
.convert(packageFile);
verifyFeatureFile(outputDirectory,
@@ -378,6 +383,7 @@
converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null))
.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
+ .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
.convert(contentPackages[0]);
File featureFile = new File(outputDirectory, "test_a.json");
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java
new file mode 100644
index 0000000..7bf35bf
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.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.feature.cpconverter.vltpkg;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.StringWriter;
+
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.VaultPackage;
+import org.junit.Test;
+
+public class PackagesEventsEmitterTest {
+
+ @Test
+ public void justCheckEmissions() {
+ VaultPackage parent = mock(VaultPackage.class);
+ when(parent.getPackageType()).thenReturn(PackageType.MIXED);
+ when(parent.getId()).thenReturn(new PackageId("apache/sling", "parent", "1.0.0"));
+ when(parent.getFile()).thenReturn(new File("/org/apache/sling/content-package.zip"));
+
+ StringWriter stringWriter = new StringWriter();
+ PackagesEventsEmitter emitter = new DefaultPackagesEventsEmitter(stringWriter);
+ emitter.start();
+ emitter.startPackage(parent);
+
+ VaultPackage contentChild = mock(VaultPackage.class);
+ when(contentChild.getPackageType()).thenReturn(PackageType.CONTENT);
+ when(contentChild.getId()).thenReturn(new PackageId("apache/sling", "content-child", "1.0.0"));
+ emitter.startSubPackage("/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip", contentChild);
+ emitter.endSubPackage();
+
+ VaultPackage applicationChild = mock(VaultPackage.class);
+ when(applicationChild.getPackageType()).thenReturn(PackageType.APPLICATION);
+ when(applicationChild.getId()).thenReturn(new PackageId("apache/sling", "application-child", "1.0.0"));
+ emitter.startSubPackage("/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip", applicationChild);
+
+ VaultPackage nestedChild = mock(VaultPackage.class);
+ when(nestedChild.getPackageType()).thenReturn(PackageType.CONTAINER);
+ when(nestedChild.getId()).thenReturn(new PackageId("apache/sling", "nested-child", "1.0.0"));
+ emitter.startSubPackage("/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip", nestedChild);
+ emitter.endSubPackage();
+
+ // applicationChild
+ emitter.endSubPackage();
+
+ emitter.endPackage();
+ emitter.end();
+
+ String actual = stringWriter.toString();
+
+ String expected = "/org/apache/sling/content-package.zip,apache/sling:parent:1.0.0,MIXED,,,\n" +
+ "/org/apache/sling/content-package.zip,apache/sling:content-child:1.0.0,CONTENT,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip\n" +
+ "/org/apache/sling/content-package.zip,apache/sling:application-child:1.0.0,APPLICATION,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip\n" +
+ "/org/apache/sling/content-package.zip,apache/sling:nested-child:1.0.0,CONTAINER,apache/sling:application-child:1.0.0,/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip!/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip\n";
+ assertTrue(actual.endsWith(expected));
+ }
+
+}