Author: rickhall Date: Fri Dec 14 13:55:01 2007 New Revision: 604310 URL: http://svn.apache.org/viewvc?rev=604310&view=rev Log: Removed auto-property processing out of the framework and into the default launcher. (FELIX-393)
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java felix/trunk/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java felix/trunk/main/src/main/java/org/apache/felix/main/Main.java Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=604310&r1=604309&r2=604310&view=diff ============================================================================== --- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original) +++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Fri Dec 14 13:55:01 2007 @@ -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 Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java?rev=604310&r1=604309&r2=604310&view=diff ============================================================================== --- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java (original) +++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java Fri Dec 14 13:55:01 2007 @@ -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 Modified: felix/trunk/main/src/main/java/org/apache/felix/main/Main.java URL: http://svn.apache.org/viewvc/felix/trunk/main/src/main/java/org/apache/felix/main/Main.java?rev=604310&r1=604309&r2=604310&view=diff ============================================================================== --- felix/trunk/main/src/main/java/org/apache/felix/main/Main.java (original) +++ felix/trunk/main/src/main/java/org/apache/felix/main/Main.java Fri Dec 14 13:55:01 2007 @@ -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