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());
         }
     }