diff options
Diffstat (limited to 'sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node')
3 files changed, 414 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeActivator.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeActivator.java new file mode 100644 index 0000000000..36feb6526a --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeActivator.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.node.osgi.impl; + +import static org.apache.tuscany.sca.node.osgi.impl.NodeManager.isSCABundle; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.RemoteServiceAdminImpl; +import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.TopologyManagerImpl; +import org.apache.tuscany.sca.osgi.service.discovery.impl.DiscoveryActivator; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.SynchronousBundleListener; + +/** + * Bundle activator to receive the BundleContext + */ +public class NodeActivator implements BundleActivator, SynchronousBundleListener { + private final static Logger logger = Logger.getLogger(NodeActivator.class.getName()); + private static BundleContext bundleContext; + private boolean inited; + private NodeManager manager; + + private DiscoveryActivator discoveryActivator = new DiscoveryActivator(); + private RemoteServiceAdminImpl remoteAdmin; + private TopologyManagerImpl controller; + + private void init() { + synchronized (this) { + if (inited) { + return; + } + manager = new NodeManager(bundleContext); + manager.start(); + bundleContext.addBundleListener(manager); + inited = true; + } + } + + public void start(BundleContext context) throws Exception { + try { + bundleContext = context; + + // FIXME: We should try to avoid aggressive initialization + init(); + + remoteAdmin = new RemoteServiceAdminImpl(context); + remoteAdmin.start(); + + discoveryActivator.start(context); + + controller = new TopologyManagerImpl(context); + controller.start(); + + boolean found = false; + for (Bundle b : context.getBundles()) { + if (isSCABundle(b)) { + found = true; + break; + } + } + + if (found) { + init(); + } else { + context.addBundleListener(this); + } + } catch (Exception e) { + logger.log(Level.SEVERE, e.getMessage(), e); + throw e; + } + } + + public void stop(BundleContext context) throws Exception { + if (inited) { + context.removeBundleListener(this); + controller.stop(); + controller = null; + + discoveryActivator.stop(context); + discoveryActivator = null; + + remoteAdmin.stop(); + remoteAdmin = null; + + manager.stop(); + bundleContext.removeBundleListener(manager); + manager = null; + bundleContext = null; + inited = false; + } + } + + public static BundleContext getBundleContext() { + return bundleContext; + } + + public void bundleChanged(BundleEvent event) { + if (event.getType() == BundleEvent.STARTING) { + if (isSCABundle(event.getBundle())) { + bundleContext.removeBundleListener(this); + init(); + } + } + + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeManager.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeManager.java new file mode 100644 index 0000000000..6914e09b8e --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/NodeManager.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.node.osgi.impl; + +import java.net.URL; +import java.util.Dictionary; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.node.Node; +import org.apache.tuscany.sca.node.configuration.NodeConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.SynchronousBundleListener; + +/** + * Managing the mapping between OSGi bundles and SCA implementation.osgi + */ +public class NodeManager implements SynchronousBundleListener, ServiceListener { + private static final Logger logger = Logger.getLogger(NodeManager.class.getName()); + private BundleContext bundleContext; + OSGiNodeFactoryImpl factory; + + public NodeManager(BundleContext bundleContext) { + super(); + this.bundleContext = bundleContext; + this.factory = new OSGiNodeFactoryImpl(this.bundleContext); + } + + public void start() { + for (Bundle b : bundleContext.getBundles()) { + if ((b.getState() & Bundle.ACTIVE) != 0) { + // Process the active bundles + bundleStarted(b); + } + } + } + + public void stop() { + if (factory != null) { + factory.destroy(); + } + } + + public static boolean isSCABundle(Bundle bundle) { + Dictionary<?, ?> headers = bundle.getHeaders(); + // OSGi RFC 119 SCA + if (headers.get("SCA-Composite") != null) { + return true; + } + + URL bundleComposite = bundle.getResource("OSGI-INF/sca/bundle.composite"); + if (bundleComposite != null) { + return true; + } + + /* FIXME: What if there is a META-INF/sca-contribution.xml? There are two cases: + * 1. The file contains deployable elements + * 2. The file doesn't contain deployable elements + */ + + /* + * FIXME: Do we want to use all of the .composite files under OSGI-INF/sca? + */ + + /* + Enumeration<?> entries = bundle.findEntries("OSGI-INF/sca", "bundle.composite", false); + if (entries != null && entries.hasMoreElements()) { + return true; + } + + // OSGi Declarative Services + if (headers.get("Service-Component") != null) { + return true; + } + + // OSGI RFC 124: BluePrint Service + if (headers.get("Bundle-Blueprint") != null) { + return true; + } + + entries = bundle.findEntries("OSGI-INF/blueprint", "*.xml", false); + if (entries != null && entries.hasMoreElements()) { + return true; + } + */ + return false; + } + + private void bundleStarted(Bundle bundle) { + if (!isSCABundle(bundle)) { + return; + } + try { + NodeConfiguration configuration = factory.getConfiguration(bundle, null); + Node node = factory.createNode(configuration); + node.start(); + } catch (Throwable e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + } + + private void bundleStopping(Bundle bundle) { + Node node = factory.getNodes().get(bundle); + if (node == null) { + return; + } + node.stop(); + } + + public void serviceChanged(ServiceEvent event) { + } + + public void bundleChanged(BundleEvent event) { + int type = event.getType(); + if (type == BundleEvent.STOPPING) { + bundleStopping(event.getBundle()); + } else if (type == BundleEvent.STARTED) { + bundleStarted(event.getBundle()); + } + } + +} diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/OSGiNodeFactoryImpl.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/OSGiNodeFactoryImpl.java new file mode 100644 index 0000000000..c79fc04c4d --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/node/osgi/impl/OSGiNodeFactoryImpl.java @@ -0,0 +1,142 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.apache.tuscany.sca.node.osgi.impl; + +import java.io.StringReader; +import java.net.URL; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.logging.Level; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.extensibility.equinox.OSGiExtensionPointRegistry; +import org.apache.tuscany.sca.node.configuration.NodeConfiguration; +import org.apache.tuscany.sca.node.configuration.NodeConfigurationFactory; +import org.apache.tuscany.sca.node.impl.NodeFactoryImpl; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; + +/** + * The OSGi based NodeFactory + * + * @version $Rev$ $Date$ + */ +public class OSGiNodeFactoryImpl extends NodeFactoryImpl { + private ServiceRegistration registration; + private BundleContext bundleContext; + + public OSGiNodeFactoryImpl() { + super(); + Bundle bundle = FrameworkUtil.getBundle(OSGiNodeFactoryImpl.class); + if (bundle != null) { + this.bundleContext = bundle.getBundleContext(); + autoDestroy = false; + setNodeFactory(this); + } else { + throw new IllegalStateException(OSGiNodeFactoryImpl.class + " is not loaded by OSGi"); + } + } + /** + * Constructs a new Node controller + */ + public OSGiNodeFactoryImpl(BundleContext bundleContext) { + super(); + this.bundleContext = bundleContext; + autoDestroy = false; + setNodeFactory(this); + } + + protected NodeConfiguration getConfiguration(Bundle bundle, String compositeContent) { + init(); + + // Create a node configuration + FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); + NodeConfigurationFactory configurationFactory = modelFactories.getFactory(NodeConfigurationFactory.class); + NodeConfiguration configuration = configurationFactory.createNodeConfiguration(); + + URL location = bundle.getEntry("/"); + String uri = bundle.getSymbolicName(); + configuration.setURI(uri).addContribution(uri, location); + + if (compositeContent != null) { + configuration.addDeploymentComposite(uri, new StringReader(compositeContent)); + } else { + String compositeURI = (String)bundle.getHeaders().get("SCA-Composite"); + if (compositeURI == null) { + compositeURI = "OSGI-INF/sca/bundle.composite"; + } + if (compositeURI != null) { + configuration.addDeploymentComposite(uri, compositeURI); + } + } + // Set the bundle + // configuration.getExtensions().add(bundle); + return configuration; + } + + public synchronized void init() { + if (!inited) { + // Register the ExtensionPointRegistry as an OSGi service + Dictionary<Object, Object> props = new Hashtable<Object, Object>(); + registry = createExtensionPointRegistry(); + registry.start(); + registration = + bundleContext.registerService(ExtensionPointRegistry.class.getName(), registry, props); + + // Call super.init after the extension point registry is registered + super.init(); + } + } + + public synchronized void destroy() { + if (inited) { + if (registration != null) { + try { + registration.unregister(); + } catch (IllegalStateException e) { + // The service has been unregistered, ignore it + } + registration = null; + } + super.destroy(); + } + + } + + @Override + protected Object getNodeKey(NodeConfiguration configuration) { + // each bundle might have more than one nodes started + return super.getNodeKey(configuration); + } + + @Override + protected ExtensionPointRegistry createExtensionPointRegistry() { + return new OSGiExtensionPointRegistry(bundleContext); + } + + @Override + protected boolean isSchemaValidationEnabled() { + return logger.isLoggable(Level.FINE); + } + +} |