X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.osgi.boot%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fboot%2FOsgiBoot.java;h=4c3ee40f0c2095da9860af6f4ef4316a72ae5c59;hb=6d6fd0f20eda4331d35e7beb5d14aacdb3a98ad8;hp=607f6264b2c9c76809759b1ac4bae43d3330f71d;hpb=8260f4470f514ea347ca53f5b4dfc632c4a4de66;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java index 607f6264b..4c3ee40f0 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java @@ -19,7 +19,7 @@ import static org.argeo.osgi.boot.OsgiBootUtils.debug; import static org.argeo.osgi.boot.OsgiBootUtils.warn; import java.io.File; -import java.io.IOException; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -31,6 +31,7 @@ import java.util.SortedMap; import java.util.StringTokenizer; import java.util.TreeMap; +import org.argeo.osgi.boot.a2.ProvisioningManager; import org.argeo.osgi.boot.internal.springutil.AntPathMatcher; import org.argeo.osgi.boot.internal.springutil.PathMatcher; import org.argeo.osgi.boot.internal.springutil.SystemPropertyUtils; @@ -38,8 +39,10 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.FrameworkEvent; +import org.osgi.framework.Version; import org.osgi.framework.startlevel.BundleStartLevel; import org.osgi.framework.startlevel.FrameworkStartLevel; +import org.osgi.framework.wiring.FrameworkWiring; /** * Basic provisioning of an OSGi runtime via file path patterns and system @@ -47,46 +50,50 @@ import org.osgi.framework.startlevel.FrameworkStartLevel; * methods, configured via properties. */ public class OsgiBoot implements OsgiBootConstants { - // 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_SOURCES = "argeo.osgi.sources"; + public final static String PROP_ARGEO_OSGI_BUNDLES = "argeo.osgi.bundles"; public final static String PROP_ARGEO_OSGI_BASE_URL = "argeo.osgi.baseUrl"; + public final static String PROP_ARGEO_OSGI_LOCAL_CACHE = "argeo.osgi.localCache"; 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"; - public final static String PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN = "argeo.osgi.boot.excludeSvn"; + // public final static String PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN = + // "argeo.osgi.boot.excludeSvn"; - // public final static String PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT = - // "argeo.osgi.boot.defaultTimeout"; public final static String PROP_ARGEO_OSGI_BOOT_SYSTEM_PROPERTIES_FILE = "argeo.osgi.boot.systemPropertiesFile"; public final static String PROP_ARGEO_OSGI_BOOT_APPCLASS = "argeo.osgi.boot.appclass"; public final static String PROP_ARGEO_OSGI_BOOT_APPARGS = "argeo.osgi.boot.appargs"; public final static String DEFAULT_BASE_URL = "reference:file:"; - public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**"; + // public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**"; // OSGi system properties - public final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel"; - public final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel"; - public final static String INSTANCE_AREA_PROP = "osgi.instance.area"; - // public final static String INSTANCE_AREA_DEFAULT_PROP = - // "osgi.instance.area.default"; + final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel"; + final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel"; + final static String INSTANCE_AREA_PROP = "osgi.instance.area"; + final static String CONFIGURATION_AREA_PROP = "osgi.configuration.area"; // Symbolic names public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot"; public final static String SYMBOLIC_NAME_EQUINOX = "org.eclipse.osgi"; - private boolean debug = Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_DEBUG, "false")).booleanValue(); /** Exclude svn metadata implicitely(a bit costly) */ - private boolean excludeSvn = Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN, "false")) - .booleanValue(); + // private boolean excludeSvn = + // Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN, + // "false")) + // .booleanValue(); - // /** Default is 10s (set in constructor) */ - // private long defaultTimeout; + /** Default is 10s */ + @Deprecated + private long defaultTimeout = 10000l; private final BundleContext bundleContext; + private final String localCache; + + private final ProvisioningManager provisioningManager; /* * INITIALIZATION @@ -94,37 +101,23 @@ public class OsgiBoot implements OsgiBootConstants { /** Constructor */ public OsgiBoot(BundleContext bundleContext) { this.bundleContext = bundleContext; - // defaultTimeout = - // Long.parseLong(OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT, - // "10000")); - // initSystemProperties(); + String homeUri = Paths.get(System.getProperty("user.home")).toUri().toString(); + localCache = getProperty(PROP_ARGEO_OSGI_LOCAL_CACHE, homeUri + ".m2/repository/"); + + provisioningManager = new ProvisioningManager(bundleContext); + String sources = getProperty(PROP_ARGEO_OSGI_SOURCES); + if (sources == null) { + provisioningManager.registerDefaultSource(); + } else { + for (String source : sources.split(",")) { + provisioningManager.registerSource(source); + } + } } - // /** - // * Set additional system properties, especially ${argeo.osgi.data.dir} as - // an - // * OS file path (and not a file:// URL) - // */ - // private void initSystemProperties() { - // String osgiInstanceArea = System.getProperty(INSTANCE_AREA_PROP); - // String osgiInstanceAreaDefault = - // System.getProperty(INSTANCE_AREA_DEFAULT_PROP); - // String tempDir = System.getProperty("java.io.tmpdir"); - // - // File dataDir = null; - // if (osgiInstanceArea != null) { - // // within OSGi with -data specified - // osgiInstanceArea = removeFilePrefix(osgiInstanceArea); - // dataDir = new File(osgiInstanceArea); - // } else if (osgiInstanceAreaDefault != null) { - // // within OSGi without -data specified - // osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault); - // dataDir = new File(osgiInstanceAreaDefault); - // } else {// outside OSGi - // dataDir = new File(tempDir + File.separator + "argeoOsgiData"); - // } - // System.setProperty(PROP_ARGEO_OSGI_DATA_DIR, dataDir.getAbsolutePath()); - // } + ProvisioningManager getProvisioningManager() { + return provisioningManager; + } /* * HIGH-LEVEL METHODS @@ -137,11 +130,9 @@ public class OsgiBoot implements OsgiBootConstants { String osgiInstancePath = bundleContext.getProperty(INSTANCE_AREA_PROP); OsgiBootUtils .info("OSGi bootstrap starting" + (osgiInstancePath != null ? " (" + osgiInstancePath + ")" : "")); - // OsgiBootUtils.info("Writable data directory : " + - // System.getProperty(PROP_ARGEO_OSGI_DATA_DIR) - // + " (set as system property " + PROP_ARGEO_OSGI_DATA_DIR + ")"); installUrls(getBundlesUrls()); installUrls(getDistributionUrls()); + provisioningManager.install(null); startBundles(); long duration = System.currentTimeMillis() - begin; OsgiBootUtils.info("OSGi bootstrap completed in " + Math.round(((double) duration) / 1000) + "s (" @@ -152,7 +143,7 @@ public class OsgiBoot implements OsgiBootConstants { } // diagnostics - if (debug) { + if (OsgiBootUtils.debug) { OsgiBootDiagnostics diagnostics = new OsgiBootDiagnostics(bundleContext); diagnostics.checkUnresolved(); Map> duplicatePackages = diagnostics.findPackagesExportedTwice(); @@ -172,6 +163,10 @@ public class OsgiBoot implements OsgiBootConstants { System.out.println(); } + public void update() { + provisioningManager.update(); + } + /* * INSTALLATION */ @@ -190,6 +185,7 @@ public class OsgiBoot implements OsgiBootConstants { String url = (String) urls.get(i); installUrl(url, installedBundles); } + refreshFramework(); } /** Actually install the provided URL */ @@ -197,30 +193,68 @@ public class OsgiBoot implements OsgiBootConstants { try { if (installedBundles.containsKey(url)) { Bundle bundle = (Bundle) installedBundles.get(url); - if (debug) + if (OsgiBootUtils.debug) debug("Bundle " + bundle.getSymbolicName() + " already installed from " + url); } else if (url.contains("/" + SYMBOLIC_NAME_EQUINOX + "/") || url.contains("/" + SYMBOLIC_NAME_OSGI_BOOT + "/")) { - if (debug) + if (OsgiBootUtils.debug) warn("Skip " + url); return; } else { - Bundle bundle = bundleContext.installBundle(url); - OsgiBootUtils - .info("Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url); + if (url.startsWith("http")) + OsgiBootUtils + .info("Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url); + else if (OsgiBootUtils.debug) + OsgiBootUtils.debug( + "Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url); + assert bundle.getSymbolicName() != null; + // uninstall previous versions + bundles: for (Bundle b : bundleContext.getBundles()) { + if (b.getSymbolicName() == null) + continue bundles; + if (bundle.getSymbolicName().equals(b.getSymbolicName())) { + Version bundleV = bundle.getVersion(); + Version bV = b.getVersion(); + if (bV == null) + continue bundles; + if (bundleV.getMajor() == bV.getMajor() && bundleV.getMinor() == bV.getMinor()) { + if (bundleV.getMicro() > bV.getMicro()) { + // uninstall older bundles + b.uninstall(); + OsgiBootUtils.debug("Uninstalled " + b); + } else if (bundleV.getMicro() < bV.getMicro()) { + // uninstall just installed bundle if newer + bundle.uninstall(); + OsgiBootUtils.debug("Uninstalled " + bundle); + break bundles; + } else { + // uninstall any other with same major/minor + if (!bundleV.getQualifier().equals(bV.getQualifier())) { + b.uninstall(); + OsgiBootUtils.debug("Uninstalled " + b); + } + } + } + } + } } } catch (BundleException e) { + final String ALREADY_INSTALLED = "is already installed"; String message = e.getMessage(); if ((message.contains("Bundle \"" + SYMBOLIC_NAME_OSGI_BOOT + "\"") || message.contains("Bundle \"" + SYMBOLIC_NAME_EQUINOX + "\"")) - && message.contains("is already installed")) { + && message.contains(ALREADY_INSTALLED)) { // silent, in order to avoid warnings: we know that both // have already been installed... } else { - OsgiBootUtils.warn("Could not install bundle from " + url + ": " + message); + if (message.contains(ALREADY_INSTALLED)) { + if (OsgiBootUtils.isDebug()) + OsgiBootUtils.warn("Duplicate install from " + url + ": " + message); + } else + OsgiBootUtils.warn("Could not install bundle from " + url + ": " + message); } - if (debug) + if (OsgiBootUtils.debug && !message.contains(ALREADY_INSTALLED)) e.printStackTrace(); } } @@ -229,15 +263,19 @@ public class OsgiBoot implements OsgiBootConstants { * START */ public void startBundles() { + startBundles(System.getProperties()); + } + + public void startBundles(Properties properties) { FrameworkStartLevel frameworkStartLevel = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class); // 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")); + Integer.parseInt(getProperty(PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL, "4"))); + Integer activeStartLevel = new Integer(getProperty(PROP_OSGI_STARTLEVEL, "6")); SortedMap> startLevels = new TreeMap>(); - computeStartLevels(startLevels, System.getProperties(), defaultStartLevel); + computeStartLevels(startLevels, properties, defaultStartLevel); // inverts the map for the time being, TODO optimise Map bundleStartLevels = new HashMap<>(); for (Integer level : startLevels.keySet()) { @@ -268,20 +306,9 @@ public class OsgiBoot implements OsgiBootConstants { int startLevel = frameworkStartLevel.getStartLevel(); OsgiBootUtils.debug("Framework start level: " + startLevel + " (initial: " + initialStartLevel + ")"); }); - - // Iterator levels = startLevels.keySet().iterator(); - // while (levels.hasNext()) { - // Integer level = (Integer) levels.next(); - // boolean allStarted = startBundles(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> startLevels, Properties properties, + private static void computeStartLevels(SortedMap> startLevels, Properties properties, Integer defaultStartLevel) { // default (and previously, only behaviour) @@ -328,150 +355,142 @@ public class OsgiBoot implements OsgiBootConstants { } } - // /** - // * Start the provided list of bundles - // * - // * @return whether all bundles are now in active state - // */ - // private boolean startBundles(List bundlesToStart) { - // if (bundlesToStart.size() == 0) - // return true; - // - // // used to monitor ACTIVE states - // List startedBundles = new ArrayList(); - // // used to log the bundles not found - // List notFoundBundles = new ArrayList(bundlesToStart); - // - // Bundle[] bundles = bundleContext.getBundles(); - // long startBegin = System.currentTimeMillis(); - // for (int i = 0; i < bundles.length; i++) { - // Bundle bundle = bundles[i]; - // String symbolicName = bundle.getSymbolicName(); - // if (bundlesToStart.contains(symbolicName)) - // try { - // try { - // bundle.start(); - // if (debug) - // debug("Bundle " + symbolicName + " started"); - // } catch (Exception e) { - // OsgiBootUtils.warn("Start of bundle " + symbolicName + " failed because - // of " + e - // + ", maybe bundle is not yet resolved," + " waiting and trying again."); - // waitForBundleResolvedOrActive(startBegin, bundle); - // bundle.start(); - // startedBundles.add(bundle); - // } - // notFoundBundles.remove(symbolicName); - // } catch (Exception e) { - // OsgiBootUtils.warn("Bundle " + symbolicName + " cannot be started: " + - // e.getMessage()); - // if (debug) - // e.printStackTrace(); - // // was found even if start failed - // notFoundBundles.remove(symbolicName); - // } - // } - // - // for (int i = 0; i < notFoundBundles.size(); i++) - // 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 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; - // } + /** + * Start the provided list of bundles + * + * @return whether all bundles are now in active state + * @deprecated + */ + @Deprecated + public boolean startBundles(List bundlesToStart) { + if (bundlesToStart.size() == 0) + return true; - // /** Waits for a bundle to become active or resolved */ - // private void waitForBundleResolvedOrActive(long startBegin, Bundle - // bundle) throws Exception { - // int originalState = bundle.getState(); - // if ((originalState == Bundle.RESOLVED) || (originalState == - // Bundle.ACTIVE)) - // return; - // - // String originalStateStr = OsgiBootUtils.stateAsString(originalState); - // - // int currentState = bundle.getState(); - // while (!(currentState == Bundle.RESOLVED || currentState == - // Bundle.ACTIVE)) { - // long now = System.currentTimeMillis(); - // if ((now - startBegin) > defaultTimeout * 10) - // throw new Exception("Bundle " + bundle.getSymbolicName() + " was not - // RESOLVED or ACTIVE after " - // + (now - startBegin) + "ms (originalState=" + originalStateStr + ", - // currentState=" - // + OsgiBootUtils.stateAsString(currentState) + ")"); - // - // try { - // Thread.sleep(100l); - // } catch (InterruptedException e) { - // // silent - // } - // currentState = bundle.getState(); - // } - // } + // used to monitor ACTIVE states + List startedBundles = new ArrayList(); + // used to log the bundles not found + List notFoundBundles = new ArrayList(bundlesToStart); + + Bundle[] bundles = bundleContext.getBundles(); + long startBegin = System.currentTimeMillis(); + for (int i = 0; i < bundles.length; i++) { + Bundle bundle = bundles[i]; + String symbolicName = bundle.getSymbolicName(); + if (bundlesToStart.contains(symbolicName)) + try { + try { + bundle.start(); + if (OsgiBootUtils.debug) + debug("Bundle " + symbolicName + " started"); + } catch (Exception e) { + OsgiBootUtils.warn("Start of bundle " + symbolicName + " failed because of " + e + + ", maybe bundle is not yet resolved," + " waiting and trying again."); + waitForBundleResolvedOrActive(startBegin, bundle); + bundle.start(); + startedBundles.add(bundle); + } + notFoundBundles.remove(symbolicName); + } catch (Exception e) { + OsgiBootUtils.warn("Bundle " + symbolicName + " cannot be started: " + e.getMessage()); + if (OsgiBootUtils.debug) + e.printStackTrace(); + // was found even if start failed + notFoundBundles.remove(symbolicName); + } + } + + for (int i = 0; i < notFoundBundles.size(); i++) + 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 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; + } + + /** Waits for a bundle to become active or resolved */ + @Deprecated + private void waitForBundleResolvedOrActive(long startBegin, Bundle bundle) throws Exception { + int originalState = bundle.getState(); + if ((originalState == Bundle.RESOLVED) || (originalState == Bundle.ACTIVE)) + return; + + String originalStateStr = OsgiBootUtils.stateAsString(originalState); + + int currentState = bundle.getState(); + while (!(currentState == Bundle.RESOLVED || currentState == Bundle.ACTIVE)) { + long now = System.currentTimeMillis(); + if ((now - startBegin) > defaultTimeout * 10) + throw new Exception("Bundle " + bundle.getSymbolicName() + " was not RESOLVED or ACTIVE after " + + (now - startBegin) + "ms (originalState=" + originalStateStr + ", currentState=" + + OsgiBootUtils.stateAsString(currentState) + ")"); + + try { + Thread.sleep(100l); + } catch (InterruptedException e) { + // silent + } + currentState = bundle.getState(); + } + } /* * BUNDLE PATTERNS INSTALLATION */ /** - * Computes a list of URLs based on Ant-like include/exclude patterns - * defined by ${argeo.osgi.bundles} with the following format:
+ * Computes a list of URLs based on Ant-like include/exclude patterns defined by + * ${argeo.osgi.bundles} with the following format:
* /base/directory;in=*.jar;in=**;ex=org.eclipse.osgi_*;jar
* WARNING: /base/directory;in=*.jar,\ at the end of a file, - * without a new line causes a '.' to be appended with unexpected side - * effects. + * without a new line causes a '.' to be appended with unexpected side effects. */ public List getBundlesUrls() { - String bundlePatterns = OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BUNDLES); + String bundlePatterns = getProperty(PROP_ARGEO_OSGI_BUNDLES); return getBundlesUrls(bundlePatterns); } /** - * Compute alist of URLs to install based on the provided patterns, with + * Compute a list 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); + String baseUrl = getProperty(PROP_ARGEO_OSGI_BASE_URL, DEFAULT_BASE_URL); return getBundlesUrls(baseUrl, bundlePatterns); } /** Implements the path matching logic */ - List getBundlesUrls(String baseUrl, String bundlePatterns) { + public List getBundlesUrls(String baseUrl, String bundlePatterns) { List urls = new ArrayList(); if (bundlePatterns == null) return urls; bundlePatterns = SystemPropertyUtils.resolvePlaceholders(bundlePatterns); - if (debug) - debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns + " (excludeSvn=" + excludeSvn + ")"); + if (OsgiBootUtils.debug) + debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns); StringTokenizer st = new StringTokenizer(bundlePatterns, ","); List bundlesSets = new ArrayList(); @@ -519,22 +538,55 @@ public class OsgiBoot implements OsgiBootConstants { * DISTRIBUTION JAR INSTALLATION */ public List getDistributionUrls() { + String distributionUrl = getProperty(PROP_ARGEO_OSGI_DISTRIBUTION_URL); + String baseUrl = getProperty(PROP_ARGEO_OSGI_BASE_URL); + return getDistributionUrls(distributionUrl, baseUrl); + } + + public List getDistributionUrls(String distributionUrl, String baseUrl) { 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 { + if (distributionUrl.startsWith("http") || distributionUrl.startsWith("file")) { distributionBundle = new DistributionBundle(distributionUrl); if (baseUrl != null) distributionBundle.setBaseUrl(baseUrl); + } else { + // relative url + if (baseUrl == null) { + baseUrl = localCache; + } + + if (distributionUrl.contains(":")) { + // TODO make it safer + String[] parts = distributionUrl.trim().split(":"); + String[] categoryParts = parts[0].split("\\."); + String artifactId = parts[1]; + String version = parts[2]; + StringBuilder sb = new StringBuilder(); + for (String categoryPart : categoryParts) { + sb.append(categoryPart).append('/'); + } + sb.append(artifactId).append('/'); + sb.append(version).append('/'); + sb.append(artifactId).append('-').append(version).append(".jar"); + distributionUrl = sb.toString(); + } + distributionBundle = new DistributionBundle(baseUrl, distributionUrl, localCache); } + // if (baseUrl != null && !(distributionUrl.startsWith("http") || + // distributionUrl.startsWith("file"))) { + // // relative url + // distributionBundle = new DistributionBundle(baseUrl, distributionUrl, + // localCache); + // } else { + // distributionBundle = new DistributionBundle(distributionUrl); + // if (baseUrl != null) + // distributionBundle.setBaseUrl(baseUrl); + // } distributionBundle.processUrl(); return distributionBundle.listUrls(); } @@ -550,7 +602,7 @@ public class OsgiBoot implements OsgiBootConstants { File[] files = baseDir.listFiles(); if (files == null) { - if (debug) + if (OsgiBootUtils.debug) OsgiBootUtils.warn("Base dir " + baseDir + " has no children, exists=" + baseDir.exists() + ", isDirectory=" + baseDir.isDirectory()); return; @@ -582,13 +634,13 @@ public class OsgiBoot implements OsgiBootConstants { // recurse only if start matches match(matcher, matched, base, newCurrentPath, pattern); } else { - if (debug) + if (OsgiBootUtils.debug) debug(newCurrentPath + " does not start match with " + pattern); } } else { boolean nonDirectoryOk = matcher.match(pattern, newCurrentPath); - if (debug) + if (OsgiBootUtils.debug) debug(currentPath + " " + (ok ? "" : " not ") + " matched with " + pattern); if (nonDirectoryOk) matched.add(relativeToFullPath(base, newCurrentPath)); @@ -642,13 +694,27 @@ public class OsgiBoot implements OsgiBootConstants { return (basePath + '/' + relativePath).replace('/', File.separatorChar); } - private String removeFilePrefix(String url) { - if (url.startsWith("file:")) - return url.substring("file:".length()); - else if (url.startsWith("reference:file:")) - return url.substring("reference:file:".length()); + private void refreshFramework() { + Bundle systemBundle = bundleContext.getBundle(0); + FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class); + frameworkWiring.refreshBundles(null); + } + + /** + * Gets a property value + * + * @return null when defaultValue is "" + */ + public String getProperty(String name, String defaultValue) { + String value = bundleContext.getProperty(name); + if (value == null) + return defaultValue; // may be null else - return url; + return value; + } + + public String getProperty(String name) { + return getProperty(name, null); } /* @@ -656,94 +722,35 @@ public class OsgiBoot implements OsgiBootConstants { */ public boolean getDebug() { - return debug; + return OsgiBootUtils.debug; } - public void setDebug(boolean debug) { - this.debug = debug; - } + // public void setDebug(boolean debug) { + // this.debug = debug; + // } public BundleContext getBundleContext() { return bundleContext; } + public String getLocalCache() { + return localCache; + } + // public void setDefaultTimeout(long defaultTimeout) { // this.defaultTimeout = defaultTimeout; // } - public boolean isExcludeSvn() { - return excludeSvn; - } - - public void setExcludeSvn(boolean excludeSvn) { - this.excludeSvn = excludeSvn; - } + // public boolean isExcludeSvn() { + // return excludeSvn; + // } + // + // public void setExcludeSvn(boolean excludeSvn) { + // this.excludeSvn = excludeSvn; + // } /* * INTERNAL CLASSES */ - /** Intermediary structure used by path matching */ - protected class BundlesSet { - private String baseUrl = "reference:file";// not used yet - private final String dir; - private List includes = new ArrayList(); - private List excludes = new ArrayList(); - - public BundlesSet(String def) { - StringTokenizer st = new StringTokenizer(def, ";"); - - if (!st.hasMoreTokens()) - throw new RuntimeException("Base dir not defined."); - try { - String dirPath = st.nextToken(); - - if (dirPath.startsWith("file:")) - dirPath = dirPath.substring("file:".length()); - - dir = new File(dirPath.replace('/', File.separatorChar)).getCanonicalPath(); - if (debug) - debug("Base dir: " + dir); - } catch (IOException e) { - throw new RuntimeException("Cannot convert to absolute path", e); - } - - while (st.hasMoreTokens()) { - String tk = st.nextToken(); - StringTokenizer stEq = new StringTokenizer(tk, "="); - String type = stEq.nextToken(); - String pattern = stEq.nextToken(); - if ("in".equals(type) || "include".equals(type)) { - includes.add(pattern); - } else if ("ex".equals(type) || "exclude".equals(type)) { - excludes.add(pattern); - } else if ("baseUrl".equals(type)) { - baseUrl = pattern; - } else { - System.err.println("Unkown bundles pattern type " + type); - } - } - - if (excludeSvn && !excludes.contains(EXCLUDES_SVN_PATTERN)) { - excludes.add(EXCLUDES_SVN_PATTERN); - } - } - - public String getDir() { - return dir; - } - - public List getIncludes() { - return includes; - } - - public List getExcludes() { - return excludes; - } - - public String getBaseUrl() { - return baseUrl; - } - - } }