This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.crankstart.launcher-1.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-crankstart-launcher.git
commit c8f35d32605c2d001d503f07c499cbd0ff03a0c9 Author: Bertrand Delacretaz <[email protected]> AuthorDate: Tue Apr 22 12:40:50 2014 +0000 Use more flexible command pattern git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/crankstart/launcher@1589114 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 14 ++- .../sling/crankstart/CrankstartFileProcessor.java | 140 --------------------- .../launcher/CrankstartFileProcessor.java | 81 ++++++++++++ .../sling/crankstart/{ => launcher}/Main.java | 2 +- .../launcher/commands/InstallBundle.java | 52 ++++++++ .../{Main.java => launcher/commands/Log.java} | 42 +++---- .../commands/SetOsgiFrameworkProperty.java | 47 +++++++ .../crankstart/launcher/commands/StartBundles.java | 48 +++++++ .../launcher/commands/StartFramework.java | 43 +++++++ .../{Main.java => launcher/commands/U.java} | 29 +---- 10 files changed, 307 insertions(+), 191 deletions(-) diff --git a/pom.xml b/pom.xml index 72a30d4..54e8c79 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> - <name>Apache Sling Crankstart Module</name> + <name>Apache Sling Crankstart Launcher</name> <inceptionYear>2014</inceptionYear> <description> @@ -34,7 +34,7 @@ <configuration> <archive> <manifest> - <mainClass>org.apache.sling.crankstart.Main</mainClass> + <mainClass>org.apache.sling.crankstart.launcher.Main</mainClass> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> </archive> @@ -50,7 +50,7 @@ <goal>unpack-dependencies</goal> </goals> <configuration> - <includeGroupIds>org.osgi,org.apache.felix,org.slf4j,javax.servlet,org.ops4j.pax.url</includeGroupIds> + <includeGroupIds>org.osgi,org.apache.felix,org.slf4j,javax.servlet,org.ops4j.pax.url,org.apache.sling</includeGroupIds> <excludeTransitive>false</excludeTransitive> <outputDirectory>${project.build.directory}/classes</outputDirectory> <overWriteReleases>false</overWriteReleases> @@ -89,11 +89,19 @@ <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>4.2.0</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.framework</artifactId> <version>4.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.crankstart.api</artifactId> + <version>0.0.1-SNAPSHOT</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> diff --git a/src/main/java/org/apache/sling/crankstart/CrankstartFileProcessor.java b/src/main/java/org/apache/sling/crankstart/CrankstartFileProcessor.java deleted file mode 100644 index 424064b..0000000 --- a/src/main/java/org/apache/sling/crankstart/CrankstartFileProcessor.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.crankstart; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.net.URL; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleException; -import org.osgi.framework.launch.Framework; -import org.osgi.framework.launch.FrameworkFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Process a crankstart file */ -public class CrankstartFileProcessor { - public static final String I_BUNDLE = "bundle "; - public static final String I_START_ALL_BUNDLES = "start.all.bundles"; - public static final String I_LOG = "log"; - public static final String I_START_FRAMEWORK = "start.framework"; - public static final String I_OSGI_PROPERTY = "osgi.property"; - - private Framework framework; - private final List<Bundle> bundles = new LinkedList<Bundle>(); - private final Logger log = LoggerFactory.getLogger(getClass()); - private final Map<String, String> osgiProperties = new HashMap<String, String>(); - - public CrankstartFileProcessor() { - System.setProperty( "java.protocol.handler.pkgs", "org.ops4j.pax.url" ); - } - - public void process(Reader input) throws IOException, BundleException { - final BufferedReader r = new BufferedReader(input); - String line = null; - while((line = r.readLine()) != null) { - processLine(line); - } - } - - private String removePrefix(String line, String prefix) { - return line.substring(prefix.length()).trim(); - } - - private void processLine(String line) throws IOException, BundleException { - line = line.trim(); - if(line.length() == 0 || line.startsWith("#")) { - // ignore comments and blank lines - } else if(line.startsWith(I_BUNDLE)) { - bundle(removePrefix(line, I_BUNDLE)); - } else if(line.startsWith(I_START_ALL_BUNDLES)) { - startAllBundles(); - } else if(line.startsWith(I_LOG)) { - log.info(removePrefix(line, I_LOG)); - } else if(line.startsWith(I_START_FRAMEWORK)) { - startFramework(); - } else if(line.startsWith(I_OSGI_PROPERTY)) { - osgiProperty(removePrefix(line, I_OSGI_PROPERTY)); - } else { - log.warn("Invalid command line: [{}]", line); - } - } - - private void osgiProperty(String line) { - final String [] parts = line.split(" "); - if(parts.length != 2) { - log.warn("Invalid OSGi property [{}]", line); - return; - } - final String key = parts[0].trim(); - final String value = parts[1].trim(); - log.info("Setting OSGI property {}={}", key, value); - osgiProperties.put(key, value); - } - - private void startFramework() throws BundleException { - if(framework != null) { - throw new IllegalStateException("OSGi framework already created"); - } - - // TODO get framework as a Maven artifact? - FrameworkFactory frameworkFactory = java.util.ServiceLoader.load(FrameworkFactory.class).iterator().next(); - framework = frameworkFactory.newFramework(osgiProperties); - framework.start(); - - log.info("OSGi framework started"); - } - - private void bundle(String line) throws IOException, BundleException { - final URL url = new URL( "mvn:" + line); - final BundleContext ctx = framework.getBundleContext(); - final String ref = "crankstart://" + line; - final InputStream bundleStream = url.openStream(); - try { - bundles.add(ctx.installBundle(ref, url.openStream())); - log.info("bundle installed: {}", ref); - } finally { - bundleStream.close(); - } - } - - public void waitForExit() throws InterruptedException { - log.info("Waiting for OSGi framework to exit..."); - framework.waitForStop(0); - } - - private void startAllBundles() throws BundleException { - for (Bundle bundle : bundles) { - log.info("Starting bundle {}", bundle.getSymbolicName()); - bundle.start(); - } - - // TODO check that all bundles have started? - // or use a crankstart instruction for that? - - log.info("{} bundles installed", bundles.size()); - } - -} diff --git a/src/main/java/org/apache/sling/crankstart/launcher/CrankstartFileProcessor.java b/src/main/java/org/apache/sling/crankstart/launcher/CrankstartFileProcessor.java new file mode 100644 index 0000000..c3e6794 --- /dev/null +++ b/src/main/java/org/apache/sling/crankstart/launcher/CrankstartFileProcessor.java @@ -0,0 +1,81 @@ +/* + * 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.crankstart.launcher; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.apache.sling.crankstart.launcher.commands.InstallBundle; +import org.apache.sling.crankstart.launcher.commands.Log; +import org.apache.sling.crankstart.launcher.commands.SetOsgiFrameworkProperty; +import org.apache.sling.crankstart.launcher.commands.StartBundles; +import org.apache.sling.crankstart.launcher.commands.StartFramework; +import org.osgi.framework.BundleException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Process a crankstart file */ +public class CrankstartFileProcessor { + private final CrankstartContext crankstartContext = new CrankstartContext(); + private final Logger log = LoggerFactory.getLogger(getClass()); + private List<CrankstartCommand> commands = new ArrayList<CrankstartCommand>(); + + public CrankstartFileProcessor() { + System.setProperty( "java.protocol.handler.pkgs", "org.ops4j.pax.url" ); + + commands.add(new InstallBundle()); + commands.add(new Log()); + commands.add(new SetOsgiFrameworkProperty()); + commands.add(new StartBundles()); + commands.add(new StartFramework()); + } + + public void process(Reader input) throws IOException, BundleException { + final BufferedReader r = new BufferedReader(input); + String line = null; + while((line = r.readLine()) != null) { + if(line.length() == 0 || line.startsWith("#")) { + // ignore comments and blank lines + } else { + for(CrankstartCommand c : commands) { + if(c.appliesTo(line)) { + try { + c.execute(crankstartContext, line); + } catch(Exception e) { + log.warn("Command execution failed", e); + } + break; + } + } + } + } + } + + public void waitForExit() throws InterruptedException { + if(crankstartContext.getOsgiFramework() == null) { + throw new IllegalStateException("OSGi framework not started"); + } + log.info("Waiting for OSGi framework to exit..."); + crankstartContext.getOsgiFramework().waitForStop(0); + log.info("OSGi framework exited"); + } +} diff --git a/src/main/java/org/apache/sling/crankstart/Main.java b/src/main/java/org/apache/sling/crankstart/launcher/Main.java similarity index 97% copy from src/main/java/org/apache/sling/crankstart/Main.java copy to src/main/java/org/apache/sling/crankstart/launcher/Main.java index 04c4a90..e858143 100644 --- a/src/main/java/org/apache/sling/crankstart/Main.java +++ b/src/main/java/org/apache/sling/crankstart/launcher/Main.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.crankstart; +package org.apache.sling.crankstart.launcher; import java.io.File; import java.io.FileReader; diff --git a/src/main/java/org/apache/sling/crankstart/launcher/commands/InstallBundle.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/InstallBundle.java new file mode 100644 index 0000000..1df274c --- /dev/null +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/InstallBundle.java @@ -0,0 +1,52 @@ +/* + * 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.crankstart.launcher.commands; + +import java.io.InputStream; +import java.net.URL; + +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** CrankstartCommand that installs a bundle */ +public class InstallBundle implements CrankstartCommand { + public static final String I_BUNDLE = "bundle "; + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Override + public boolean appliesTo(String commandLine) { + return commandLine.startsWith(I_BUNDLE); + } + + @Override + public void execute(CrankstartContext crankstartContext, String commandLine) throws Exception { + final String bundleRef = U.removePrefix(I_BUNDLE, commandLine); + final URL url = new URL( "mvn:" + bundleRef); + final BundleContext ctx = crankstartContext.getOsgiFramework().getBundleContext(); + final String ref = "crankstart://" + bundleRef; + final InputStream bundleStream = url.openStream(); + try { + ctx.installBundle(ref, url.openStream()); + log.info("bundle installed: {}", ref); + } finally { + bundleStream.close(); + } + } +} diff --git a/src/main/java/org/apache/sling/crankstart/Main.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/Log.java similarity index 50% copy from src/main/java/org/apache/sling/crankstart/Main.java copy to src/main/java/org/apache/sling/crankstart/launcher/commands/Log.java index 04c4a90..569c83d 100644 --- a/src/main/java/org/apache/sling/crankstart/Main.java +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/Log.java @@ -14,29 +14,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.crankstart; +package org.apache.sling.crankstart.launcher.commands; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** Execute a crankstart file */ -public class Main { - public static void main(String [] args) throws Exception { - String crankFile = "default.crank.txt"; - if(args.length < 1) { - System.err.println("Using default crank file " + crankFile); - System.err.println("To use a different one, provide its name as a jar file argument"); - } else { - crankFile = args[0]; - } - final Reader r = new FileReader(new File(crankFile)); - try { - final CrankstartFileProcessor p = new CrankstartFileProcessor(); - p.process(r); - p.waitForExit(); - } finally { - r.close(); - } +/** CrankstartCommand that logs a message */ +public class Log implements CrankstartCommand { + public static final String I_LOG = "log"; + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Override + public boolean appliesTo(String commandLine) { + return commandLine.startsWith(I_LOG); } -} \ No newline at end of file + + @Override + public void execute(CrankstartContext crankstartContext, String commandLine) throws Exception { + log.info(U.removePrefix(I_LOG, commandLine)); + } +} diff --git a/src/main/java/org/apache/sling/crankstart/launcher/commands/SetOsgiFrameworkProperty.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/SetOsgiFrameworkProperty.java new file mode 100644 index 0000000..4661430 --- /dev/null +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/SetOsgiFrameworkProperty.java @@ -0,0 +1,47 @@ +/* + * 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.crankstart.launcher.commands; + +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** CrankstartCommand that logs a message */ +public class SetOsgiFrameworkProperty implements CrankstartCommand { + public static final String I_OSGI_PROPERTY = "osgi.property"; + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Override + public boolean appliesTo(String commandLine) { + return commandLine.startsWith(I_OSGI_PROPERTY); + } + + @Override + public void execute(CrankstartContext crankstartContext, String commandLine) throws Exception { + final String args = U.removePrefix(I_OSGI_PROPERTY, commandLine); + final String [] parts = args.split(" "); + if(parts.length != 2) { + log.warn("Invalid OSGi property statement, ignored: [{}]", commandLine); + return; + } + final String key = parts[0].trim(); + final String value = parts[1].trim(); + log.info("Setting OSGI property {}={}", key, value); + crankstartContext.setOsgiFrameworkProperty(key, value); + } +} diff --git a/src/main/java/org/apache/sling/crankstart/launcher/commands/StartBundles.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/StartBundles.java new file mode 100644 index 0000000..bcd0eda --- /dev/null +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/StartBundles.java @@ -0,0 +1,48 @@ +/* + * 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.crankstart.launcher.commands; + +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** CrankstartCommand that logs a message */ +public class StartBundles implements CrankstartCommand { + public static final String I_START_ALL_BUNDLES = "start.all.bundles"; + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Override + public boolean appliesTo(String commandLine) { + return commandLine.startsWith(I_START_ALL_BUNDLES); + } + + @Override + public void execute(CrankstartContext crankstartContext, String commandLine) throws Exception { + int count = 0; + for (Bundle bundle : crankstartContext.getOsgiFramework().getBundleContext().getBundles()) { + log.info("Starting bundle {}", bundle.getSymbolicName()); + bundle.start(); + count++; + } + + // TODO check that all bundles have started? + // or use a crankstart instruction for that? + log.info("{} bundles processed", count); + } +} diff --git a/src/main/java/org/apache/sling/crankstart/launcher/commands/StartFramework.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/StartFramework.java new file mode 100644 index 0000000..205d1c9 --- /dev/null +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/StartFramework.java @@ -0,0 +1,43 @@ +/* + * 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.crankstart.launcher.commands; + +import org.apache.sling.crankstart.api.CrankstartCommand; +import org.apache.sling.crankstart.api.CrankstartContext; +import org.osgi.framework.launch.FrameworkFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** CrankstartCommand that logs a message */ +public class StartFramework implements CrankstartCommand { + public static final String I_START_FRAMEWORK = "start.framework"; + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Override + public boolean appliesTo(String commandLine) { + return commandLine.startsWith(I_START_FRAMEWORK); + } + + @Override + public void execute(CrankstartContext crankstartContext, String commandLine) throws Exception { + // TODO get framework as a Maven artifact? + FrameworkFactory frameworkFactory = java.util.ServiceLoader.load(FrameworkFactory.class).iterator().next(); + crankstartContext.setOsgiFramework(frameworkFactory.newFramework(crankstartContext.getOsgiFrameworkProperties())); + crankstartContext.getOsgiFramework().start(); + log.info("OSGi framework started"); + } +} diff --git a/src/main/java/org/apache/sling/crankstart/Main.java b/src/main/java/org/apache/sling/crankstart/launcher/commands/U.java similarity index 50% rename from src/main/java/org/apache/sling/crankstart/Main.java rename to src/main/java/org/apache/sling/crankstart/launcher/commands/U.java index 04c4a90..d736771 100644 --- a/src/main/java/org/apache/sling/crankstart/Main.java +++ b/src/main/java/org/apache/sling/crankstart/launcher/commands/U.java @@ -14,29 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.crankstart; +package org.apache.sling.crankstart.launcher.commands; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; - -/** Execute a crankstart file */ -public class Main { - public static void main(String [] args) throws Exception { - String crankFile = "default.crank.txt"; - if(args.length < 1) { - System.err.println("Using default crank file " + crankFile); - System.err.println("To use a different one, provide its name as a jar file argument"); - } else { - crankFile = args[0]; - } - final Reader r = new FileReader(new File(crankFile)); - try { - final CrankstartFileProcessor p = new CrankstartFileProcessor(); - p.process(r); - p.waitForExit(); - } finally { - r.close(); - } +class U { + static String removePrefix(String prefix, String line) { + return line.substring(prefix.length()).trim(); } -} \ No newline at end of file +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
