X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.osgiboot%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fosgiboot%2FOsgiBoot.java;h=788c0babfdd04ff2c39fe7577ee1ab6ea862fe60;hb=af874b12bcb864e1ee2b48e8d6e1fea3a584c53d;hp=3709e1a752c348635873d9def6fadd1e6e3ff286;hpb=5a6f312be273231164d31304311d3fef193cc879;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java b/runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java index 3709e1a75..788c0babf 100644 --- a/runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java +++ b/runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java @@ -1,9 +1,14 @@ package org.argeo.slc.osgiboot; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -14,12 +19,14 @@ import org.argeo.slc.osgiboot.internal.springutil.SystemPropertyUtils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; public class OsgiBoot { public final static String PROP_SLC_OSGI_START = "slc.osgi.start"; public final static String PROP_SLC_OSGI_BUNDLES = "slc.osgi.bundles"; public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations"; public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl"; + public final static String PROP_SLC_OSGI_MODULES_URL = "slc.osgi.modulesUrl"; public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug"; public final static String DEFAULT_BASE_URL = "reference:file:"; @@ -30,6 +37,7 @@ public class OsgiBoot { .booleanValue(); private boolean excludeSvn = true; + private String modulesUrlSeparator = ","; private final BundleContext bundleContext; @@ -37,6 +45,15 @@ public class OsgiBoot { this.bundleContext = bundleContext; } + public void bootstrap() { + info("SLC OSGi bootstrap starting..."); + installUrls(getBundlesUrls()); + installUrls(getLocationsUrls()); + installUrls(getModulesUrls()); + startBundles(); + info("SLC OSGi bootstrap completed"); + } + public void installUrls(List urls) { Map installedBundles = getInstalledBundles(); for (int i = 0; i < urls.size(); i++) { @@ -62,12 +79,51 @@ public class OsgiBoot { } - public void startBundles() throws Exception { + 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); + 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) { + warn("Could not install bundle from " + urlStr + ": " + + e.getMessage()); + } + } + } + + } + + public void startBundles() { String bundlesToStart = getProperty(PROP_SLC_OSGI_START); startBundles(bundlesToStart); } - public void startBundles(String bundlesToStartStr) throws Exception { + public void startBundles(String bundlesToStartStr) { if (bundlesToStartStr == null) return; @@ -80,25 +136,28 @@ public class OsgiBoot { startBundles(bundlesToStart); } - public void startBundles(List bundlesToStart) throws Exception { + public void startBundles(List bundlesToStart) { if (bundlesToStart.size() == 0) return; - Map bundles = getBundles(); - for (int i = 0; i < bundlesToStart.size(); i++) { - String name = bundlesToStart.get(i).toString(); - Bundle bundle = (Bundle) bundles.get(name); - if (bundle != null) + List notStartedBundles = new ArrayList(bundlesToStart); + Bundle[] bundles = bundleContext.getBundles(); + for (int i = 0; i < bundles.length; i++) { + Bundle bundle = bundles[i]; + String symbolicName = bundle.getSymbolicName(); + if (bundlesToStart.contains(symbolicName)) try { bundle.start(); + notStartedBundles.remove(symbolicName); } catch (Exception e) { - warn("Bundle " + name + " cannot be started: " + warn("Bundle " + symbolicName + " cannot be started: " + e.getMessage()); } - else - warn("Bundle " + name + " not installed."); - } + + for (int i = 0; i < notStartedBundles.size(); i++) + warn("Bundle " + notStartedBundles.get(i) + + " not started because it was not found."); } /** Key is location */ @@ -128,6 +187,114 @@ public class OsgiBoot { return getLocationsUrls(baseUrl, bundleLocations); } + public List getModulesUrls() { + List urls = new ArrayList(); + String modulesUrlStr = getProperty(PROP_SLC_OSGI_MODULES_URL); + if (modulesUrlStr == null) + return urls; + + Map installedBundles = getBundles(); + + BufferedReader reader = null; + try { + URL modulesUrl = new URL(modulesUrlStr); + reader = new BufferedReader(new InputStreamReader(modulesUrl + .openStream())); + String line = null; + while ((line = reader.readLine()) != null) { + StringTokenizer st = new StringTokenizer(line, + modulesUrlSeparator); + String moduleName = st.nextToken(); + String moduleVersion = st.nextToken(); + String url = st.nextToken(); + + if (installedBundles.containsKey(moduleName)) { + Bundle bundle = (Bundle) installedBundles.get(moduleName); + String bundleVersion = bundle.getHeaders().get( + Constants.BUNDLE_VERSION).toString(); + int comp = compareVersions(bundleVersion, moduleVersion); + if (comp > 0) { + warn("Installed version " + bundleVersion + + " of bundle " + moduleName + + " is newer than provided version " + + moduleVersion); + } else if (comp < 0) { + urls.add(url); + info("Updated bundle " + moduleName + " with version " + + moduleVersion + " (old version was " + + bundleVersion + ")"); + } else { + // do nothing + } + } else { + urls.add(url); + } + } + } catch (Exception e1) { + throw new RuntimeException("Cannot read url " + modulesUrlStr, e1); + } finally { + if (reader != null) + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return urls; + } + + /** + * @return ==0: versions are identical, <0: tested version is newer, >0: + * currentVersion is newer. + */ + protected int compareVersions(String currentVersion, String testedVersion) { + List cToks = new ArrayList(); + StringTokenizer cSt = new StringTokenizer(currentVersion, "."); + while (cSt.hasMoreTokens()) + cToks.add(cSt.nextToken()); + List tToks = new ArrayList(); + StringTokenizer tSt = new StringTokenizer(currentVersion, "."); + while (tSt.hasMoreTokens()) + tToks.add(tSt.nextToken()); + + int comp = 0; + comp: for (int i = 0; i < cToks.size(); i++) { + if (tToks.size() <= i) { + // equals until then, tested shorter + comp = 1; + break comp; + } + + String c = (String) cToks.get(i); + String t = (String) tToks.get(i); + + try { + int cInt = Integer.parseInt(c); + int tInt = Integer.parseInt(t); + if (cInt == tInt) + continue comp; + else { + comp = (cInt - tInt); + break comp; + } + } catch (NumberFormatException e) { + if (c.equals(t)) + continue comp; + else { + comp = c.compareTo(t); + break comp; + } + } + } + + if (comp == 0 && tToks.size() > cToks.size()) { + // equals until then, current shorter + comp = -1; + } + + return comp; + } + public List getLocationsUrls(String baseUrl, String bundleLocations) { List urls = new ArrayList(); @@ -141,7 +308,7 @@ public class OsgiBoot { StringTokenizer st = new StringTokenizer(bundleLocations, File.pathSeparator); while (st.hasMoreTokens()) { - urls.add(baseUrl + st.nextToken().trim()); + urls.add(locationToUrl(baseUrl, st.nextToken().trim())); } return urls; } @@ -191,7 +358,7 @@ public class OsgiBoot { for (int i = 0; i < included.size(); i++) { String fullPath = (String) included.get(i); if (!excluded.contains(fullPath)) - urls.add(baseUrl + fullPath); + urls.add(locationToUrl(baseUrl, fullPath)); } return urls; @@ -261,18 +428,30 @@ public class OsgiBoot { } } + 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; + } + /** Transforms a relative path in a full system path. */ protected String relativeToFullPath(String basePath, String relativePath) { return (basePath + '/' + relativePath).replace('/', File.separatorChar); } - protected void info(Object obj) { - System.out.println("# INFO " + obj); + protected static void info(Object obj) { + System.out.println("#OSGiBOOT# " + obj); } protected void debug(Object obj) { if (debug) - System.out.println("# DBUG " + obj); + System.out.println("#OSGiBOOT DEBUG# " + obj); } protected void warn(Object obj) {