Modifed default launcher in Main to separate out auto-property processing
so that it is easier to reuse the code in custom launchers. (FELIX-448)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@609721 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/main/src/main/java/org/apache/felix/main/AutoActivator.java b/main/src/main/java/org/apache/felix/main/AutoActivator.java
new file mode 100644
index 0000000..387d9c5
--- /dev/null
+++ b/main/src/main/java/org/apache/felix/main/AutoActivator.java
@@ -0,0 +1,213 @@
+/*
+ * 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.felix.main;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.startlevel.StartLevel;
+
+public class AutoActivator implements BundleActivator
+{
+ /**
+ * The property name prefix for the launcher's auto-install property.
+ **/
+ public static final String AUTO_INSTALL_PROP = "felix.auto.install";
+ /**
+ * The property name prefix for the launcher's auto-start property.
+ **/
+ public static final String AUTO_START_PROP = "felix.auto.start";
+
+ private Map m_configMap;
+
+ public AutoActivator(Map configMap)
+ {
+ m_configMap = configMap;
+ }
+
+ /**
+ * Used to instigate auto-install and auto-start configuration
+ * property processing via a custom framework activator during
+ * framework startup.
+ * @param context The system bundle context.
+ **/
+ public void start(BundleContext context)
+ {
+ processAutoProperties(context);
+ }
+
+ /**
+ * Currently does nothing as part of framework shutdown.
+ * @param context The system bundle context.
+ **/
+ public void stop(BundleContext context)
+ {
+ // Do nothing.
+ }
+
+ /**
+ * <p>
+ * Processes the auto-install and auto-start properties from the
+ * specified configuration properties.
+ * </p>
+ */
+ private void processAutoProperties(BundleContext context)
+ {
+ // Retrieve the Start Level service, since it will be needed
+ // to set the start level of the installed bundles.
+ StartLevel sl = (StartLevel) context.getService(
+ context.getServiceReference(org.osgi.service.startlevel.StartLevel.class.getName()));
+
+ // Retrieve all auto-install and auto-start properties and install
+ // their associated bundles. The auto-install property specifies a
+ // space-delimited list of bundle URLs to be automatically installed
+ // into each new profile, while the auto-start property specifies
+ // bundles to be installed and started. The start level to which the
+ // bundles are assigned is specified by appending a ".n" to the
+ // property name, where "n" is the desired start level for the list
+ // of bundles. If no start level is specified, the default start
+ // level is assumed.
+ for (Iterator i = m_configMap.keySet().iterator(); i.hasNext(); )
+ {
+ String key = (String) i.next();
+
+ // Ignore all keys that are not an auto property.
+ if (!key.startsWith(AUTO_INSTALL_PROP) && !key.startsWith(AUTO_START_PROP))
+ {
+ continue;
+ }
+
+ // If the auto property does not have a start level,
+ // then assume it is the default bundle start level, otherwise
+ // parse the specified start level.
+ int startLevel = sl.getInitialBundleStartLevel();
+ if (!key.equals(AUTO_INSTALL_PROP) && !key.equals(AUTO_START_PROP))
+ {
+ try
+ {
+ startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
+ }
+ catch (NumberFormatException ex)
+ {
+ System.err.println("Invalid property: " + key);
+ }
+ }
+
+ // Parse and install the bundles associated with the key.
+ StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ", true);
+ for (String location = nextLocation(st); location != null; location = nextLocation(st))
+ {
+ try
+ {
+ Bundle b = context.installBundle(location, null);
+ sl.setBundleStartLevel(b, startLevel);
+ }
+ catch (Exception ex)
+ {
+ System.err.println("Auto-properties install: " + ex);
+ }
+ }
+ }
+
+ // Now loop through the auto-start bundles and start them.
+ for (Iterator i = m_configMap.keySet().iterator(); i.hasNext(); )
+ {
+ String key = (String) i.next();
+ if (key.startsWith(AUTO_START_PROP))
+ {
+ StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ", true);
+ for (String location = nextLocation(st); location != null; location = nextLocation(st))
+ {
+ // Installing twice just returns the same bundle.
+ try
+ {
+ Bundle b = context.installBundle(location, null);
+ if (b != null)
+ {
+ b.start();
+ }
+ }
+ catch (Exception ex)
+ {
+ System.err.println("Auto-properties start: " + ex);
+ }
+ }
+ }
+ }
+ }
+
+ private static String nextLocation(StringTokenizer st)
+ {
+ String retVal = null;
+
+ if (st.countTokens() > 0)
+ {
+ String tokenList = "\" ";
+ StringBuffer tokBuf = new StringBuffer(10);
+ String tok = null;
+ boolean inQuote = false;
+ boolean tokStarted = false;
+ boolean exit = false;
+ while ((st.hasMoreTokens()) && (!exit))
+ {
+ tok = st.nextToken(tokenList);
+ if (tok.equals("\""))
+ {
+ inQuote = ! inQuote;
+ if (inQuote)
+ {
+ tokenList = "\"";
+ }
+ else
+ {
+ tokenList = "\" ";
+ }
+
+ }
+ else if (tok.equals(" "))
+ {
+ if (tokStarted)
+ {
+ retVal = tokBuf.toString();
+ tokStarted=false;
+ tokBuf = new StringBuffer(10);
+ exit = true;
+ }
+ }
+ else
+ {
+ tokStarted = true;
+ tokBuf.append(tok.trim());
+ }
+ }
+
+ // Handle case where end of token stream and
+ // still got data
+ if ((!exit) && (tokStarted))
+ {
+ retVal = tokBuf.toString();
+ }
+ }
+
+ return retVal;
+ }
+}
\ No newline at end of file
diff --git a/main/src/main/java/org/apache/felix/main/Main.java b/main/src/main/java/org/apache/felix/main/Main.java
index a854545..fb69a61 100644
--- a/main/src/main/java/org/apache/felix/main/Main.java
+++ b/main/src/main/java/org/apache/felix/main/Main.java
@@ -26,8 +26,6 @@
import org.apache.felix.framework.Felix;
import org.apache.felix.framework.cache.BundleCache;
import org.apache.felix.framework.util.StringMap;
-import org.osgi.framework.*;
-import org.osgi.service.startlevel.StartLevel;
/**
* <p>
@@ -38,7 +36,7 @@
* worthwhile to reuse some of its property handling capabilities.
* </p>
**/
-public class Main implements BundleActivator
+public class Main
{
/**
* The property name used to specify an URL to the system
@@ -62,39 +60,10 @@
* The default name used for the default configuration properties file.
**/
public static final String DEFAULT_PROPERTIES_FILE_VALUE = "default.properties";
- /**
- * The property name prefix for the launcher's auto-install property.
- **/
- public static final String AUTO_INSTALL_PROP = "felix.auto.install";
- /**
- * The property name prefix for the launcher's auto-start property.
- **/
- public static final String AUTO_START_PROP = "felix.auto.start";
- private static Properties m_configProps = null;
private static Felix m_felix = null;
/**
- * Used to instigate auto-install and auto-start configuration
- * property processing via a custom framework activator during
- * framework startup.
- * @param context The system bundle context.
- **/
- public void start(BundleContext context)
- {
- Main.processAutoProperties(context);
- }
-
- /**
- * Currently does nothing as part of framework shutdown.
- * @param context The system bundle context.
- **/
- public void stop(BundleContext context)
- {
- // Do nothing.
- }
-
- /**
* <p>
* This method performs the main task of constructing an framework instance
* and starting its execution. The following functions are performed
@@ -202,16 +171,16 @@
Main.loadSystemProperties();
// Read configuration properties.
- m_configProps = Main.loadConfigProperties();
+ Properties configProps = Main.loadConfigProperties();
// Copy framework properties from the system properties.
- Main.copySystemProperties(m_configProps);
+ Main.copySystemProperties(configProps);
// See if the profile name property was specified.
- String profileName = m_configProps.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ String profileName = configProps.getProperty(BundleCache.CACHE_PROFILE_PROP);
// See if the profile directory property was specified.
- String profileDirName = m_configProps.getProperty(BundleCache.CACHE_PROFILE_DIR_PROP);
+ String profileDirName = configProps.getProperty(BundleCache.CACHE_PROFILE_DIR_PROP);
// Print welcome banner.
System.out.println("\nWelcome to Felix.");
@@ -235,7 +204,7 @@
System.out.println("");
if (profileName.length() != 0)
{
- m_configProps.setProperty(BundleCache.CACHE_PROFILE_PROP, profileName);
+ configProps.setProperty(BundleCache.CACHE_PROFILE_PROP, profileName);
}
}
@@ -251,9 +220,9 @@
// Create a list for custom framework activators and
// add an instance of Main to process auto-properties.
List list = new ArrayList();
- list.add(new Main());
+ list.add(new AutoActivator(configProps));
// Now create an instance of the framework.
- Map configMap = new StringMap(m_configProps, false);
+ Map configMap = new StringMap(configProps, false);
m_felix = new Felix(configMap, list);
m_felix.start();
}
@@ -267,222 +236,6 @@
/**
* <p>
- * Processes the auto-install and auto-start properties from the
- * specified configuration properties.
- */
- private static void processAutoProperties(BundleContext context)
- {
- // Retrieve the Start Level service, since it will be needed
- // to set the start level of the installed bundles.
- StartLevel sl = (StartLevel) context.getService(
- context.getServiceReference(org.osgi.service.startlevel.StartLevel.class.getName()));
-
- // The auto-install property specifies a space-delimited list of
- // bundle URLs to be automatically installed into each new profile;
- // the start level to which the bundles are assigned is specified by
- // appending a ".n" to the auto-install property name, where "n" is
- // the desired start level for the list of bundles.
- for (Iterator i = m_configProps.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
-
- // Ignore all keys that are not the auto-install property.
- if (!key.startsWith(AUTO_INSTALL_PROP))
- {
- continue;
- }
-
- // If the auto-install property does not have a start level,
- // then assume it is the default bundle start level, otherwise
- // parse the specified start level.
- int startLevel = sl.getInitialBundleStartLevel();
- if (!key.equals(AUTO_INSTALL_PROP))
- {
- try
- {
- startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
- }
- catch (NumberFormatException ex)
- {
- System.err.println("Invalid property: " + key);
- }
- }
-
- StringTokenizer st = new StringTokenizer(m_configProps.getProperty(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- try
- {
- Bundle b = context.installBundle(location, null);
- sl.setBundleStartLevel(b, startLevel);
- }
- catch (Exception ex)
- {
- System.err.println("Auto-properties install: " + ex);
- }
- }
- }
- while (location != null);
- }
- }
-
- // The auto-start property specifies a space-delimited list of
- // bundle URLs to be automatically installed and started into each
- // new profile; the start level to which the bundles are assigned
- // is specified by appending a ".n" to the auto-start property name,
- // where "n" is the desired start level for the list of bundles.
- // The following code starts bundles in two passes, first it installs
- // them, then it starts them.
- for (Iterator i = m_configProps.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
-
- // Ignore all keys that are not the auto-start property.
- if (!key.startsWith(AUTO_START_PROP))
- {
- continue;
- }
-
- // If the auto-start property does not have a start level,
- // then assume it is the default bundle start level, otherwise
- // parse the specified start level.
- int startLevel = sl.getInitialBundleStartLevel();
- if (!key.equals(AUTO_START_PROP))
- {
- try
- {
- startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
- }
- catch (NumberFormatException ex)
- {
- System.err.println("Invalid property: " + key);
- }
- }
-
- StringTokenizer st = new StringTokenizer(m_configProps.getProperty(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- try
- {
- Bundle b = context.installBundle(location, null);
- sl.setBundleStartLevel(b, startLevel);
- }
- catch (Exception ex)
- {
- System.err.println("Auto-properties install:" + ex);
- }
- }
- }
- while (location != null);
- }
- }
-
- // Now loop through and start the installed bundles.
- for (Iterator i = m_configProps.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
- if (key.startsWith(AUTO_START_PROP))
- {
- StringTokenizer st = new StringTokenizer(m_configProps.getProperty(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- // Installing twice just returns the same bundle.
- try
- {
- Bundle b = context.installBundle(location, null);
- if (b != null)
- {
- b.start();
- }
- }
- catch (Exception ex)
- {
- System.err.println("Auto-properties start: " + ex);
- }
- }
- }
- while (location != null);
- }
- }
- }
- }
-
- private static String nextLocation(StringTokenizer st)
- {
- String retVal = null;
-
- if (st.countTokens() > 0)
- {
- String tokenList = "\" ";
- StringBuffer tokBuf = new StringBuffer(10);
- String tok = null;
- boolean inQuote = false;
- boolean tokStarted = false;
- boolean exit = false;
- while ((st.hasMoreTokens()) && (!exit))
- {
- tok = st.nextToken(tokenList);
- if (tok.equals("\""))
- {
- inQuote = ! inQuote;
- if (inQuote)
- {
- tokenList = "\"";
- }
- else
- {
- tokenList = "\" ";
- }
-
- }
- else if (tok.equals(" "))
- {
- if (tokStarted)
- {
- retVal = tokBuf.toString();
- tokStarted=false;
- tokBuf = new StringBuffer(10);
- exit = true;
- }
- }
- else
- {
- tokStarted = true;
- tokBuf.append(tok.trim());
- }
- }
-
- // Handle case where end of token stream and
- // still got data
- if ((!exit) && (tokStarted))
- {
- retVal = tokBuf.toString();
- }
- }
-
- return retVal;
- }
-
- /**
- * <p>
* Loads the properties in the system property file associated with the
* framework installation into <tt>System.setProperty()</tt>. These properties
* are not directly used by the framework in anyway. By default, the system