You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2017/06/09 13:55:06 UTC
svn commit: r1798220 - in
/sling/whiteboard/cziegeler/feature-modelconverter: pom.xml
src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java
Author: cziegeler
Date: Fri Jun 9 13:55:06 2017
New Revision: 1798220
URL: http://svn.apache.org/viewvc?rev=1798220&view=rev
Log:
Update model converter
Modified:
sling/whiteboard/cziegeler/feature-modelconverter/pom.xml
sling/whiteboard/cziegeler/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java
Modified: sling/whiteboard/cziegeler/feature-modelconverter/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-modelconverter/pom.xml?rev=1798220&r1=1798219&r2=1798220&view=diff
==============================================================================
--- sling/whiteboard/cziegeler/feature-modelconverter/pom.xml (original)
+++ sling/whiteboard/cziegeler/feature-modelconverter/pom.xml Fri Jun 9 13:55:06 2017
@@ -56,7 +56,7 @@
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
- <includeArtifactIds>org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.sling.provisioning.model,slf4j-api,slf4j-simple</includeArtifactIds>
+ <includeArtifactIds>commons-cli,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.sling.provisioning.model,slf4j-api,slf4j-simple</includeArtifactIds>
</configuration>
</execution>
</executions>
@@ -90,6 +90,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.3.1</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature</artifactId>
<version>0.0.1-SNAPSHOT</version>
Modified: sling/whiteboard/cziegeler/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java?rev=1798220&r1=1798219&r2=1798220&view=diff
==============================================================================
--- sling/whiteboard/cziegeler/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java (original)
+++ sling/whiteboard/cziegeler/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/Main.java Fri Jun 9 13:55:06 2017
@@ -29,11 +29,22 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
import org.apache.sling.feature.Application;
import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Bundles;
+import org.apache.sling.feature.Configurations;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Extensions;
+import org.apache.sling.feature.KeyValueMap;
import org.apache.sling.feature.json.ApplicationJSONWriter;
+import org.apache.sling.feature.json.FeatureJSONWriter;
import org.apache.sling.feature.support.ArtifactHandler;
import org.apache.sling.feature.support.ArtifactManager;
import org.apache.sling.feature.support.ArtifactManagerConfig;
@@ -58,6 +69,75 @@ public class Main {
private static Logger LOGGER;
+ private static String runModes;
+
+ private static String output;
+
+ private static String input;
+
+ private static boolean createApp = false;
+
+ private static boolean includeModelInfo = false;
+
+ private static String repoUrls;
+
+ /**
+ * Parse the command line parameters and update a configuration object.
+ * @param args Command line parameters
+ * @return Configuration object.
+ */
+ private static void parseArgs(final String[] args) {
+ final Options options = new Options();
+
+ final Option repoOption = new Option("u", true, "Set repository url");
+ final Option modelOption = new Option("f", true, "Set feature files/directories");
+ final Option runModeOption = new Option("r", true, "Set run modes (comma separated)");
+ final Option createAppOption = new Option("a", false, "If enabled, create application json");
+ createAppOption.setArgs(0);
+ final Option includeModelOption = new Option("i", false, "Include model filename as metadata for artifacts");
+ includeModelOption.setArgs(0);
+ final Option outputOption = new Option("o", true, "Set output file");
+ options.addOption(repoOption);
+ options.addOption(modelOption);
+ options.addOption(createAppOption);
+ options.addOption(outputOption);
+ options.addOption(includeModelOption);
+
+ final CommandLineParser clp = new BasicParser();
+ try {
+ final CommandLine cl = clp.parse(options, args);
+
+ if ( cl.hasOption(repoOption.getOpt()) ) {
+ repoUrls = cl.getOptionValue(repoOption.getOpt());
+ }
+ if ( cl.hasOption(modelOption.getOpt()) ) {
+ input = cl.getOptionValue(modelOption.getOpt());
+ }
+ if ( cl.hasOption(createAppOption.getOpt()) ) {
+ createApp = true;
+ }
+ if ( cl.hasOption(includeModelOption.getOpt()) ) {
+ includeModelInfo = true;
+ }
+ if ( cl.hasOption(runModeOption.getOpt()) ) {
+ runModes = cl.getOptionValue(runModeOption.getOpt());
+ }
+ if ( cl.hasOption(outputOption.getOpt()) ) {
+ output = cl.getOptionValue(outputOption.getOpt());
+ }
+ } catch ( final ParseException pe) {
+ LOGGER.error("Unable to parse command line: {}", pe.getMessage(), pe);
+ System.exit(1);
+ }
+ if ( output == null ) {
+ output = createApp ? "application.json" : "feature.json";
+ }
+ if ( input == null ) {
+ LOGGER.error("Required argument missing: model file or directory");
+ System.exit(1);
+ }
+ }
+
public static void main(final String[] args) {
// setup logging
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
@@ -70,24 +150,9 @@ public class Main {
LOGGER.info("Apache Sling Provisiong Model to Feature Application Converter");
LOGGER.info("");
- // first argument is either a model file or a model directory
- if ( args.length == 0 ) {
- LOGGER.error("Required argument missing: model file or directory");
- System.exit(1);
- }
- if ( args.length > 3 ) {
- LOGGER.error("Too many arguments. Only three (model file/dir, run modes and output file) are supported");
- System.exit(1);
- }
- String runModes = null;
- String output = "application.json";
- if ( args.length > 2 ) {
- output = args[2];
- }
- if ( args.length > 1 ) {
- runModes = args[1];
- }
- final File f = new File(args[0]);
+ parseArgs(args);
+
+ final File f = new File(input);
final File[] files;
if ( f.isDirectory() ) {
final List<File> list = new ArrayList<>();
@@ -107,65 +172,48 @@ public class Main {
}
final Model model = createModel(files, runModes);
- final Application app = buildApplication(model);
+ if ( createApp ) {
+ final Application app = buildApplication(model);
- writeApplication(app, output);
+ writeApplication(app, output);
+ } else {
+ final List<org.apache.sling.feature.Feature> features = buildFeatures(model);
+ int index = 1;
+ for(final org.apache.sling.feature.Feature feature : features) {
+ writeFeature(feature, output, index);
+ index++;
+ }
+ }
}
- private static Application buildApplication(final Model model) {
- final Application app = new Application();
+ private static List<org.apache.sling.feature.Feature> buildFeatures(final Model model) {
+ final List<org.apache.sling.feature.Feature> features = new ArrayList<>();
- Extension cpExtension = null;
for(final Feature feature : model.getFeatures() ) {
- for(final RunMode runMode : feature.getRunModes() ) {
- if ( !ModelConstants.FEATURE_LAUNCHPAD.equals(feature.getName()) ) {
- for(final ArtifactGroup group : runMode.getArtifactGroups()) {
- for(final Artifact artifact : group) {
- final ArtifactId id = ArtifactId.fromMvnUrl(artifact.toMvnUrl());
- final org.apache.sling.feature.Artifact newArtifact = new org.apache.sling.feature.Artifact(id);
+ final String idString;
+ if ( feature.getName() != null ) {
+ if ( feature.getVersion() != null ) {
+ idString = "generated/" + feature.getName() + "/" + feature.getVersion();
+ } else {
+ idString = "generated/" + feature.getName() + "/1.0.0";
+ }
+ } else {
+ idString = "generated/feature/1.0.0";
+ }
+ final org.apache.sling.feature.Feature f = new org.apache.sling.feature.Feature(ArtifactId.fromMvnId(idString));
+ features.add(f);
- for(final Map.Entry<String, String> entry : artifact.getMetadata().entrySet()) {
- newArtifact.getMetadata().put(entry.getKey(), entry.getValue());
- }
+ buildFromFeature(feature, f.getBundles(), f.getConfigurations(), f.getExtensions(), f.getFrameworkProperties());
+ }
- if ( newArtifact.getId().getType().equals("zip") ) {
- if ( cpExtension == null ) {
- cpExtension = new Extension(ExtensionType.ARTIFACTS, "content-packages", true);
- app.getExtensions().add(cpExtension);
- }
- cpExtension.getArtifacts().add(newArtifact);
- } else {
- int startLevel = group.getStartLevel();
- if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) {
- startLevel = 1;
- } else if ( startLevel == 0 ) {
- startLevel = 20;
- }
- app.getBundles().add(startLevel, newArtifact);
- }
- }
- }
- }
+ return features;
+ }
- for(final Configuration cfg : runMode.getConfigurations()) {
- final org.apache.sling.feature.Configuration newCfg;
- if ( cfg.getFactoryPid() != null ) {
- newCfg = new org.apache.sling.feature.Configuration(cfg.getFactoryPid(), cfg.getPid());
- } else {
- newCfg = new org.apache.sling.feature.Configuration(cfg.getPid());
- }
- final Enumeration<String> keys = cfg.getProperties().keys();
- while ( keys.hasMoreElements() ) {
- final String key = keys.nextElement();
- newCfg.getProperties().put(key, cfg.getProperties().get(key));
- }
- app.getConfigurations().add(newCfg);
- }
+ private static Application buildApplication(final Model model) {
+ final Application app = new Application();
- for(final Map.Entry<String, String> prop : runMode.getSettings()) {
- app.getFrameworkProperties().put(prop.getKey(), prop.getValue());
- }
- }
+ for(final Feature feature : model.getFeatures() ) {
+ buildFromFeature(feature, app.getBundles(), app.getConfigurations(), app.getExtensions(), app.getFrameworkProperties());
}
// TODO - parse launchpad base to get sling.properties
@@ -177,6 +225,63 @@ public class Main {
return app;
}
+ private static void buildFromFeature(final Feature feature,
+ final Bundles bundles,
+ final Configurations configurations,
+ final Extensions extensions,
+ final KeyValueMap properties) {
+ Extension cpExtension = extensions.getByName("content-packages");
+ for(final RunMode runMode : feature.getRunModes() ) {
+ if ( !ModelConstants.FEATURE_LAUNCHPAD.equals(feature.getName()) ) {
+ for(final ArtifactGroup group : runMode.getArtifactGroups()) {
+ for(final Artifact artifact : group) {
+ final ArtifactId id = ArtifactId.fromMvnUrl(artifact.toMvnUrl());
+ final org.apache.sling.feature.Artifact newArtifact = new org.apache.sling.feature.Artifact(id);
+
+ for(final Map.Entry<String, String> entry : artifact.getMetadata().entrySet()) {
+ newArtifact.getMetadata().put(entry.getKey(), entry.getValue());
+ }
+
+ if ( newArtifact.getId().getType().equals("zip") ) {
+ if ( cpExtension == null ) {
+ cpExtension = new Extension(ExtensionType.ARTIFACTS, "content-packages", true);
+ extensions.add(cpExtension);
+ }
+ cpExtension.getArtifacts().add(newArtifact);
+ } else {
+ int startLevel = group.getStartLevel();
+ if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) {
+ startLevel = 1;
+ } else if ( startLevel == 0 ) {
+ startLevel = 20;
+ }
+ bundles.add(startLevel, newArtifact);
+ }
+ }
+ }
+ }
+
+ for(final Configuration cfg : runMode.getConfigurations()) {
+ final org.apache.sling.feature.Configuration newCfg;
+ if ( cfg.getFactoryPid() != null ) {
+ newCfg = new org.apache.sling.feature.Configuration(cfg.getFactoryPid(), cfg.getPid());
+ } else {
+ newCfg = new org.apache.sling.feature.Configuration(cfg.getPid());
+ }
+ final Enumeration<String> keys = cfg.getProperties().keys();
+ while ( keys.hasMoreElements() ) {
+ final String key = keys.nextElement();
+ newCfg.getProperties().put(key, cfg.getProperties().get(key));
+ }
+ configurations.add(newCfg);
+ }
+
+ for(final Map.Entry<String, String> prop : runMode.getSettings()) {
+ properties.put(prop.getKey(), prop.getValue());
+ }
+ }
+ }
+
private static void writeApplication(final Application app, final String out) {
LOGGER.info("Writing application...");
final File file = new File(out);
@@ -187,6 +292,26 @@ public class Main {
System.exit(1);
}
}
+
+ private static void writeFeature(final org.apache.sling.feature.Feature f, String out, final int index) {
+ LOGGER.info("Writing feature...");
+ if ( index > 1 ) {
+ final int lastDot = out.lastIndexOf('.');
+ if ( lastDot == -1 ) {
+ out = out + "_" + String.valueOf(index);
+ } else {
+ out = out.substring(0, lastDot) + "_" + String.valueOf(index) + out.substring(lastDot);
+ }
+ }
+ final File file = new File(out);
+ try ( final FileWriter writer = new FileWriter(file)) {
+ FeatureJSONWriter.write(writer, f);
+ } catch ( final IOException ioe) {
+ LOGGER.error("Unable to write feature to {} : {}", out, ioe.getMessage(), ioe);
+ System.exit(1);
+ }
+ }
+
/**
* Read the models and prepare the model
* @param files The model files
@@ -270,7 +395,9 @@ public class Main {
} else {
final org.apache.sling.provisioning.model.Artifact realArtifact = nextModel.getFeature(feature.getName()).getRunMode(runMode.getNames()).getArtifactGroup(group.getStartLevel()).search(a);
- realArtifact.getMetadata().put("model-filename", modelFile.getName());
+ if ( includeModelInfo ) {
+ realArtifact.getMetadata().put("model-filename", modelFile.getName());
+ }
if ( runMode.getNames() != null ) {
realArtifact.getMetadata().put("runmodes", String.join(",", runMode.getNames()));
}
@@ -350,12 +477,14 @@ public class Main {
// second pass: aggregate the settings and add them to the first required feature
final Feature requiredFeature = m.getFeature(requiredFeatures[0]);
- for(final Feature f : m.getFeatures()) {
- if ( f.getName().equals(requiredFeature.getName()) ) {
- continue;
+ if ( requiredFeature != null ) {
+ for(final Feature f : m.getFeatures()) {
+ if ( f.getName().equals(requiredFeature.getName()) ) {
+ continue;
+ }
+ copyAndClearSettings(requiredFeature, f.getRunMode(new String[] {ModelConstants.RUN_MODE_STANDALONE}));
+ copyAndClearSettings(requiredFeature, f.getRunMode());
}
- copyAndClearSettings(requiredFeature, f.getRunMode(new String[] {ModelConstants.RUN_MODE_STANDALONE}));
- copyAndClearSettings(requiredFeature, f.getRunMode());
}
}