diff options
author | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-04-30 04:39:55 +0000 |
---|---|---|
committer | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-04-30 04:39:55 +0000 |
commit | 563383415f9efeb2ff9420f0097989e5b79a6257 (patch) | |
tree | 541c21b1ad15cfae8f057a70197b0e564dde3904 /branches/sca-java-1.x/modules/implementation-osgi/src/main/java | |
parent | b61cf23bd501dfde37fbef4056a7b1148ae92268 (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/src/main/java')
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() { |