summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main')
-rw-r--r--sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java93
1 files changed, 81 insertions, 12 deletions
diff --git a/sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java b/sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
index 78b1ea476f..1d5d99cd34 100644
--- a/sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
+++ b/sca-java-2.x/trunk/modules/implementation-osgi-runtime/src/main/java/org/apache/tuscany/sca/implementation/osgi/runtime/OSGiImplementationProvider.java
@@ -25,6 +25,10 @@ import static org.apache.tuscany.sca.implementation.osgi.OSGiProperty.SERVICE_IM
import static org.apache.tuscany.sca.implementation.osgi.OSGiProperty.SERVICE_IMPORTED_CONFIGS;
import static org.osgi.framework.Constants.SERVICE_RANKING;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
@@ -54,6 +58,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceException;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
@@ -130,7 +135,7 @@ public class OSGiImplementationProvider implements ImplementationProvider {
registrations.add(registration);
}
}
-
+
// Set the OSGi service reference properties into the SCA service
for (ComponentService service : component.getServices()) {
// The properties might have been set by the export service
@@ -229,6 +234,66 @@ public class OSGiImplementationProvider implements ImplementationProvider {
return implementation;
}
+ /**
+ * A proxy invocation handler that wrap exceptions into OSGi ServiceException
+ */
+ private static class InvocationHandlerDelegate implements InvocationHandler {
+ private final Object instance;
+
+ public InvocationHandlerDelegate(Object instance) {
+ super();
+ this.instance = instance;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (!Proxy.isProxyClass(instance.getClass())) {
+ Method m = instance.getClass().getMethod(method.getName(), method.getParameterTypes());
+ try {
+ return m.invoke(instance, args);
+ } catch (InvocationTargetException e) {
+ wrapException(method, e.getCause());
+ return null;
+ }
+ } else {
+ InvocationHandler handler = Proxy.getInvocationHandler(instance);
+ try {
+ return handler.invoke(instance, method, args);
+ } catch (Throwable e) {
+ wrapException(method, e);
+ return null;
+ }
+ }
+ }
+
+ private void wrapException(Method method, Throwable e) throws Throwable {
+ for (Class<?> exType : method.getExceptionTypes()) {
+ if (exType.isInstance(e)) {
+ throw e;
+ }
+ }
+ throw new ServiceException(e.getMessage(), ServiceException.REMOTE, e);
+ }
+
+ /**
+ * A utility to cast the object to the given interface. If the class for the object
+ * is loaded by a different classloader, a proxy will be created.
+ *
+ * @param <T>
+ * @param obj
+ * @param cls
+ * @return
+ */
+ static <T> T cast(Object obj, Class<T> cls) {
+ if (obj == null) {
+ return null;
+ } else {
+ return cls.cast(Proxy.newProxyInstance(cls.getClassLoader(),
+ new Class<?>[] {cls},
+ new InvocationHandlerDelegate(obj)));
+ }
+ }
+ }
+
public class OSGiServiceFactory implements ServiceFactory {
private RuntimeEndpointReference epr;
private String interfaceName;
@@ -240,22 +305,26 @@ public class OSGiImplementationProvider implements ImplementationProvider {
public OSGiServiceFactory(String interfaceName, EndpointReference epr) {
super();
this.interfaceName = interfaceName;
- this.epr = (RuntimeEndpointReference) epr;
+ this.epr = (RuntimeEndpointReference)epr;
}
public Object getService(Bundle bundle, ServiceRegistration registration) {
- Class<?> interfaceClass = null;
try {
- interfaceClass = bundle.loadClass(interfaceName);
- } catch (ClassNotFoundException e) {
- return null;
- }
- ProxyFactory proxyService = proxyFactoryExtensionPoint.getInterfaceProxyFactory();
- if (!interfaceClass.isInterface()) {
- proxyService = proxyFactoryExtensionPoint.getClassProxyFactory();
+ Class<?> interfaceClass = null;
+ try {
+ interfaceClass = bundle.loadClass(interfaceName);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ ProxyFactory proxyService = proxyFactoryExtensionPoint.getInterfaceProxyFactory();
+ if (!interfaceClass.isInterface()) {
+ proxyService = proxyFactoryExtensionPoint.getClassProxyFactory();
+ }
+ Object proxy = proxyService.createProxy(interfaceClass, epr);
+ return InvocationHandlerDelegate.cast(proxy, interfaceClass);
+ } catch (Throwable e) {
+ throw new ServiceException(e.getMessage(), ServiceException.FACTORY_EXCEPTION, e);
}
- Object proxy = proxyService.createProxy(interfaceClass, epr);
- return proxy;
}
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {