+ protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+ String moduleName, String moduleVersion) {
+ OsgiBundle osgiBundle = new OsgiBundle(moduleName, moduleVersion);
+ return getExecutionFlowDescriptorConverter(osgiBundle);
+ }
+
+ protected synchronized ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+ OsgiBundle osgiBundle) {
+ if (executionFlowDescriptorConverters.containsKey(osgiBundle))
+ return executionFlowDescriptorConverters.get(osgiBundle);
+ else
+ return defaultDescriptorConverter;
+ }
+
+ public ModuleDescriptor getModuleDescriptor(String moduleName,
+ String version) {
+ return getExecutionModuleDescriptor(moduleName, version);
+ }
+
+ public List<ModuleDescriptor> listModules() {
+ Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+ List<ModuleDescriptor> lst = new ArrayList<ModuleDescriptor>();
+ for (Bundle bundle : bundles) {
+ ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+ setMetadataFromBundle(moduleDescriptor, bundle);
+ lst.add(moduleDescriptor);
+ }
+ return lst;
+ }
+
+ public void start(NameVersion nameVersion) {
+ try {
+ Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+ nameVersion));
+ if (bundle == null)
+ throw new SlcException("Counld not find bundle for "
+ + nameVersion);
+
+ bundlesManager.startSynchronous(bundle);
+ if (isSpringInstrumented(bundle)) {
+ // Wait for Spring application context to be ready
+ String filter = "(Bundle-SymbolicName="
+ + bundle.getSymbolicName() + ")";
+ try {
+ bundlesManager.getServiceRefSynchronous(
+ ApplicationContext.class.getName(), filter);
+ } catch (Exception e) {
+ // stop if application context not found
+ bundle.stop();
+ throw e;
+ }
+ }
+ } catch (Exception e) {
+ throw new SlcException("Cannot start " + nameVersion, e);
+ }
+ }
+
+ /** Do it calmly in order to avoid NPE */
+ private Boolean isSpringInstrumented(Bundle bundle) {
+ Dictionary<?, ?> headers = bundle.getHeaders();
+ if (headers != null && headers.get("Spring-Context") != null)
+ return true;
+ Enumeration<?> springEntryPaths = bundle
+ .getEntryPaths("/META-INF/spring");
+ if (springEntryPaths != null && springEntryPaths.hasMoreElements())
+ return true;
+ return false;
+ }
+
+ public void stop(NameVersion nameVersion) {
+ try {
+ Bundle bundle = bundlesManager.findRelatedBundle(new OsgiBundle(
+ nameVersion));
+ bundlesManager.stopSynchronous(bundle);
+ } catch (BundleException e) {
+ throw new SlcException("Cannot stop " + nameVersion, e);
+ }
+ }
+
+ protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
+ Bundle bdl = bundle;
+ if (bdl == null) {
+ if (md.getName() == null || md.getVersion() == null)
+ throw new SlcException("Name and version not available.");
+
+ Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+ for (Bundle b : bundles) {
+ if (b.getSymbolicName().equals(md.getName())
+ && md.getVersion().equals(
+ getHeaderSafe(b, Constants.BUNDLE_VERSION))) {
+ bdl = b;
+ break;
+ }
+ }
+
+ }
+
+ if (bdl == null)
+ throw new SlcException("Cannot find bundle.");
+
+ md.setName(bdl.getSymbolicName());
+ md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION));
+ md.setTitle(getHeaderSafe(bdl, Constants.BUNDLE_NAME));
+ md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION));
+
+ // copy manifets header to meta data
+ Dictionary<?, ?> headers = bundle.getHeaders();
+ Enumeration<?> keys = headers.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ Object value = headers.get(key);
+ if (value != null)
+ md.getMetadata().put(key.toString(), value.toString());
+ }
+
+ // check if started
+ if (bundle.getState() == Bundle.ACTIVE
+ || bundle.getState() == Bundle.STARTING)
+ md.setStarted(true);
+ else
+ md.setStarted(false);
+ }
+
+ private String getHeaderSafe(Bundle bundle, Object key) {
+ Object obj = bundle.getHeaders().get(key);
+ if (obj == null)
+ return null;
+ else
+ return obj.toString();
+ }
+
+ /*
+ * REGISTRATION
+ */
+
+ /** Registers an execution context. */
+ public synchronized void register(ExecutionContext executionContext,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
+ osgiBundle.setTitle(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
+ osgiBundle.setDescription(getHeaderSafe(bundle,
+ Constants.BUNDLE_DESCRIPTION));
+ executionContexts.put(osgiBundle, executionContext);
+ if (log.isTraceEnabled())
+ log.trace("Registered execution context from " + osgiBundle);
+ // Notify
+ ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+ md.setStarted(true);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleAdded(md);
+ }
+
+ /** Unregisters an execution context. */
+ public synchronized void unregister(ExecutionContext executionContext,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (executionContexts.containsKey(osgiBundle)) {
+ executionContexts.remove(osgiBundle);
+ if (log.isTraceEnabled())
+ log.trace("Removed execution context from " + osgiBundle);
+ // Notify
+ ModuleDescriptor md = osgiBundle.getModuleDescriptor();
+ md.setStarted(false);
+ for (ExecutionModulesListener listener : executionModulesListeners)
+ listener.executionModuleRemoved(md);
+ }
+ }
+
+ /** Registers an execution flow. */
+ public synchronized void register(ExecutionFlow executionFlow,
+ Map<String, String> properties) {
+ OsgiBundle osgiBundle = asOsgiBundle(properties);
+ if (!executionFlows.containsKey(osgiBundle)) {
+ executionFlows.put(osgiBundle, new HashSet<ExecutionFlow>());
+ }
+ executionFlows.get(osgiBundle).add(executionFlow);