Author: pauls Date: Sun Sep 17 22:26:51 2017 New Revision: 1808660 URL: http://svn.apache.org/viewvc?rev=1808660&view=rev Log: Add a start of an application builder - for now, it just takes features and turns them into an application but ultimately, it should probably be where we resolve things as well.
Added: sling/whiteboard/cziegeler/feature-applicationbuilder/ (with props) sling/whiteboard/cziegeler/feature-applicationbuilder/pom.xml sling/whiteboard/cziegeler/feature-applicationbuilder/src/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java Propchange: sling/whiteboard/cziegeler/feature-applicationbuilder/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Sep 17 22:26:51 2017 @@ -0,0 +1,2 @@ +*.iml +target Added: sling/whiteboard/cziegeler/feature-applicationbuilder/pom.xml URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-applicationbuilder/pom.xml?rev=1808660&view=auto ============================================================================== --- sling/whiteboard/cziegeler/feature-applicationbuilder/pom.xml (added) +++ sling/whiteboard/cziegeler/feature-applicationbuilder/pom.xml Sun Sep 17 22:26:51 2017 @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + <!-- + 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>30</version> + <relativePath /> + </parent> + + <artifactId>org.apache.sling.feature.applicationbuilder</artifactId> + <version>0.0.1-SNAPSHOT</version> + + <name>Apache Sling Feature Application Builder</name> + <description> + A feature describes an OSGi system + </description> + + <properties> + <sling.java.version>8</sling.java.version> + </properties> + + <scm> + <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-applicationbuilder</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-applicationbuilder</developerConnection> + <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-applicationbuilder</url> + </scm> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>unpack-dependencies</id> + <phase>prepare-package</phase> + <goals> + <goal>unpack-dependencies</goal> + </goals> + <configuration> + <excludes>META-INF/**</excludes> + <outputDirectory>${project.build.directory}/classes</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <includeArtifactIds>commons-cli,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,slf4j-api,slf4j-simple,osgi.core</includeArtifactIds> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>org.apache.sling.feature.applicationbuilder.impl.Main</mainClass> + </manifest> + </archive> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <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> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.feature.support</artifactId> + <version>0.0.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.johnzon</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <!-- Testing --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> +</project> Added: sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java?rev=1808660&view=auto ============================================================================== --- sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java (added) +++ sling/whiteboard/cziegeler/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java Sun Sep 17 22:26:51 2017 @@ -0,0 +1,189 @@ +/* + * 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.applicationbuilder.impl; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +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.support.ArtifactHandler; +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.ApplicationJSONReader; +import org.apache.sling.feature.support.json.ApplicationJSONWriter; +import org.apache.sling.feature.support.json.FeatureJSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Main { + + private static Logger LOGGER; + + private static String output; + + private static String input; + + private static String repoUrls; + + private static String propsFile; + + /** + * 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 Option repoOption = Option.builder("u").hasArg().argName("Set repository url") + .desc("repository url").required().build(); + + final Option modelOption = new Option("f", true, "Set feature files/directories"); + final Option propsOption = new Option("p", true, "sling.properties file"); + + + final Option outputOption = Option.builder("o").hasArg().argName("Set output file") + .desc("output file").build(); + + final Options options = new Options(); + options.addOption(repoOption); + options.addOption(modelOption); + options.addOption(outputOption); + options.addOption(propsOption); + + final CommandLineParser parser = new DefaultParser(); + try { + final CommandLine cl = parser.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(outputOption.getOpt()) ) { + output = cl.getOptionValue(outputOption.getOpt()); + } + if ( cl.hasOption(propsOption.getOpt()) ) { + propsFile = cl.getOptionValue(propsOption.getOpt()); + } + } catch ( final ParseException pe) { + LOGGER.error("Unable to parse command line: {}", pe.getMessage(), pe); + System.exit(1); + } + if ( input == null ) { + LOGGER.error("Required argument missing: model file or directory"); + System.exit(1); + } + } + + private static ArtifactManager getArtifactManager() { + final ArtifactManagerConfig amConfig = new ArtifactManagerConfig(); + if ( repoUrls != null ) { + amConfig.setRepositoryUrls(repoUrls.split(",")); + } + try { + return ArtifactManager.getArtifactManager(amConfig); + } catch ( IOException ioe) { + LOGGER.error("Unable to create artifact manager " + ioe.getMessage(), ioe); + System.exit(1); + } + // we never reach this, but have to keep the compiler happy + return null; + } + + public static void main(final String[] args) { + // setup logging + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info"); + System.setProperty("org.slf4j.simpleLogger.showThreadName", "false"); + System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true"); + System.setProperty("org.slf4j.simpleLogger.showLogName", "false"); + + LOGGER = LoggerFactory.getLogger("applicationbuilder"); + + LOGGER.info("Apache Sling Feature Application Builder"); + LOGGER.info(""); + + parseArgs(args); + + final ArtifactManagerConfig amConfig = new ArtifactManagerConfig(); + if ( repoUrls != null ) { + amConfig.setRepositoryUrls(repoUrls.split(",")); + } + final ArtifactManager am = getArtifactManager(); + + final File f = new File(input); + final List<File> files = new ArrayList<>(); + if ( f.isDirectory() ) { + for(final File file : f.listFiles()) { + if ( file.isFile() && !file.getName().startsWith(".") ) { + files.add(file); + } + } + if ( files.isEmpty() ) { + LOGGER.error("No files found in {}", f); + System.exit(1); + } + Collections.sort(files); + } else { + files.add(f); + } + + + try { + writeApplication(FeatureUtil.assembleApplication(null, am, files.stream() + .map(File::getAbsolutePath) + .toArray(String[]::new)), output == null ? "application.json" : output); + + } catch ( final IOException ioe) { + LOGGER.error("Unable to read feature/application files " + ioe.getMessage(), ioe); + System.exit(1); + } + } + + private static void writeApplication(final Application app, final String out) { + LOGGER.info("Writing application..."); + final File file = new File(out); + try ( final FileWriter writer = new FileWriter(file)) { + ApplicationJSONWriter.write(writer, app); + } catch ( final IOException ioe) { + LOGGER.error("Unable to write application to {} : {}", out, ioe.getMessage(), ioe); + System.exit(1); + } + } +}