1 package org
.argeo
.slc
.detached
.admin
;
3 import org
.osgi
.framework
.Bundle
;
4 import org
.osgi
.framework
.BundleContext
;
5 import org
.osgi
.framework
.BundleException
;
6 import org
.osgi
.framework
.FrameworkEvent
;
7 import org
.osgi
.framework
.FrameworkListener
;
8 import org
.osgi
.framework
.InvalidSyntaxException
;
9 import org
.osgi
.framework
.ServiceReference
;
10 import org
.osgi
.service
.packageadmin
.PackageAdmin
;
13 * Wraps low-level access to a {@link BundleContext}. Hacked from the related
14 * class in org.argeo.slc.support.osgi.
16 class MinimalBundlesManager
implements FrameworkListener
{
17 private final BundleContext bundleContext
;
19 private long defaultTimeout
= 10000l;
20 private final Object refreshedPackageSem
= new Object();
22 private boolean debug
= true;
24 public MinimalBundlesManager(BundleContext bundleContext
) {
25 this.bundleContext
= bundleContext
;
26 bundleContext
.addFrameworkListener(this);
29 protected void finalize() throws Throwable
{
30 bundleContext
.removeFrameworkListener(this);
34 * Stop the module, update it, refresh it and restart it. All synchronously.
36 public void upgradeSynchronous(Bundle bundle
) {
38 stopSynchronous(bundle
);
39 updateSynchronous(bundle
);
40 // Refresh in case there are fragments
41 refreshSynchronous(bundle
);
42 startSynchronous(bundle
);
44 String filter
= "(Bundle-SymbolicName=" + bundle
.getSymbolicName()
46 // Wait for application context to be ready
47 // TODO: use service tracker
48 getServiceRefSynchronous(
49 "org.springframework.context.ApplicationContext", filter
);
52 debug("Bundle " + bundle
.getSymbolicName()
53 + " ready to be used at latest version.");
54 } catch (Exception e
) {
55 throw new RuntimeException("Cannot update bundle "
56 + bundle
.getSymbolicName(), e
);
60 /** Updates bundle synchronously. */
61 protected void updateSynchronous(Bundle bundle
) throws BundleException
{
62 // int originalState = bundle.getState();
64 boolean waiting
= true;
66 long begin
= System
.currentTimeMillis();
68 int state
= bundle
.getState();
69 if (state
== Bundle
.INSTALLED
|| state
== Bundle
.ACTIVE
70 || state
== Bundle
.RESOLVED
)
74 if (System
.currentTimeMillis() - begin
> defaultTimeout
)
75 throw new RuntimeException("Update of bundle "
76 + bundle
.getSymbolicName()
77 + " timed out. Bundle state = " + bundle
.getState());
81 debug("Bundle " + bundle
.getSymbolicName() + " updated.");
84 /** Starts bundle synchronously. Does nothing if already started. */
85 protected void startSynchronous(Bundle bundle
) throws BundleException
{
86 int originalState
= bundle
.getState();
87 if (originalState
== Bundle
.ACTIVE
)
91 boolean waiting
= true;
93 long begin
= System
.currentTimeMillis();
95 if (bundle
.getState() == Bundle
.ACTIVE
)
99 if (System
.currentTimeMillis() - begin
> defaultTimeout
)
100 throw new RuntimeException("Start of bundle "
101 + bundle
.getSymbolicName()
102 + " timed out. Bundle state = " + bundle
.getState());
106 debug("Bundle " + bundle
.getSymbolicName() + " started.");
109 /** Stops bundle synchronously. Does nothing if already started. */
110 protected void stopSynchronous(Bundle bundle
) throws BundleException
{
111 int originalState
= bundle
.getState();
112 if (originalState
!= Bundle
.ACTIVE
)
116 boolean waiting
= true;
118 long begin
= System
.currentTimeMillis();
120 if (bundle
.getState() != Bundle
.ACTIVE
121 && bundle
.getState() != Bundle
.STOPPING
)
125 if (System
.currentTimeMillis() - begin
> defaultTimeout
)
126 throw new RuntimeException("Stop of bundle "
127 + bundle
.getSymbolicName()
128 + " timed out. Bundle state = " + bundle
.getState());
132 debug("Bundle " + bundle
.getSymbolicName() + " stopped.");
135 /** Refresh bundle synchronously. Does nothing if already started. */
136 protected void refreshSynchronous(Bundle bundle
) throws BundleException
{
137 ServiceReference packageAdminRef
= bundleContext
138 .getServiceReference(PackageAdmin
.class.getName());
139 PackageAdmin packageAdmin
= (PackageAdmin
) bundleContext
140 .getService(packageAdminRef
);
141 Bundle
[] bundles
= { bundle
};
142 packageAdmin
.refreshPackages(bundles
);
144 synchronized (refreshedPackageSem
) {
146 refreshedPackageSem
.wait(defaultTimeout
);
147 } catch (InterruptedException e
) {
153 debug("Bundle " + bundle
.getSymbolicName() + " refreshed.");
156 public void frameworkEvent(FrameworkEvent event
) {
157 if (event
.getType() == FrameworkEvent
.PACKAGES_REFRESHED
) {
158 synchronized (refreshedPackageSem
) {
159 refreshedPackageSem
.notifyAll();
164 public ServiceReference
[] getServiceRefSynchronous(String clss
,
165 String filter
) throws InvalidSyntaxException
{
167 debug("Filter: '" + filter
+ "'");
168 ServiceReference
[] sfs
= null;
169 boolean waiting
= true;
170 long begin
= System
.currentTimeMillis();
172 sfs
= bundleContext
.getServiceReferences(clss
, filter
);
178 if (System
.currentTimeMillis() - begin
> defaultTimeout
)
179 throw new RuntimeException("Search of services " + clss
180 + " with filter " + filter
+ " timed out.");
187 * protected void sleep(long ms) { try { Thread.sleep(ms); } catch
188 * (InterruptedException e) { // silent } }
190 * public ServiceTracker newTracker(Class<?> clss) { ServiceTracker st = new
191 * ServiceTracker(bundleContext, clss.getName(), null); st.open(); return
194 * @SuppressWarnings(value = { "unchecked" }) public <T> T
195 * getSingleService(Class<T> clss, String filter) {
196 * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
197 * ServiceReference[] sfs; try { sfs =
198 * bundleContext.getServiceReferences(clss.getName(), filter); } catch
199 * (InvalidSyntaxException e) { throw new
200 * SlcException("Cannot retrieve service reference for " + filter, e); }
202 * if (sfs == null || sfs.length == 0) return null; else if (sfs.length > 1)
203 * throw new SlcException("More than one execution flow found for " +
204 * filter); return (T) bundleContext.getService(sfs[0]); }
206 * public <T> T getSingleServiceStrict(Class<T> clss, String filter) { T
207 * service = getSingleService(clss, filter); if (service == null) throw new
208 * SlcException("No execution flow found for " + filter); else return
211 * public Bundle findRelatedBundle(OsgiBundle osgiBundle) { Bundle bundle =
212 * null; if (osgiBundle.getInternalBundleId() != null) { bundle =
213 * bundleContext.getBundle(osgiBundle.getInternalBundleId()); Assert.isTrue(
214 * osgiBundle.getName().equals(bundle.getSymbolicName()),
215 * "symbolic name consistent");
216 * Assert.isTrue(osgiBundle.getVersion().equals(
217 * bundle.getHeaders().get(Constants.BUNDLE_VERSION)),
218 * "version consistent"); } else { for (Bundle b :
219 * bundleContext.getBundles()) { if
220 * (b.getSymbolicName().equals(osgiBundle.getName())) { if
221 * (b.getHeaders().get(Constants.BUNDLE_VERSION).equals(
222 * osgiBundle.getVersion())) { bundle = b;
223 * osgiBundle.setInternalBundleId(b.getBundleId()); } } } } return bundle; }
225 * public OsgiBundle findFromPattern(String pattern) { OsgiBundle osgiBundle
226 * = null; for (Bundle b : bundleContext.getBundles()) { if
227 * (b.getSymbolicName().contains(pattern)) { osgiBundle = new OsgiBundle(b);
228 * break; } } return osgiBundle; }
230 * public OsgiBundle getBundle(Long bundleId) { Bundle bundle =
231 * bundleContext.getBundle(bundleId); return new OsgiBundle(bundle); }
233 * public void setBundleContext(BundleContext bundleContext) {
234 * this.bundleContext = bundleContext; }
236 * public void afterPropertiesSet() throws Exception {
237 * bundleContext.addFrameworkListener(this); }
239 * public void setDefaultTimeout(Long defaultTimeout) { this.defaultTimeout
240 * = defaultTimeout; }
242 * BundleContext getBundleContext() { return bundleContext; }
245 protected void debug(Object obj
) {
247 System
.out
.println("#OSGiMANAGER DEBUG# " + obj
);
250 protected void sleep(long ms
) {
253 } catch (InterruptedException e
) {