summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-1.x/modules/implementation-osgi
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-04-30 04:39:55 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-04-30 04:39:55 +0000
commit563383415f9efeb2ff9420f0097989e5b79a6257 (patch)
tree541c21b1ad15cfae8f057a70197b0e564dde3904 /branches/sca-java-1.x/modules/implementation-osgi
parentb61cf23bd501dfde37fbef4056a7b1148ae92268 (diff)
Fix for TUSCANY-3000
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@770058 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-1.x/modules/implementation-osgi')
-rw-r--r--branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java626
-rw-r--r--branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProviderFactory.java38
2 files changed, 331 insertions, 333 deletions
diff --git a/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java b/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
index 5664c77618..b49f94c1e0 100644
--- a/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
+++ b/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
@@ -6,15 +6,15 @@
* 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.
+ * under the License.
*/
package org.apache.tuscany.sca.implementation.osgi.runtime;
@@ -92,51 +92,51 @@ import org.osgi.service.packageadmin.PackageAdmin;
*
* @version $Rev$ $Date$
*/
-public class OSGiImplementationProvider implements ScopedImplementationProvider,
+public class OSGiImplementationProvider implements ScopedImplementationProvider,
FrameworkListener,
BundleListener {
-
+
private static final String COMPONENT_SERVICE_NAME = "component.service.name";
-
+
// Maximum milliseconds to wait for a method to complete
- private static final long METHOD_TIMEOUT_MILLIS = 60000;
+ private static final long METHOD_TIMEOUT_MILLIS = 60000;
// Maximum milliseconds to wait for services to be registered into OSGi service registry
- private static final long SERVICE_TIMEOUT_MILLIS = 300000;
-
+ private static final long SERVICE_TIMEOUT_MILLIS = 300000;
+
private OSGiImplementationImpl implementation;
private OSGiAnnotations osgiAnnotations;
private BundleContext bundleContext;
-
+
private Hashtable<RuntimeWire, Reference> referenceWires = new Hashtable<RuntimeWire,Reference>();
- private Hashtable<RuntimeWire, ComponentReference> componentReferenceWires
+ private Hashtable<RuntimeWire, ComponentReference> componentReferenceWires
= new Hashtable<RuntimeWire,ComponentReference>();
- private HashSet<RuntimeWire> resolvedWires = new HashSet<RuntimeWire>();
+ private HashSet<RuntimeWire> resolvedWires = new HashSet<RuntimeWire>();
private boolean wiresResolved;
-
- private AtomicInteger startBundleEntryCount = new AtomicInteger();
+
+ private AtomicInteger startBundleEntryCount = new AtomicInteger();
private AtomicInteger processAnnotationsEntryCount = new AtomicInteger();
-
+
private JavaPropertyValueObjectFactory propertyValueFactory;
-
+
private Hashtable<String, Object> componentProperties = new Hashtable<String, Object>();
private RuntimeComponent runtimeComponent;
-
+
private Bundle osgiBundle;
private ArrayList<Bundle> dependentBundles = new ArrayList<Bundle>();
private OSGiServiceListener osgiServiceListener;
private PackageAdmin packageAdmin;
-
+
private OSGiRuntime osgiRuntime;
-
+
private ScopeRegistry scopeRegistry;
private DataBindingExtensionPoint dataBindingRegistry;
-
+
private boolean packagesRefreshed;
-
+
private MessageFactory messageFactory;
private InterfaceContractMapper mapper;
-
+
public OSGiImplementationProvider(RuntimeComponent definition,
OSGiImplementation impl,
@@ -147,8 +147,8 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
RequestContextFactory requestContextFactory,
MessageFactory messageFactory,
InterfaceContractMapper mapper) throws BundleException {
-
-
+
+
this.implementation = (OSGiImplementationImpl)impl;
this.runtimeComponent = definition;
this.dataBindingRegistry = dataBindingRegistry;
@@ -156,13 +156,13 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
this.scopeRegistry = scopeRegistry;
this.messageFactory = messageFactory;
this.mapper = mapper;
-
+
bundleContext = getBundleContext();
osgiBundle = (Bundle)implementation.getOSGiBundle();
bundleContext.addBundleListener(this);
- osgiServiceListener = new OSGiServiceListener(osgiBundle);
- bundleContext.addServiceListener(osgiServiceListener);
-
+ osgiServiceListener = new OSGiServiceListener(osgiBundle);
+ bundleContext.addServiceListener(osgiServiceListener);
+
// Install and start all dependent bundles
String[] imports = implementation.getImports();
for (int i = 0; i < imports.length; i++) {
@@ -170,9 +170,9 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
if (location.length() > 0) {
Bundle bundle = bundleContext.installBundle(location);
dependentBundles.add(bundle);
- }
+ }
}
-
+
this.osgiAnnotations = new OSGiAnnotations(
implementation.getModelFactories(),
@@ -184,68 +184,68 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
osgiBundle,
dependentBundles);
-
- // PackageAdmin is used to resolve bundles
- org.osgi.framework.ServiceReference packageAdminReference =
+
+ // PackageAdmin is used to resolve bundles
+ org.osgi.framework.ServiceReference packageAdminReference =
bundleContext.getServiceReference("org.osgi.service.packageadmin.PackageAdmin");
if (packageAdminReference != null) {
packageAdmin = (PackageAdmin) bundleContext.getService(packageAdminReference);
bundleContext.addFrameworkListener(this);
}
-
-
+
+
}
-
+
protected RuntimeComponent getRuntimeComponent() {
return runtimeComponent;
}
-
+
protected OSGiImplementationImpl getImplementation() {
return implementation;
}
-
- // Create a property table from the list of properties
+
+ // Create a property table from the list of properties
// The source properties are properties read from <property/> elements
- // Create property values in the table of the appropriate class based
+ // Create property values in the table of the appropriate class based
// on the property type specified.
private void processProperties(List<?> props, Hashtable<String, Object> propsTable) {
-
+
if (props != null) {
for (Object p : props) {
-
+
Property prop = (Property)p;
Class javaType = SimpleTypeMapperImpl.getJavaType(prop.getXSDType());
ObjectFactory<?> objFactory = propertyValueFactory.createValueFactory(prop, prop.getValue(), javaType);
- Object value = objFactory.getInstance();
+ Object value = objFactory.getInstance();
propsTable.put(prop.getName(), value);
}
}
}
-
+
private BundleContext getBundleContext() throws BundleException {
try {
if (bundleContext == null) {
osgiRuntime = OSGiRuntime.getRuntime();
- bundleContext = osgiRuntime .getBundleContext();
+ bundleContext = osgiRuntime .getBundleContext();
}
} catch (BundleException e) {
throw e;
} catch (Exception e) {
throw new BundleException("Could not start OSGi runtime", e);
}
-
-
+
+
return bundleContext;
}
-
-
+
+
private String getOSGiFilter(Hashtable<String, Object> props) {
-
+
String filter = "";
-
+
if (props != null && props.size() > 0) {
int propCount = 0;
for (String propName : props.keySet()) {
@@ -254,35 +254,35 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
filter = filter + "(" + propName + "=" + props.get(propName) + ")";
propCount++;
}
-
+
if (propCount > 1) filter = "(&" + filter + ")";
}
else
filter = null;
return filter;
}
-
+
/*
* Return a matching service registered by the specified bundle.
* If <implementation.osgi /> has the attribute filter defined, return a service
* reference that matches the filter. Otherwise, return a service which has a component
* name equal to this component's name. If not found, return a service which no
* component name set.
- *
+ *
* Even though services registered by this bundle can be filtered using the
- * service listener, we use this method to filter all service references so that
+ * service listener, we use this method to filter all service references so that
* the service matching functionality of OSGi can be directly used.
*/
- private org.osgi.framework.ServiceReference getOSGiServiceReference(
+ private org.osgi.framework.ServiceReference getOSGiServiceReference(
String scaServiceName,
- String osgiServiceName, String filter)
+ String osgiServiceName, String filter)
throws InvalidSyntaxException {
-
+
String compServiceName = runtimeComponent.getName() + "/" + scaServiceName;
if (filter != null && filter.length() > 0) {
- org.osgi.framework.ServiceReference[] references =
+ org.osgi.framework.ServiceReference[] references =
bundleContext.getServiceReferences(osgiServiceName, filter);
-
+
org.osgi.framework.ServiceReference reference = null;
if (references != null) {
@@ -298,32 +298,32 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
}
}
-
+
return reference;
-
+
}
-
- filter = scaServiceName == null? null :
+
+ filter = scaServiceName == null? null :
"(" + COMPONENT_SERVICE_NAME + "="+ compServiceName + ")";
-
- org.osgi.framework.ServiceReference[] references =
+
+ org.osgi.framework.ServiceReference[] references =
bundleContext.getServiceReferences(osgiServiceName, filter);
-
- if (references != null) {
+
+ if (references != null) {
for (org.osgi.framework.ServiceReference ref : references) {
if (ref.getBundle() == osgiBundle) {
return ref;
}
}
}
-
+
references = bundleContext.getServiceReferences(osgiServiceName, null);
-
+
org.osgi.framework.ServiceReference reference = null;
-
+
if (references != null) {
for (org.osgi.framework.ServiceReference ref : references) {
-
+
if (ref.getBundle() != osgiBundle)
continue;
Object compName = ref.getProperty(COMPONENT_SERVICE_NAME);
@@ -335,21 +335,21 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
}
}
-
+
return reference;
}
-
+
/**
* This method is used to avoid full synchronization of methods which should
- * be executed only once.
- *
+ * be executed only once.
+ *
* entryCount=0: The count is incremented, and this thread executes the method. Returns true.
- *
- * entryCount=1: Another thread is already executing this method.
- * Wait for the thread to complete if doWait is true. Returns false.
- *
+ *
+ * entryCount=1: Another thread is already executing this method.
+ * Wait for the thread to complete if doWait is true. Returns false.
+ *
* entryCount=2: The method has already been executed. Returns false.
- *
+ *
* @param doWait If true, and another method is executing this method
* wait for method execution to complete
* @param entryCount Atomic integer used to ensure that the method is
@@ -357,7 +357,7 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
* @return true if this thread has exclusive access to execute this method
*/
private boolean enterMethod(boolean doWait, AtomicInteger entryCount) {
-
+
if (entryCount.compareAndSet(0, 1)) {
return true;
}
@@ -375,12 +375,12 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
return false;
}
}
-
+
/**
- * Called on method exit of methods which were entered after
+ * Called on method exit of methods which were entered after
* enterMethod returned true. Increments entryCount, and wakes
* up threads waiting for the method to complete.
- *
+ *
* @param entryCount Atomic integer used for synchronization
*/
private void exitMethod(AtomicInteger entryCount) {
@@ -389,20 +389,20 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
entryCount.notifyAll();
}
}
-
+
protected Bundle startBundle(boolean doWait) throws ObjectCreationException {
try {
-
- if (enterMethod(doWait, startBundleEntryCount)) {
-
+
+ if (enterMethod(doWait, startBundleEntryCount)) {
+
configurePropertiesUsingConfigAdmin();
-
+
resolveBundle();
-
+
processAnnotations(true);
-
-
+
+
for (Bundle bundle : dependentBundles) {
try {
if (bundle.getState() != Bundle.ACTIVE && bundle.getState() != Bundle.STARTING) {
@@ -413,14 +413,14 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
throw e;
}
}
-
+
}
-
+
if (osgiBundle.getState() != Bundle.ACTIVE && osgiBundle.getState() != Bundle.STARTING) {
-
+
int retry = 0;
-
+
while (retry++ < 10) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@@ -433,15 +433,15 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
// } catch ( BundleException e) {
} catch ( PrivilegedActionException e) {
// It is possible that the thread "Refresh Packages" is in the process of
- // changing the state of this bundle.
+ // changing the state of this bundle.
Thread.yield();
-
+
if (retry == 10)
throw e;
}
}
- }
-
+ }
+
} catch (Exception e) {
throw new ObjectCreationException(e);
} finally {
@@ -449,32 +449,32 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
return osgiBundle;
}
-
-
+
+
// This method is called by OSGiInstanceWrapper.getInstance to obtain the OSGi service reference
// corresponding to the specified service. The properties used to filter the service should
// be chosen based on whether this is a normal service or a callback.
- protected org.osgi.framework.ServiceReference getOSGiServiceReference(ComponentService service)
+ protected org.osgi.framework.ServiceReference getOSGiServiceReference(ComponentService service)
throws ObjectCreationException {
-
+
Hashtable<String, Object> props = new Hashtable<String, Object>();
if (!service.isCallback())
processProperties(implementation.getServiceProperties(service.getName()), props);
else
processProperties(implementation.getServiceCallbackProperties(service.getName()), props);
-
+
String filter = getOSGiFilter(props);
Interface serviceInterface = service.getInterfaceContract().getInterface();
String scaServiceName = service.getName();
-
+
return getOSGiServiceReference(serviceInterface, filter, scaServiceName);
-
+
}
-
+
protected org.osgi.framework.ServiceReference getOSGiServiceReference(
- EndpointReference from, Interface callbackInterface)
+ EndpointReference from, Interface callbackInterface)
throws ObjectCreationException {
-
+
RuntimeWire refWire = null;
String filter = null;
for (RuntimeWire wire : referenceWires.keySet()) {
@@ -489,58 +489,58 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
processProperties(implementation.getReferenceCallbackProperties(scaRef.getName()), props);
filter = getOSGiFilter(props);
}
-
+
return getOSGiServiceReference(callbackInterface, filter, null);
}
-
+
private org.osgi.framework.ServiceReference getOSGiServiceReference(Interface serviceInterface,
String filter, String scaServiceName)
throws ObjectCreationException {
-
+
try {
-
+
String serviceInterfaceName = null;
org.osgi.framework.ServiceReference osgiServiceReference = null;
-
+
if (serviceInterface instanceof JavaInterface) {
serviceInterfaceName = ((JavaInterface)serviceInterface).getJavaClass().getName();
-
- if ((osgiServiceReference = getOSGiServiceReference(
+
+ if ((osgiServiceReference = getOSGiServiceReference(
scaServiceName,
serviceInterfaceName, filter)) == null) {
-
+
// The service listener for our bundle will notify us when the service is registered.
- synchronized (implementation) {
-
+ synchronized (implementation) {
+
// When declarative services are used, the component is started asynchronously
// So this thread has to wait for the service to be registered by the component
// activate method
// For regular bundle activators, bundle.start activates the bundle synchronously
// and hence the service would probably have been started by the bundle activator
long startTime = System.currentTimeMillis();
- while ((osgiServiceReference = getOSGiServiceReference(
+ while ((osgiServiceReference = getOSGiServiceReference(
scaServiceName,
serviceInterfaceName, filter)) == null) {
-
+
// Wait for the bundle to register the service
implementation.wait(100);
if (System.currentTimeMillis() - startTime > SERVICE_TIMEOUT_MILLIS)
break;
}
- }
-
+ }
+
}
}
-
+
return osgiServiceReference;
-
+
} catch (Exception e) {
throw new ObjectCreationException(e);
}
}
-
-
+
+
// Felix does not support bundle fragments. This is a temporary workaround.
protected Bundle installDummyBundleWithoutFragments(Class<?> interfaceClass)
throws Exception {
@@ -558,7 +558,7 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
+ bundleName + EOL + "Bundle-SymbolicName: " + bundleName + EOL
+ "Bundle-Version: " + "1.0.0" + EOL
+ "Bundle-Localization: plugin" + EOL;
-
+
ArrayList<String> dummyClasses = new ArrayList<String>();
StringBuilder manifestBuf = new StringBuilder();
@@ -571,10 +571,10 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
for (Class<?> clazz : interfaceClass.getClasses()) {
dummyClasses.add(clazz.getName());
}
- if (existingBundle != null &&
+ if (existingBundle != null &&
(existingClasses = (String)existingBundle.getHeaders().get("SCA-Dummy-Classes")) != null) {
exportedInterfaces = exportedInterfaces + " " + existingClasses;
-
+
StringTokenizer tokenizer = new StringTokenizer(existingClasses);
while (tokenizer.hasMoreTokens()) {
String className = tokenizer.nextToken();
@@ -595,23 +595,23 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
for (int i = 0; i < dummyClasses.size(); i++) {
String className = dummyClasses.get(i);
-
+
Class clazz = interfaceClass.getClassLoader().loadClass(className);
className = clazz.getName().replaceAll("\\.", "/") + ".class";
ZipEntry ze = new ZipEntry(className);
jarOut.putNextEntry(ze);
InputStream stream = clazz.getResourceAsStream(clazz.getSimpleName() + ".class");
-
+
byte[] bytes = new byte[stream.available()];
stream.read(bytes);
jarOut.write(bytes);
stream.close();
}
-
-
+
+
jarOut.close();
out.close();
-
+
if (existingBundle != null) {
existingBundle.stop();
existingBundle.uninstall();
@@ -623,129 +623,129 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
+ ".jar", in);
bundle.start();
-
+
if (existingBundle != null && packageAdmin != null) {
refreshPackages();
-
+
}
return bundle;
}
-
+
private Bundle getDummyHostBundle(String packageName) {
-
+
if (packageAdmin == null)
return null;
-
+
ExportedPackage exp = packageAdmin.getExportedPackage(packageName);
if (exp == null)
return null;
else
return exp.getExportingBundle();
}
-
+
private static String getPackageName(Class<?> cls) {
String name = cls.getName();
int index = name.lastIndexOf('.');
return index == -1 ? "" : name.substring(0, index);
}
-
+
private Bundle installDummyBundle(Class<?> interfaceClass)
throws Exception {
-
+
if (!osgiRuntime.supportsBundleFragments()) {
return installDummyBundleWithoutFragments(interfaceClass);
}
-
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
-
+
String EOL = System.getProperty("line.separator");
ArrayList<Class<?>> dummyClasses = new ArrayList<Class<?>>();
-
+
String interfaceName = interfaceClass.getName();
String packageName = getPackageName(interfaceClass);
String bundleName = "dummy.sca." + interfaceName;
-
-
+
+
String manifestStr = "Manifest-Version: 1.0" + EOL +
"Bundle-ManifestVersion: 2" + EOL +
"Bundle-Name: " + bundleName + EOL +
"Bundle-SymbolicName: " + bundleName + EOL +
"Bundle-Version: " + "1.0.0" + EOL +
"Bundle-Localization: plugin" + EOL;
-
-
+
+
StringBuilder manifestBuf = new StringBuilder();
manifestBuf.append(manifestStr);
manifestBuf.append("Export-Package: " + packageName + EOL);
Bundle dummyHost = getDummyHostBundle(packageName);
if (dummyHost != null)
manifestBuf.append("Fragment-Host: " + dummyHost.getSymbolicName() + EOL);
-
+
ByteArrayInputStream manifestStream = new ByteArrayInputStream(manifestBuf.toString().getBytes());
Manifest manifest = new Manifest();
manifest.read(manifestStream);
-
+
dummyClasses.add(interfaceClass);
for (Class<?> clazz : interfaceClass.getClasses()) {
dummyClasses.add(clazz);
}
-
+
JarOutputStream jarOut = new JarOutputStream(out, manifest);
for (int i = 0; i < dummyClasses.size(); i++) {
-
+
Class<?> clazz = dummyClasses.get(i);
String className = clazz.getName();
className = clazz.getName().replaceAll("\\.", "/") + ".class";
ZipEntry ze = new ZipEntry(className);
jarOut.putNextEntry(ze);
InputStream stream = clazz.getResourceAsStream(clazz.getSimpleName() + ".class");
-
+
byte[] bytes = new byte[stream.available()];
stream.read(bytes);
jarOut.write(bytes);
stream.close();
}
-
+
jarOut.close();
out.close();
-
-
+
+
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-
-
+
+
Bundle bundle = bundleContext.installBundle(
"file://" + bundleName + ".jar",
in);
-
+
if (dummyHost == null)
bundle.start();
-
+
return bundle;
-
+
}
-
-
-
+
+
+
public InstanceWrapper<?> createInstanceWrapper() throws ObjectCreationException {
-
+
return new OSGiInstanceWrapper<Object>(this, osgiAnnotations, bundleContext);
}
-
-
-
+
+
+
private void resolveWireCreateDummyBundles(final Class interfaceClass) throws Exception {
-
-
+
+
try {
-
+
osgiBundle.loadClass(interfaceClass.getName());
-
+
} catch (ClassNotFoundException e) {
-
+
// The interface used by the proxy is not in the source bundle
// A dummy bundle needs to be installed to create the proxy
// Allow privileged access to file system. Requires FileSystem permission in security
@@ -755,89 +755,89 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
return installDummyBundle(interfaceClass);
}
});
-
+
if (packageAdmin != null) {
-
+
packageAdmin.resolveBundles(new Bundle[]{dummyBundle, osgiBundle});
-
- }
+
+ }
}
}
-
+
/**
* For OSGi->Java wires, create a proxy corresponding to the Java interfaces
- * and register the proxy with the OSGi registry, so that the source OSGi bundle can
+ * and register the proxy with the OSGi registry, so that the source OSGi bundle can
* locate the target Java instance from the registry like a regular OSGi service.
- *
+ *
* For OSGi->OSGi wires, start the target OSGi bundle, so that references of the
* target are resolved before the source OSGi bundle is started. If the reference
* has properties specified, create a Proxy and register a service with highest
* possible ranking. The Proxy should wire to the correct OSGi instance specified
* in the SCA composite.
- *
+ *
* The first phase determines whether a proxy should be installed. It also registers
* a dummy bundle if necessary to resolve the bundle. When phase1 is completed on all
* wires of the component, the bundle should be resolved. Phase2 registers the proxy service.
*/
private boolean resolveWireResolveReferences(Bundle bundle, Class interfaceClass, RuntimeWire wire,
boolean isOSGiToOSGiWire) throws Exception {
-
+
// FIXME: At the moment injection of values into instances require an instance to be obtained
// through the instance wrapper, and hence requires a proxy. When we do this processing here,
// we don't yet know whether the target requires any property or callback injection. So it is
- // safer to create a proxy all the time.
- boolean createProxy = true;
-
+ // safer to create a proxy all the time.
+ boolean createProxy = true;
+
ComponentReference scaRef = componentReferenceWires.get(wire);
Hashtable<String, Object> targetProperties = new Hashtable<String, Object>();
processProperties(implementation.getReferenceProperties(scaRef.getName()), targetProperties);
-
+
if (isOSGiToOSGiWire) {
-
+
OSGiImplementationProvider implProvider = (OSGiImplementationProvider)wire.getTarget().getComponent().getImplementationProvider();
-
+
// This is an OSGi->OSGi wire
isOSGiToOSGiWire = true;
-
- // If the target component is stateless, use a proxy to create a new service each time
+
+ // If the target component is stateless, use a proxy to create a new service each time
if (!implProvider.getScope().equals(Scope.COMPOSITE)) createProxy = true;
-
+
Interface interfaze = wire.getTarget().getInterfaceContract().getInterface();
-
+
// If the target interface is remotable, create a proxy to support pass-by-value semantics
// AllowsPassByReference is not detected until the target instance is obtained.
if (interfaze.isRemotable())
createProxy = true;
-
+
// If any of the operations in the target interface is non-blocking, create a proxy
List<Operation> ops = interfaze.getOperations();
for (Operation op : ops) {
if (op.isNonBlocking())
createProxy = true;
}
-
+
// If properties are specified for the reference, create a proxy since rewiring may be required
if (targetProperties.size() > 0) {
createProxy = true;
}
-
+
// If properties are specified for the component, create a proxy for configuring
// the component services.
if (componentProperties.size() > 0) {
createProxy = true;
}
-
+
// Since this is an OSGi->OSGi wire, start the target bundle before starting the
- // source bundle if there is no proxy. For direct wiring without a proxy, this ordering
- // is irrelevant in terms of class resolution, but the target needs to be started at some
- // point. But there is no opportunity later on to start the target OSGi bundle without a proxy.
+ // source bundle if there is no proxy. For direct wiring without a proxy, this ordering
+ // is irrelevant in terms of class resolution, but the target needs to be started at some
+ // point. But there is no opportunity later on to start the target OSGi bundle without a proxy.
// When a Proxy is used, the target bundle needs to be resolved for the source bundle
// to be resolved so that the interface is visible to the source. In this case the bundle
- // will be started when an instance is needed.
- if (!createProxy) {
+ // will be started when an instance is needed.
+ if (!createProxy) {
implProvider.startBundle(false);
}
else {
@@ -847,26 +847,26 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
else {
createProxy = true;
}
-
+
return createProxy;
}
-
-
- // Register proxy service
+
+
+ // Register proxy service
private void resolveWireRegisterProxyService(final Bundle bundle, final Class interfaceClass, RuntimeWire wire) throws Exception {
-
+
ComponentReference scaRef = componentReferenceWires.get(wire);
Hashtable<String, Object> targetProperties = new Hashtable<String, Object>();
processProperties(implementation.getReferenceProperties(scaRef.getName()), targetProperties);
targetProperties.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
-
+
if (targetProperties.get(COMPONENT_SERVICE_NAME) == null && wire.getTarget().getComponent() != null) {
- String compServiceName = wire.getTarget().getComponent().getName() + "/" +
+ String compServiceName = wire.getTarget().getComponent().getName() + "/" +
wire.getTarget().getContract().getName();
targetProperties.put(COMPONENT_SERVICE_NAME, compServiceName);
}
-
-
+
+
JDKProxyFactory proxyService = new JDKProxyFactory(messageFactory, mapper);
// Allow privileged access to load classes. Requires getClassLoader permission in security
@@ -885,18 +885,18 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
return null;
}
});
-
-
+
+
}
-
-
+
+
private void refreshPackages() {
-
+
if (packageAdmin != null) {
synchronized (this) {
packagesRefreshed = false;
packageAdmin.refreshPackages(null);
-
+
if (!packagesRefreshed) {
try {
this.wait(2000);
@@ -905,24 +905,24 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
}
packagesRefreshed = false;
- }
+ }
}
}
-
-
+
+
private void resolveBundle() throws ObjectCreationException {
-
-
+
+
try {
-
+
if (!wiresResolved) {
wiresResolved = true;
-
+
if (!setReferencesAndProperties()) {
wiresResolved = false;
return;
}
-
+
int refPlusServices = referenceWires.size() + runtimeComponent.getServices().size();
boolean[] createProxyService = new boolean[refPlusServices];
Class<?>[] interfaceClasses = new Class<?>[refPlusServices] ;
@@ -930,47 +930,47 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
boolean[] wireResolved = new boolean[refPlusServices];
int index = 0;
for (RuntimeWire wire : referenceWires.keySet()) {
-
+
Reference reference = referenceWires.get(wire);
-
+
isOSGiToOSGiWire[index] = wire.getTarget().getComponent() != null &&
- wire.getTarget().getComponent().getImplementationProvider()
+ wire.getTarget().getComponent().getImplementationProvider()
instanceof OSGiImplementationProvider;
-
+
Interface refInterface = reference.getInterfaceContract().getInterface();
if (refInterface instanceof JavaInterface) {
interfaceClasses[index] = ((JavaInterface)refInterface).getJavaClass();
-
+
if (!isOSGiToOSGiWire[index])
resolveWireCreateDummyBundles(interfaceClasses[index]);
}
-
+
if (!resolvedWires.contains(wire)) {
- resolvedWires.add(wire);
+ resolvedWires.add(wire);
}
else
wireResolved[index] = true;
-
+
index++;
}
for (ComponentService service : runtimeComponent.getServices()) {
Interface callbackInterface = service.getInterfaceContract().getCallbackInterface();
if (callbackInterface instanceof JavaInterface) {
interfaceClasses[index] = ((JavaInterface)callbackInterface).getJavaClass();
-
+
resolveWireCreateDummyBundles(interfaceClasses[index]);
}
-
+
index++;
}
-
+
index = 0;
for (RuntimeWire wire : referenceWires.keySet()) {
-
+
if (!wireResolved[index]) {
- createProxyService[index] = resolveWireResolveReferences(osgiBundle,
- interfaceClasses[index],
+ createProxyService[index] = resolveWireResolveReferences(osgiBundle,
+ interfaceClasses[index],
wire,
isOSGiToOSGiWire[index]);
}
@@ -978,11 +978,11 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
refreshPackages();
-
-
+
+
index = 0;
for (RuntimeWire wire : referenceWires.keySet()) {
-
+
if (createProxyService[index] && !wireResolved[index])
resolveWireRegisterProxyService(osgiBundle, interfaceClasses[index], wire);
index++;
@@ -991,48 +991,48 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
else if (osgiBundle.getState() == Bundle.INSTALLED && packageAdmin != null) {
packageAdmin.resolveBundles(new Bundle[] {osgiBundle});
}
-
+
} catch (Exception e) {
e.printStackTrace();
throw new ObjectCreationException(e);
- }
+ }
}
-
-
+
+
@SuppressWarnings("unchecked")
private void configurePropertiesUsingConfigAdmin() {
-
+
try {
if (componentProperties.size() == 0)
return;
-
- org.osgi.framework.ServiceReference configAdminReference =
+
+ org.osgi.framework.ServiceReference configAdminReference =
bundleContext.getServiceReference("org.osgi.service.cm.ConfigurationAdmin");
if (configAdminReference != null) {
-
+
Object cm = bundleContext.getService(configAdminReference);
Class cmClass = cm.getClass().getClassLoader().loadClass("org.osgi.service.cm.ConfigurationAdmin");
Method getConfigMethod = cmClass.getMethod("getConfiguration", String.class, String.class);
-
+
Class configClass = cm.getClass().getClassLoader().loadClass("org.osgi.service.cm.Configuration");
-
+
Method getMethod = configClass.getMethod("getProperties");
Method updateMethod = configClass.getMethod("update", Dictionary.class);
-
+
List<Service> services = implementation.getServices();
HashSet<String> pidsProcessed = new HashSet<String>();
-
+
for (Service service : services) {
-
+
List<ComponentProperty> serviceProps = implementation.getServiceProperties(service.getName());
String pid = null;
-
+
if (serviceProps != null) {
for (ComponentProperty prop : serviceProps) {
if (prop.getName().equals("service.pid")) {
- ObjectFactory objFactory = propertyValueFactory.createValueFactory(prop,
+ ObjectFactory objFactory = propertyValueFactory.createValueFactory(prop,
prop.getValue(), String.class);
pid = (String)objFactory.getInstance();
}
@@ -1040,10 +1040,10 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
}
if (pid == null || pidsProcessed.contains(pid))
continue;
-
-
-
+
+
+
Object config = getConfigMethod.invoke(cm, pid, null);
Dictionary props = (Dictionary) getMethod.invoke(config);
if (props == null)
@@ -1052,26 +1052,26 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
props.put(propertyName, componentProperties.get(propertyName));
}
-
+
updateMethod.invoke(config, props);
-
-
- }
-
+
+
+ }
+
}
-
+
} catch (Exception e) {
e.printStackTrace();
}
}
-
-
-
+
+
+
public boolean isOptimizable() {
return false;
}
-
+
public Scope getScope() {
return osgiAnnotations.getScope();
}
@@ -1087,15 +1087,15 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
public long getMaxIdleTime() {
return osgiAnnotations.getMaxIdleTime();
}
-
+
protected ScopeContainer<?> getScopeContainer() {
startBundle(true);
return ((ScopedRuntimeComponent)runtimeComponent).getScopeContainer();
}
-
+
public Invoker createTargetInvoker(RuntimeComponentService service, Operation operation) {
-
-
+
+
Interface serviceInterface = operation.getInterface();
boolean isRemotable = serviceInterface.isRemotable();
@@ -1106,39 +1106,39 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
} else {
return invoker;
}
-
+
}
-
-
+
+
public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
return createTargetInvoker(service, operation);
}
-
+
public boolean supportsOneWayInvocation() {
return false;
}
private boolean setReferencesAndProperties() {
-
+
for (Reference ref: implementation.getReferences()) {
List<RuntimeWire> wireList = null;
ComponentReference compRef = null;
for (ComponentReference cRef : runtimeComponent.getReferences()) {
if (cRef.getName().equals(ref.getName())) {
-
+
wireList = ((RuntimeComponentReference)cRef).getRuntimeWires();
-
+
compRef = cRef;
break;
}
}
-
+
if (ref.getMultiplicity() == Multiplicity.ONE_N || ref.getMultiplicity() == Multiplicity.ZERO_N) {
for (RuntimeWire wire : wireList) {
referenceWires.put(wire, ref);
componentReferenceWires.put(wire, compRef);
}
-
+
} else {
if (wireList == null && ref.getMultiplicity() == Multiplicity.ONE_ONE) {
throw new IllegalStateException("Required reference is missing: " + ref.getName());
@@ -1148,29 +1148,29 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
referenceWires.put(wire, ref);
componentReferenceWires.put(wire, compRef);
}
-
+
}
-
+
}
-
+
processProperties(runtimeComponent.getProperties(), componentProperties);
-
+
return true;
-
+
}
-
+
public void start() {
setReferencesAndProperties();
}
-
+
public void processAnnotations(boolean doWait) throws IntrospectionException {
-
+
if (!enterMethod(doWait, processAnnotationsEntryCount))
return;
-
+
try {
osgiAnnotations.processAnnotations();
-
+
Scope scope = osgiAnnotations.getScope();
if (scope.equals(Scope.SYSTEM) || scope.equals(Scope.COMPOSITE)) {
// Nothing
@@ -1187,65 +1187,65 @@ public class OSGiImplementationProvider implements ScopedImplementationProvider
if (oldScopeContainer != null && oldScopeContainer.getLifecycleState() == ScopeContainer.RUNNING) {
scopeContainer.start();
}
-
+
component.setScopeContainer(scopeContainer);
}
}
} finally {
exitMethod(processAnnotationsEntryCount);
- }
+ }
}
-
+
public void stop() {
if (osgiServiceListener != null)
bundleContext.removeServiceListener(osgiServiceListener);
}
-
-
+
+
public void frameworkEvent(FrameworkEvent event) {
if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
synchronized (this) {
packagesRefreshed = true;
this.notifyAll();
- }
+ }
}
-
+
}
-
+
public void bundleChanged(BundleEvent event) {
if (event.getType() == BundleEvent.RESOLVED && event.getBundle() == osgiBundle) {
try {
processAnnotations(false);
} catch (Throwable e) {
e.printStackTrace();
- }
+ }
}
}
private class OSGiServiceListener implements ServiceListener {
-
+
private Bundle bundle;
-
+
OSGiServiceListener(Bundle bundle) {
this.bundle = bundle;
}
-
+
public void serviceChanged(org.osgi.framework.ServiceEvent event) {
-
+
org.osgi.framework.ServiceReference reference = event.getServiceReference();
-
+
if (event.getType() == ServiceEvent.REGISTERED && reference.getBundle() == bundle) {
-
+
synchronized (implementation) {
-
+
implementation.notifyAll();
}
}
-
+
if (event.getType() == ServiceEvent.UNREGISTERING && reference.getBundle() == bundle) {
// TODO: Process deregistering of OSGi services.
}
diff --git a/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProviderFactory.java b/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProviderFactory.java
index 814d37f203..1a13ef99f7 100644
--- a/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProviderFactory.java
+++ b/branches/sca-java-1.x/modules/implementation-osgi/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProviderFactory.java
@@ -6,15 +6,15 @@
* 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.
+ * under the License.
*/
package org.apache.tuscany.sca.implementation.osgi.runtime;
@@ -29,8 +29,7 @@ import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint;
import org.apache.tuscany.sca.core.scope.ScopeRegistry;
import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
-import org.apache.tuscany.sca.databinding.TransformerExtensionPoint;
-import org.apache.tuscany.sca.databinding.impl.MediatorImpl;
+import org.apache.tuscany.sca.databinding.Mediator;
import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
import org.apache.tuscany.sca.implementation.osgi.OSGiImplementation;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
@@ -47,48 +46,47 @@ import org.osgi.framework.BundleException;
* @version $Rev$ $Date$
*/
public class OSGiImplementationProviderFactory implements ImplementationProviderFactory<OSGiImplementation> {
-
+
private DataBindingExtensionPoint dataBindings;
private JavaPropertyValueObjectFactory propertyFactory;
private ProxyFactory proxyFactory;
private ScopeRegistry scopeRegistry;
private MessageFactory messageFactory;
private InterfaceContractMapper mapper;
-
+
private RequestContextFactory requestContextFactory;
-
+
public OSGiImplementationProviderFactory(ExtensionPointRegistry extensionPoints ) {
-
+
dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class);
ProxyFactoryExtensionPoint proxyFactories = extensionPoints.getExtensionPoint(ProxyFactoryExtensionPoint.class);
proxyFactory = new ExtensibleProxyFactory(proxyFactories);
ContextFactoryExtensionPoint contextFactories = extensionPoints.getExtensionPoint(ContextFactoryExtensionPoint.class);
requestContextFactory = contextFactories.getFactory(RequestContextFactory.class);
-
+
// FIXME: Scope registry is not an extension point, and this usage is specific
// to implementation.osgi since it needs to change scope after the component is
// created. Do we need to find a better way?
scopeRegistry = extensionPoints.getExtensionPoint(ScopeRegistry.class);
-
- TransformerExtensionPoint transformers = extensionPoints.getExtensionPoint(TransformerExtensionPoint.class);
- MediatorImpl mediator = new MediatorImpl(dataBindings, transformers);
+
+ Mediator mediator = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class).getUtility(Mediator.class);
propertyFactory = new JavaPropertyValueObjectFactory(mediator);
ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
messageFactory = modelFactories.getFactory(MessageFactory.class);
-
+
UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
mapper = utilities.getUtility(InterfaceContractMapper.class);
}
public ImplementationProvider createImplementationProvider(RuntimeComponent component,
OSGiImplementation implementation) {
-
+
try {
-
- return new OSGiImplementationProvider(component,
- implementation,
+
+ return new OSGiImplementationProvider(component,
+ implementation,
dataBindings,
propertyFactory,
proxyFactory,
@@ -97,11 +95,11 @@ public class OSGiImplementationProviderFactory implements ImplementationProvider
messageFactory,
mapper
);
-
+
} catch (BundleException e) {
throw new RuntimeException(e);
}
-
+
}
public Class<OSGiImplementation> getModelType() {