Removed auto-property processing out of the framework and into the default
launcher. (FELIX-393)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@604310 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 8b3c641..254b5e6 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -113,8 +113,8 @@
/**
* <p>
- * This method starts the framework instance; instances of the framework
- * are dormant until this method is called. The caller may also provide
+ * This method creates the framework instance; instances of the framework
+ * are not active until they are started. The constructor accepts a
* <tt>Map</tt> instance that will be used to obtain configuration or
* framework properties. Configuration properties are used internally by
* the framework and its extensions to alter its default behavior.
@@ -148,18 +148,6 @@
* OSGi Log Service (i.e., 1 = error, 2 = warning, 3 = information,
* and 4 = debug). The default value is 1.
* </li>
- * <li><tt>felix.auto.install.<n></tt> - Space-delimited list of
- * bundles to automatically install into start level <tt>n</tt> when
- * the framework is started. Append a specific start level to this
- * property name to assign the bundles' start level
- * (e.g., <tt>felix.auto.install.2</tt>).
- * </li>
- * <li><tt>felix.auto.start.<n></tt> - Space-delimited list of
- * bundles to automatically install and start into start level
- * <tt>n</tt> when the framework is started. Append a
- * specific start level to this property name to assign the
- * bundles' start level(e.g., <tt>felix.auto.start.2</tt>).
- * </li>
* <li><tt>felix.startlevel.framework</tt> - The initial start level
* of the framework once it starts execution; the default
* value is 1.
@@ -195,12 +183,6 @@
* API documentation.
* </p>
* <p>
- * Framework properties are somewhat misnamed, since they are not used by
- * the framework, but by bundles via <tt>BundleContext.getProperty()</tt>.
- * Please refer to bundle documentation of your specific bundle for any
- * available properties.
- * </p>
- * <p>
* The <a href="Main.html"><tt>Main</tt></a> class implements some
* functionality for default property file handling, which makes it
* possible to specify configuration properties and framework properties
@@ -210,7 +192,7 @@
* class documentation for more information.
* </p>
*
- * @param configMutableMap An map for obtaining configuration properties,
+ * @param configMutableMap A map for obtaining configuration properties,
* may be <tt>null</tt>.
* @param activatorList A list of System Bundle activators.
**/
@@ -219,7 +201,7 @@
// Initialize member variables.
m_configMutableMap = (configMutableMap == null)
? new StringMap(false) : configMutableMap;
- m_configMap = createUnmodifiableMap(m_configMutableMap);
+ m_configMap = createUnmodifiableMap(m_configMutableMap);
m_activatorList = activatorList;
// Create logger with appropriate log level. Even though the
@@ -271,15 +253,15 @@
m_factory.createModule("0", m_extensionManager));
}
- private Map createUnmodifiableMap(Map mutableMap)
+ private Map createUnmodifiableMap(Map mutableMap)
{
Map result = Collections.unmodifiableMap(mutableMap);
- // Work around a bug in certain version of J9 where a call to
- // Collections.unmodifiableMap().keySet().iterator() throws
- // a NoClassDefFoundError. We try to detect this and return
+ // Work around a bug in certain version of J9 where a call to
+ // Collections.unmodifiableMap().keySet().iterator() throws
+ // a NoClassDefFoundError. We try to detect this and return
// the given mutableMap instead.
- try
+ try
{
result.keySet().iterator();
}
@@ -684,60 +666,10 @@
// Initialize event dispatcher.
m_dispatcher = EventDispatcher.start(m_logger);
- // Before we reload any cached bundles, let's create a system
- // bundle that is responsible for providing specific container
- // related services.
- try
- {
- IContentLoader cl = m_extensionManager;
- cl.setSearchPolicy(
- new R4SearchPolicy(
- m_policyCore, m_systemBundleInfo.getCurrentModule()));
- m_factory.setContentLoader(
- m_systemBundleInfo.getCurrentModule(),
- cl);
- m_factory.setSecurityContext(
- m_systemBundleInfo.getCurrentModule(),
- getClass().getProtectionDomain());
-
- m_installedBundleMap.put(
- m_systemBundleInfo.getLocation(), this);
-
- // Manually resolve the System Bundle, which will cause its
- // state to be set to RESOLVED.
- try
- {
- m_policyCore.resolve(m_systemBundleInfo.getCurrentModule());
- }
- catch (ResolveException ex)
- {
- // This should never happen.
- throw new BundleException(
- "Unresolved package in System Bundle:"
- + ex.getRequirement());
- }
-
- // Create system bundle activator.
- m_systemBundleInfo.setActivator(new SystemBundleActivator());
-
- // Create the bundle context for the system bundle and
- // then activate it.
- m_systemBundleInfo.setBundleContext(new BundleContextImpl(m_logger, this, this));
- Felix.m_secureAction.startActivator(m_systemBundleInfo.getActivator(), m_systemBundleInfo.getBundleContext());
- }
- catch (Throwable ex)
- {
- m_factory = null;
- EventDispatcher.shutdown();
- m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
- throw new RuntimeException("Unable to start system bundle.");
- }
-
- // Now that the system bundle is successfully created we can give
- // its bundle context to the logger so that it can track log services.
- m_logger.setSystemBundleContext(m_systemBundleInfo.getBundleContext());
-
- // Now reload the cached bundles.
+ // Reload the cached bundles bundles before creating and starting
+ // the system bundle, since we want all cached bundles to be reloaded
+ // when we activate the system bundle and any subsequent custom
+ // framework activators passed into the framework constructor.
BundleArchive[] archives = null;
// First get cached bundle identifiers.
@@ -826,8 +758,58 @@
}
}
- // Load bundles from auto-install and auto-start properties;
- processAutoProperties();
+ // Now that the cached bundles are reloaded, create the system
+ // bundle that is responsible for providing specific container
+ // related services and activating all custom framework activators.
+ try
+ {
+ IContentLoader cl = m_extensionManager;
+ cl.setSearchPolicy(
+ new R4SearchPolicy(
+ m_policyCore, m_systemBundleInfo.getCurrentModule()));
+ m_factory.setContentLoader(
+ m_systemBundleInfo.getCurrentModule(),
+ cl);
+ m_factory.setSecurityContext(
+ m_systemBundleInfo.getCurrentModule(),
+ getClass().getProtectionDomain());
+
+ m_installedBundleMap.put(
+ m_systemBundleInfo.getLocation(), this);
+
+ // Manually resolve the System Bundle, which will cause its
+ // state to be set to RESOLVED.
+ try
+ {
+ m_policyCore.resolve(m_systemBundleInfo.getCurrentModule());
+ }
+ catch (ResolveException ex)
+ {
+ // This should never happen.
+ throw new BundleException(
+ "Unresolved package in System Bundle:"
+ + ex.getRequirement());
+ }
+
+ // Create system bundle activator.
+ m_systemBundleInfo.setActivator(new SystemBundleActivator());
+
+ // Create the bundle context for the system bundle and
+ // then activate it.
+ m_systemBundleInfo.setBundleContext(new BundleContextImpl(m_logger, this, this));
+ Felix.m_secureAction.startActivator(m_systemBundleInfo.getActivator(), m_systemBundleInfo.getBundleContext());
+ }
+ catch (Throwable ex)
+ {
+ m_factory = null;
+ EventDispatcher.shutdown();
+ m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
+ throw new RuntimeException("Unable to start system bundle.");
+ }
+
+ // Now that the system bundle is successfully created we can give
+ // its bundle context to the logger so that it can track log services.
+ m_logger.setSystemBundleContext(m_systemBundleInfo.getBundleContext());
// Set the start level using the start level service;
// this ensures that all start level requests are
@@ -3615,214 +3597,6 @@
return sb.toString();
}
- private void processAutoProperties()
- {
- // 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_configMap.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
-
- // Ignore all keys that are not the auto-install property.
- if (!key.startsWith(FelixConstants.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 = getInitialBundleStartLevel();
- if (!key.equals(FelixConstants.AUTO_INSTALL_PROP))
- {
- try
- {
- startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
- }
- catch (NumberFormatException ex)
- {
- m_logger.log(Logger.LOG_ERROR, "Invalid property: " + key);
- }
- }
-
- StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- try
- {
- FelixBundle b = (FelixBundle) installBundle(location, null);
- b.getInfo().setStartLevel(startLevel);
- }
- catch (Exception ex)
- {
- m_logger.log(
- Logger.LOG_ERROR, "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_configMap.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
-
- // Ignore all keys that are not the auto-start property.
- if (!key.startsWith(FelixConstants.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 = getInitialBundleStartLevel();
- if (!key.equals(FelixConstants.AUTO_START_PROP))
- {
- try
- {
- startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
- }
- catch (NumberFormatException ex)
- {
- m_logger.log(Logger.LOG_ERROR, "Invalid property: " + key);
- }
- }
-
- StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- try
- {
- FelixBundle b = (FelixBundle) installBundle(location, null);
- b.getInfo().setStartLevel(startLevel);
- }
- catch (Exception ex)
- {
- m_logger.log(Logger.LOG_ERROR, "Auto-properties install.", ex);
- }
- }
- }
- while (location != null);
- }
- }
-
- // Now loop through and start the installed bundles.
- for (Iterator i = m_configMap.keySet().iterator(); i.hasNext(); )
- {
- String key = (String) i.next();
- if (key.startsWith(FelixConstants.AUTO_START_PROP))
- {
- StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ",true);
- if (st.countTokens() > 0)
- {
- String location = null;
- do
- {
- location = nextLocation(st);
- if (location != null)
- {
- // Installing twice just returns the same bundle.
- try
- {
- FelixBundle bundle = (FelixBundle) installBundle(location, null);
- if (bundle != null)
- {
- startBundle(bundle, true);
- }
- }
- catch (Exception ex)
- {
- m_logger.log(
- Logger.LOG_ERROR, "Auto-properties start.", ex);
- }
- }
- }
- while (location != null);
- }
- }
- }
- }
-
- private 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;
- }
-
//
// Private utility methods.
//
@@ -3940,11 +3714,11 @@
}
// Add the bundle activator for the package admin service.
- m_activatorList.add(new PackageAdminActivator(Felix.this));
+ m_activatorList.add(0, new PackageAdminActivator(Felix.this));
// Add the bundle activator for the start level service.
- m_activatorList.add(new StartLevelActivator(m_logger, Felix.this));
+ m_activatorList.add(0, new StartLevelActivator(m_logger, Felix.this));
// Add the bundle activator for the url handler service.
- m_activatorList.add(new URLHandlersActivator(m_configMap, Felix.this));
+ m_activatorList.add(0, new URLHandlersActivator(m_configMap, Felix.this));
// Start all activators.
for (int i = 0; i < m_activatorList.size(); i++)
@@ -4574,4 +4348,4 @@
m_bundleLock.notifyAll();
}
}
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java b/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
index bb5ab86..3c9861a 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
@@ -43,8 +43,6 @@
// Miscellaneous framework configuration property names.
public static final String LOG_LEVEL_PROP = "felix.log.level";
- public static final String AUTO_INSTALL_PROP = "felix.auto.install";
- public static final String AUTO_START_PROP = "felix.auto.start";
public static final String EMBEDDED_EXECUTION_PROP = "felix.embedded.execution";
public static final String STRICT_OSGI_PROP = "felix.strict.osgi";
public static final String FRAMEWORK_STARTLEVEL_PROP
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 7d4444c..0fea622 100644
--- a/main/src/main/java/org/apache/felix/main/Main.java
+++ b/main/src/main/java/org/apache/felix/main/Main.java
@@ -25,7 +25,12 @@
import org.apache.felix.framework.Felix;
import org.apache.felix.framework.cache.BundleCache;
+import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.StringMap;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.startlevel.StartLevel;
/**
* <p>
@@ -33,15 +38,13 @@
* intended to be the only way to instantiate and execute the framework; rather, it is
* one example of how to do so. When embedding the framework in a host application,
* this class can serve as a simple guide of how to do so. It may even be
- * worthwhile to reuse some of its property handling capabilities. This class
- * is completely static and is only intended to start a single instance of
- * the framework.
+ * worthwhile to reuse some of its property handling capabilities.
* </p>
**/
-public class Main
+public class Main implements BundleActivator
{
/**
- * The system property name used to specify an URL to the system
+ * The property name used to specify an URL to the system
* property file.
**/
public static final String SYSTEM_PROPERTIES_PROP = "felix.system.properties";
@@ -50,7 +53,7 @@
**/
public static final String SYSTEM_PROPERTIES_FILE_VALUE = "system.properties";
/**
- * The system property name used to specify an URL to the configuration
+ * The property name used to specify an URL to the configuration
* property file to be used for the created the framework instance.
**/
public static final String CONFIG_PROPERTIES_PROP = "felix.config.properties";
@@ -62,10 +65,39 @@
* 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
@@ -80,7 +112,8 @@
* The only properties defined in this file that will impact the framework's
* behavior are the those concerning setting HTTP proxies, such as
* <tt>http.proxyHost</tt>, <tt>http.proxyPort</tt>, and
- * <tt>http.proxyAuth</tt>.
+ * <tt>http.proxyAuth</tt>. Generally speaking, the framework does
+ * not use system properties at all.
* </li>
* <li><i><b>Perform system property variable substitution on system
* properties.</b></i> Any system properties in the system property
@@ -122,7 +155,7 @@
* <a href="cache/DefaultBundleCache.html"><tt>DefaultBundleCache</tt></a>
* documentation for more details its configuration options.
* </li>
- * <li><i><b>Creates and starts a framework instance.</b></i> A
+ * <li><i><b>Creates and starts a framework instance.</b></i> A
* case insensitive
* <a href="util/StringMap.html"><tt>StringMap</tt></a>
* is created for the configuration property file and is passed
@@ -138,30 +171,50 @@
* interact with the framework are installed or if the configuration property
* file cannot be found, the framework will appear to be hung or deadlocked.
* This is not the case, it is executing correctly, there is just no way to
- * interact with it. Refer to the
- * <a href="Felix.html#Felix(java.util.Map, java.util.List)">
- * <tt>Felix</tt></a> constructor documentation for more information on
- * framework configuration options.
+ * interact with it. The default launcher provides two configuration properties
+ * to help you automatically install and/or start bundles, which are:
+ * </p>
+ * <ul>
+ * <li><tt>felix.auto.install.<n></tt> - Space-delimited list of
+ * bundle URLs to automatically install into start level <tt>n</tt> when
+ * the framework is started. Append a specific start level to this
+ * property name to assign the bundles' start level
+ * (e.g., <tt>felix.auto.install.2</tt>); otherwise, bundles are
+ * installed into the default bundle start level.
+ * </li>
+ * <li><tt>felix.auto.start.<n></tt> - Space-delimited list of
+ * bundle URLs to automatically install and start into start level
+ * <tt>n</tt> when the framework is started. Append a
+ * specific start level to this property name to assign the
+ * bundles' start level(e.g., <tt>felix.auto.start.2</tt>); otherwise,
+ * bundles are installed into the default bundle start level.
+ * </li>
+ * </ul>
+ * <p>
+ * These properties should be specified in the <tt>config.properties</tt>
+ * so that they can be processed by the launcher during the framework
+ * startup process.
* </p>
* @param argv An array of arguments, all of which are ignored.
* @throws Exception If an error occurs.
**/
+
public static void main(String[] argv) throws Exception
{
// Load system properties.
Main.loadSystemProperties();
// Read configuration properties.
- Properties configProps = Main.loadConfigProperties();
+ m_configProps = Main.loadConfigProperties();
// Copy framework properties from the system properties.
- Main.copySystemProperties(configProps);
+ Main.copySystemProperties(m_configProps);
// See if the profile name property was specified.
- String profileName = configProps.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ String profileName = m_configProps.getProperty(BundleCache.CACHE_PROFILE_PROP);
// See if the profile directory property was specified.
- String profileDirName = configProps.getProperty(BundleCache.CACHE_PROFILE_DIR_PROP);
+ String profileDirName = m_configProps.getProperty(BundleCache.CACHE_PROFILE_DIR_PROP);
// Print welcome banner.
System.out.println("\nWelcome to Felix.");
@@ -185,7 +238,7 @@
System.out.println("");
if (profileName.length() != 0)
{
- configProps.setProperty(BundleCache.CACHE_PROFILE_PROP, profileName);
+ m_configProps.setProperty(BundleCache.CACHE_PROFILE_PROP, profileName);
}
}
@@ -198,8 +251,13 @@
try
{
+ // 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());
// Now create an instance of the framework.
- m_felix = new Felix(new StringMap(configProps, false), null);
+ Map configMap = new StringMap(m_configProps, false);
+ m_felix = new Felix(configMap, list);
m_felix.start();
}
catch (Exception ex)
@@ -212,6 +270,222 @@
/**
* <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
@@ -455,7 +729,7 @@
for (Enumeration e = System.getProperties().propertyNames();
e.hasMoreElements(); )
{
- String key = (String)e.nextElement();
+ String key = (String) e.nextElement();
if (key.startsWith("felix.") ||
key.equals("org.osgi.framework.system.packages") ||
key.equals("org.osgi.framework.bootdelegation"))
@@ -588,4 +862,4 @@
// Return the value.
return val;
}
-}
+}
\ No newline at end of file