X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.support.equinox%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fosgi%2FBundlesManager.java;h=445fdf98cdcd3eac6bc7ef7113b057eca22d1113;hb=8695884efeb66c4bab1b268bc8a82099eaa61a57;hp=2cd2b37c617bfe65dfb20f12a1b1f096ab5daf71;hpb=370e17b89b62de8a5af827a209a9aaf07e2f0842;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java index 2cd2b37c6..445fdf98c 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java @@ -1,58 +1,191 @@ package org.argeo.slc.osgi; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkEvent; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.PackageAdmin; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; import org.springframework.osgi.context.BundleContextAware; -public class BundlesManager implements BundleContextAware { +/** Wraps access to a {@link BundleContext} */ +public class BundlesManager implements BundleContextAware, FrameworkListener, + InitializingBean { private final static Log log = LogFactory.getLog(BundlesManager.class); private BundleContext bundleContext; - private List urlsToInstall; - - public void init() { - // Install - if (urlsToInstall != null) { - Map installedBundles = new HashMap(); - for (Bundle bundle : bundleContext.getBundles()) - installedBundles.put(bundle.getLocation(), bundle); - - for (String url : urlsToInstall) - try { - - if (installedBundles.containsKey(url)) { - Bundle bundle = installedBundles.get(url); - // bundle.update(); - log.debug("Bundle " + bundle.getSymbolicName() - + " already installed from " + url); - } else { - Bundle bundle = bundleContext.installBundle(url); - log.debug("Installed bundle " - + bundle.getSymbolicName() + " from " + url); - } - } catch (BundleException e) { - log.warn("Could not install bundle from " + url + ": " - + e.getMessage()); - } + private Long defaultTimeout = 10000l; + private final Object refreshedPackageSem = new Object(); + + /** Updates bundle synchronously. */ + public void updateSynchronous(Bundle bundle) throws BundleException { + // int originalState = bundle.getState(); + bundle.update(); + boolean waiting = true; + + long begin = System.currentTimeMillis(); + do { + int state = bundle.getState(); + if (state == Bundle.INSTALLED || state == Bundle.ACTIVE + || state == Bundle.RESOLVED) + waiting = false; + + sleep(100); + if (System.currentTimeMillis() - begin > defaultTimeout) + throw new SlcException("Update of bundle " + + bundle.getSymbolicName() + + " timed out. Bundle state = " + bundle.getState()); + } while (waiting); + + if (log.isTraceEnabled()) + log.debug("Bundle " + bundle.getSymbolicName() + " updated."); + } + + /** Starts bundle synchronously. Does nothing if already started. */ + public void startSynchronous(Bundle bundle) throws BundleException { + int originalState = bundle.getState(); + if (originalState == Bundle.ACTIVE) + return; + + bundle.start(); + boolean waiting = true; + + long begin = System.currentTimeMillis(); + do { + if (bundle.getState() == Bundle.ACTIVE) + waiting = false; + + sleep(100); + if (System.currentTimeMillis() - begin > defaultTimeout) + throw new SlcException("Start of bundle " + + bundle.getSymbolicName() + + " timed out. Bundle state = " + bundle.getState()); + } while (waiting); + + if (log.isTraceEnabled()) + log.debug("Bundle " + bundle.getSymbolicName() + " started."); + } + + /** Stops bundle synchronously. Does nothing if already started. */ + public void stopSynchronous(Bundle bundle) throws BundleException { + int originalState = bundle.getState(); + if (originalState != Bundle.ACTIVE) + return; + + bundle.stop(); + boolean waiting = true; + + long begin = System.currentTimeMillis(); + do { + if (bundle.getState() != Bundle.ACTIVE + && bundle.getState() != Bundle.STOPPING) + waiting = false; + + sleep(100); + if (System.currentTimeMillis() - begin > defaultTimeout) + throw new SlcException("Stop of bundle " + + bundle.getSymbolicName() + + " timed out. Bundle state = " + bundle.getState()); + } while (waiting); + + if (log.isTraceEnabled()) + log.debug("Bundle " + bundle.getSymbolicName() + " stopped."); + } + + /** Refresh bundle synchronously. Does nothing if already started. */ + public void refreshSynchronous(Bundle bundle) throws BundleException { + ServiceReference packageAdminRef = bundleContext + .getServiceReference(PackageAdmin.class.getName()); + PackageAdmin packageAdmin = (PackageAdmin) bundleContext + .getService(packageAdminRef); + Bundle[] bundles = { bundle }; + packageAdmin.refreshPackages(bundles); + + synchronized (refreshedPackageSem) { + try { + refreshedPackageSem.wait(defaultTimeout); + } catch (InterruptedException e) { + // silent + } + } + + if (log.isTraceEnabled()) + log.debug("Bundle " + bundle.getSymbolicName() + " refreshed."); + } + + public void frameworkEvent(FrameworkEvent event) { + if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { + synchronized (refreshedPackageSem) { + refreshedPackageSem.notifyAll(); + } + } + } + + public List listPublishedApplicationContexts( + String filter) { + try { + List lst = new ArrayList(); + ServiceReference[] sfs = bundleContext.getServiceReferences( + ApplicationContext.class.getName(), filter); + for (int i = 0; i < sfs.length; i++) { + ApplicationContext applicationContext = (ApplicationContext) bundleContext + .getService(sfs[i]); + lst.add(applicationContext); + } + return lst; + } catch (InvalidSyntaxException e) { + throw new SlcException( + "Cannot list published application contexts", e); } + } + + public ServiceReference[] getServiceRefSynchronous(String clss, + String filter) throws InvalidSyntaxException { + if (log.isTraceEnabled()) + log.debug("Filter: '" + filter + "'"); + ServiceReference[] sfs = null; + boolean waiting = true; + long begin = System.currentTimeMillis(); + do { + sfs = bundleContext.getServiceReferences(clss, filter); + + if (sfs != null) + waiting = false; + sleep(100); + if (System.currentTimeMillis() - begin > defaultTimeout) + throw new SlcException("Search of services " + clss + + " with filter " + filter + " timed out."); + } while (waiting); + + return sfs; + } + + protected void sleep(long ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + // silent + } } public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } - public void setUrlsToInstall(List urlsToInstall) { - this.urlsToInstall = urlsToInstall; + public void afterPropertiesSet() throws Exception { + bundleContext.addFrameworkListener(this); } }