]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - base/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/osgi/boot/OsgiBoot.java
Add dep folder
[lgpl/argeo-commons.git] / base / runtime / org.argeo.osgi.boot / src / main / java / org / argeo / osgi / boot / OsgiBoot.java
index 6b51038718bb28e35cd14b830c56ded2669e1506..300ebb82dd48ba2802b3328cd832fd3a3dc1dbbe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2012 Mathieu Baudier
+ * Copyright (C) 2007-2012 Argeo GmbH
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.StringTokenizer;
@@ -52,14 +53,18 @@ public class OsgiBoot {
        public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot";
        public final static String SYMBOLIC_NAME_EQUINOX = "org.eclipse.osgi";
 
+       public final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel";
+       public final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel";
+
        public final static String PROP_ARGEO_OSGI_DATA_DIR = "argeo.osgi.data.dir";
 
        public final static String PROP_ARGEO_OSGI_START = "argeo.osgi.start";
        public final static String PROP_ARGEO_OSGI_BUNDLES = "argeo.osgi.bundles";
        public final static String PROP_ARGEO_OSGI_LOCATIONS = "argeo.osgi.locations";
        public final static String PROP_ARGEO_OSGI_BASE_URL = "argeo.osgi.baseUrl";
-       /** Use org.argeo.osgi */
+       /** @deprecated */
        public final static String PROP_ARGEO_OSGI_MODULES_URL = "argeo.osgi.modulesUrl";
+       public final static String PROP_ARGEO_OSGI_DISTRIBUTION_URL = "argeo.osgi.distributionUrl";
 
        // booleans
        public final static String PROP_ARGEO_OSGI_BOOT_DEBUG = "argeo.osgi.boot.debug";
@@ -159,6 +164,7 @@ public class OsgiBoot {
                installUrls(getBundlesUrls());
                installUrls(getLocationsUrls());
                installUrls(getModulesUrls());
+               installUrls(getDistributionUrls());
                checkUnresolved();
                startBundles();
                long duration = System.currentTimeMillis() - begin;
@@ -189,6 +195,14 @@ public class OsgiBoot {
        /*
         * INSTALLATION
         */
+       /** Install a single url. Convenience method. */
+       public Bundle installUrl(String url) {
+               List urls = new ArrayList();
+               urls.add(url);
+               installUrls(urls);
+               return (Bundle) getBundlesByLocation().get(url);
+       }
+
        /** Install the bundles at this URL list. */
        public void installUrls(List urls) {
                Map installedBundles = getBundlesByLocation();
@@ -254,57 +268,88 @@ public class OsgiBoot {
                }
        }
 
-       /* @deprecated Doesn't seem to be used anymore. */
-       // public void installOrUpdateUrls(Map urls) {
-       // Map installedBundles = getBundles();
-       //
-       // for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) {
-       // String moduleName = (String) modules.next();
-       // String urlStr = (String) urls.get(moduleName);
-       // if (installedBundles.containsKey(moduleName)) {
-       // Bundle bundle = (Bundle) installedBundles.get(moduleName);
-       // InputStream in;
-       // try {
-       // URL url = new URL(urlStr);
-       // in = url.openStream();
-       // bundle.update(in);
-       // OsgiBootUtils.info("Updated bundle " + moduleName
-       // + " from " + urlStr);
-       // } catch (Exception e) {
-       // throw new RuntimeException("Cannot update " + moduleName
-       // + " from " + urlStr);
-       // }
-       // if (in != null)
-       // try {
-       // in.close();
-       // } catch (IOException e) {
-       // e.printStackTrace();
-       // }
-       // } else {
-       // try {
-       // Bundle bundle = bundleContext.installBundle(urlStr);
-       // if (debug)
-       // debug("Installed bundle " + bundle.getSymbolicName()
-       // + " from " + urlStr);
-       // } catch (BundleException e) {
-       // OsgiBootUtils.warn("Could not install bundle from "
-       // + urlStr + ": " + e.getMessage());
-       // }
-       // }
-       // }
-       //
-       // }
-
        /*
         * START
         */
        public void startBundles() {
-               String bundlesToStart = OsgiBootUtils
-                               .getProperty(PROP_ARGEO_OSGI_START);
-               startBundles(bundlesToStart);
+               // default and active start levels from System properties
+               Integer defaultStartLevel = new Integer(Integer.parseInt(OsgiBootUtils
+                               .getProperty(PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL, "4")));
+               Integer activeStartLevel = new Integer(OsgiBootUtils.getProperty(
+                               PROP_OSGI_STARTLEVEL, "6"));
+
+               SortedMap/* <Integer, List<String>> */startLevels = new TreeMap();
+               computeStartLevels(startLevels, System.getProperties(),
+                               defaultStartLevel);
+
+               Iterator/* <Integer> */levels = startLevels.keySet().iterator();
+               while (levels.hasNext()) {
+                       Integer level = (Integer) levels.next();
+                       boolean allStarted = startBundles((List) startLevels.get(level));
+                       if (!allStarted)
+                               OsgiBootUtils
+                                               .warn("Not all bundles started for level " + level);
+                       if (level.equals(activeStartLevel))
+                               break;// active start level reached
+               }
+
+       }
+
+       public static void computeStartLevels(
+                       SortedMap/* <Integer, List<String>> */startLevels,
+                       Properties properties, Integer defaultStartLevel) {
+
+               // default (and previously, only behaviour)
+               appendToStartLevels(startLevels, defaultStartLevel,
+                               properties.getProperty(PROP_ARGEO_OSGI_START, ""));
+
+               // list argeo.osgi.start.* system properties
+               Iterator/* <String> */keys = properties.keySet().iterator();
+               final String prefix = PROP_ARGEO_OSGI_START + ".";
+               while (keys.hasNext()) {
+                       String key = (String) keys.next();
+                       if (key.startsWith(prefix)) {
+                               Integer startLevel;
+                               String suffix = key.substring(prefix.length());
+                               String[] tokens = suffix.split("\\.");
+                               if (tokens.length > 0 && !tokens[0].trim().equals(""))
+                                       try {
+                                               // first token is start level
+                                               startLevel = new Integer(tokens[0]);
+                                       } catch (NumberFormatException e) {
+                                               startLevel = defaultStartLevel;
+                                       }
+                               else
+                                       startLevel = defaultStartLevel;
+
+                               // append bundle names
+                               String bundleNames = properties.getProperty(key);
+                               appendToStartLevels(startLevels, startLevel, bundleNames);
+                       }
+               }
+       }
+
+       /** Append a comma-separated list of bundles to the start levels. */
+       private static void appendToStartLevels(
+                       SortedMap/* <Integer, List<String>> */startLevels,
+                       Integer startLevel, String str) {
+               if (str == null || str.trim().equals(""))
+                       return;
+
+               if (!startLevels.containsKey(startLevel))
+                       startLevels.put(startLevel, new ArrayList());
+               String[] bundleNames = str.split(",");
+               for (int i = 0; i < bundleNames.length; i++) {
+                       if (bundleNames[i] != null && !bundleNames[i].trim().equals(""))
+                               ((List) startLevels.get(startLevel)).add(bundleNames[i]);
+               }
        }
 
-       /** Convenience method accepting a comma-separated list of bundle to start */
+       /**
+        * Convenience method accepting a comma-separated list of bundle to start
+        * 
+        * @deprecated
+        */
        public void startBundles(String bundlesToStartStr) {
                if (bundlesToStartStr == null)
                        return;
@@ -318,13 +363,19 @@ public class OsgiBoot {
                startBundles(bundlesToStart);
        }
 
-       /** Start the provided list of bundles */
-       public void startBundles(List bundlesToStart) {
+       /**
+        * Start the provided list of bundles
+        * 
+        * @return whether all bundlesa are now in active state
+        */
+       public boolean startBundles(List bundlesToStart) {
                if (bundlesToStart.size() == 0)
-                       return;
+                       return true;
 
+               // used to monitor ACTIVE states
+               List/* <Bundle> */startedBundles = new ArrayList();
                // used to log the bundles not found
-               List notFoundBundles = new ArrayList(bundlesToStart);
+               List/* <String> */notFoundBundles = new ArrayList(bundlesToStart);
 
                Bundle[] bundles = bundleContext.getBundles();
                long startBegin = System.currentTimeMillis();
@@ -344,6 +395,7 @@ public class OsgiBoot {
                                                                + " waiting and trying again.");
                                                waitForBundleResolvedOrActive(startBegin, bundle);
                                                bundle.start();
+                                               startedBundles.add(bundle);
                                        }
                                        notFoundBundles.remove(symbolicName);
                                } catch (Exception e) {
@@ -357,8 +409,39 @@ public class OsgiBoot {
                }
 
                for (int i = 0; i < notFoundBundles.size(); i++)
-                       OsgiBootUtils.warn("Bundle " + notFoundBundles.get(i)
-                                       + " not started because it was not found.");
+                       OsgiBootUtils.warn("Bundle '" + notFoundBundles.get(i)
+                                       + "' not started because it was not found.");
+
+               // monitors that all bundles are started
+               long beginMonitor = System.currentTimeMillis();
+               boolean allStarted = !(startedBundles.size() > 0);
+               List/* <String> */notStarted = new ArrayList();
+               while (!allStarted
+                               && (System.currentTimeMillis() - beginMonitor) < defaultTimeout) {
+                       notStarted = new ArrayList();
+                       allStarted = true;
+                       for (int i = 0; i < startedBundles.size(); i++) {
+                               Bundle bundle = (Bundle) startedBundles.get(i);
+                               // TODO check behaviour of lazs bundles
+                               if (bundle.getState() != Bundle.ACTIVE) {
+                                       allStarted = false;
+                                       notStarted.add(bundle.getSymbolicName());
+                               }
+                       }
+                       try {
+                               Thread.sleep(100);
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+               }
+               long duration = System.currentTimeMillis() - beginMonitor;
+
+               if (!allStarted)
+                       for (int i = 0; i < notStarted.size(); i++)
+                               OsgiBootUtils.warn("Bundle '" + notStarted.get(i)
+                                               + "' not ACTIVE after " + (duration / 1000) + "s");
+
+               return allStarted;
        }
 
        /*
@@ -434,7 +517,7 @@ public class OsgiBoot {
                int currentState = bundle.getState();
                while (!(currentState == Bundle.RESOLVED || currentState == Bundle.ACTIVE)) {
                        long now = System.currentTimeMillis();
-                       if ((now - startBegin) > defaultTimeout)
+                       if ((now - startBegin) > defaultTimeout * 10)
                                throw new Exception("Bundle " + bundle.getSymbolicName()
                                                + " was not RESOLVED or ACTIVE after "
                                                + (now - startBegin) + "ms (originalState="
@@ -496,15 +579,23 @@ public class OsgiBoot {
         * effects.
         */
        public List getBundlesUrls() {
-               String baseUrl = OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BASE_URL,
-                               DEFAULT_BASE_URL);
                String bundlePatterns = OsgiBootUtils
                                .getProperty(PROP_ARGEO_OSGI_BUNDLES);
+               return getBundlesUrls(bundlePatterns);
+       }
+
+       /**
+        * Compute alist of URLs to install based on the provided patterns, with
+        * default base url
+        */
+       public List getBundlesUrls(String bundlePatterns) {
+               String baseUrl = OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BASE_URL,
+                               DEFAULT_BASE_URL);
                return getBundlesUrls(baseUrl, bundlePatterns);
        }
 
        /** Implements the path matching logic */
-       public List getBundlesUrls(String baseUrl, String bundlePatterns) {
+       List getBundlesUrls(String baseUrl, String bundlePatterns) {
                List urls = new ArrayList();
                if (bundlePatterns == null)
                        return urls;
@@ -552,6 +643,34 @@ public class OsgiBoot {
                return urls;
        }
 
+       /*
+        * DISTRIBUTION JAR INSTALLATION
+        */
+       public List getDistributionUrls() {
+               List urls = new ArrayList();
+               String distributionUrl = OsgiBootUtils
+                               .getProperty(PROP_ARGEO_OSGI_DISTRIBUTION_URL);
+               if (distributionUrl == null)
+                       return urls;
+               String baseUrl = OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BASE_URL);
+
+               DistributionBundle distributionBundle;
+               if (baseUrl != null
+                               && !(distributionUrl.startsWith("http") || distributionUrl
+                                               .startsWith("file"))) {
+                       // relative url
+                       distributionBundle = new DistributionBundle(baseUrl,
+                                       distributionUrl);
+               } else {
+                       distributionBundle = new DistributionBundle(distributionUrl);
+                       if (baseUrl != null)
+                               distributionBundle.setBaseUrl(baseUrl);
+
+               }
+               distributionBundle.processUrl();
+               return distributionBundle.listUrls();
+       }
+
        /*
         * MODULES LIST INSTALLATION (${argeo.osgi.modulesUrl})
         */
@@ -561,6 +680,8 @@ public class OsgiBoot {
         * If ${argeo.osgi.baseUrl} is set, URLs will be considered relative paths
         * and be concatenated with the base URL, typically the root of a Maven
         * repository.
+        * 
+        * @deprecated
         */
        public List getModulesUrls() {
                List urls = new ArrayList();
@@ -728,15 +849,15 @@ public class OsgiBoot {
 
        /** Creates an URL from a location */
        protected String locationToUrl(String baseUrl, String location) {
-               int extInd = location.lastIndexOf('.');
-               String ext = null;
-               if (extInd > 0)
-                       ext = location.substring(extInd);
-
-               if (baseUrl.startsWith("reference:") && ".jar".equals(ext))
-                       return "file:" + location;
-               else
-                       return baseUrl + location;
+               // int extInd = location.lastIndexOf('.');
+               // String ext = null;
+               // if (extInd > 0)
+               // ext = location.substring(extInd);
+               //
+               // if (baseUrl.startsWith("reference:") && ".jar".equals(ext))
+               // return "file:" + location;
+               // else
+               return baseUrl + location;
        }
 
        /** Transforms a relative path in a full system path. */
@@ -871,4 +992,45 @@ public class OsgiBoot {
 
        }
 
+       /* @deprecated Doesn't seem to be used anymore. */
+       // public void installOrUpdateUrls(Map urls) {
+       // Map installedBundles = getBundles();
+       //
+       // for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) {
+       // String moduleName = (String) modules.next();
+       // String urlStr = (String) urls.get(moduleName);
+       // if (installedBundles.containsKey(moduleName)) {
+       // Bundle bundle = (Bundle) installedBundles.get(moduleName);
+       // InputStream in;
+       // try {
+       // URL url = new URL(urlStr);
+       // in = url.openStream();
+       // bundle.update(in);
+       // OsgiBootUtils.info("Updated bundle " + moduleName
+       // + " from " + urlStr);
+       // } catch (Exception e) {
+       // throw new RuntimeException("Cannot update " + moduleName
+       // + " from " + urlStr);
+       // }
+       // if (in != null)
+       // try {
+       // in.close();
+       // } catch (IOException e) {
+       // e.printStackTrace();
+       // }
+       // } else {
+       // try {
+       // Bundle bundle = bundleContext.installBundle(urlStr);
+       // if (debug)
+       // debug("Installed bundle " + bundle.getSymbolicName()
+       // + " from " + urlStr);
+       // } catch (BundleException e) {
+       // OsgiBootUtils.warn("Could not install bundle from "
+       // + urlStr + ": " + e.getMessage());
+       // }
+       // }
+       // }
+       //
+       // }
+
 }