diff options
author | bdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-18 13:53:47 +0000 |
---|---|---|
committer | bdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-18 13:53:47 +0000 |
commit | 219ae1935ec10aeb4b5a1955183272cda9a3a574 (patch) | |
tree | 1065600edfbc333f7df2fe79239d065efc34517c /sca-java-2.x/trunk/modules/implementation-java-runtime/src | |
parent | a91e13d3e237ea8dcd91a1eafaecf47203e50768 (diff) |
TUSCANY-3652 Inject callbacks at service invocation
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@986678 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/trunk/modules/implementation-java-runtime/src')
7 files changed, 112 insertions, 23 deletions
diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java index 209546ce2f..f5d9860130 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceFactory.java @@ -36,15 +36,18 @@ public class ReflectiveInstanceFactory<T> implements InstanceFactory<T> { private final Injector<T>[] injectors; private final EventInvoker<T> initInvoker; private final EventInvoker<T> destroyInvoker; + private final Injector<T>[] callbackInjectors; public ReflectiveInstanceFactory(Constructor<T> ctr, ObjectFactory<?>[] ctrArgs, Injector<T>[] injectors, + Injector<T>[] callbackInjectors, EventInvoker<T> initInvoker, EventInvoker<T> destroyInvoker) { this.ctr = ctr; this.ctrArgs = ctrArgs; this.injectors = injectors; + this.callbackInjectors = callbackInjectors; this.initInvoker = initInvoker; this.destroyInvoker = destroyInvoker; } @@ -88,6 +91,6 @@ public class ReflectiveInstanceFactory<T> implements InstanceFactory<T> { } } - return new ReflectiveInstanceWrapper<T>(instance, initInvoker, destroyInvoker); + return new ReflectiveInstanceWrapper<T>(instance, initInvoker, destroyInvoker, callbackInjectors); } } diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java index 7c96606cf6..a3ed16dde5 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/context/ReflectiveInstanceWrapper.java @@ -21,6 +21,7 @@ package org.apache.tuscany.sca.implementation.java.context; import org.apache.tuscany.sca.core.factory.InstanceWrapper; import org.apache.tuscany.sca.core.scope.TargetDestructionException; import org.apache.tuscany.sca.core.scope.TargetInitializationException; +import org.apache.tuscany.sca.implementation.java.injection.Injector; import org.apache.tuscany.sca.implementation.java.invocation.EventInvoker; /** @@ -30,11 +31,13 @@ public class ReflectiveInstanceWrapper<T> implements InstanceWrapper<T> { private final EventInvoker<T> initInvoker; private final EventInvoker<T> destroyInvoker; private final T instance; + private final Injector<T>[] callbackInjectors; - public ReflectiveInstanceWrapper(T instance, EventInvoker<T> initInvoker, EventInvoker<T> destroyInvoker) { + public ReflectiveInstanceWrapper(T instance, EventInvoker<T> initInvoker, EventInvoker<T> destroyInvoker, Injector<T>[] callbackInjectors) { this.instance = instance; this.initInvoker = initInvoker; this.destroyInvoker = destroyInvoker; + this.callbackInjectors = callbackInjectors; } public T getInstance() { @@ -61,4 +64,9 @@ public class ReflectiveInstanceWrapper<T> implements InstanceWrapper<T> { destroyInvoker.invokeEvent(instance); } } + + public Injector<T>[] getCallbackInjectors() { + return this.callbackInjectors; + } + } diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java index de810a0f02..97b7570faa 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaAsyncImplementationInvoker.java @@ -21,12 +21,12 @@ package org.apache.tuscany.sca.implementation.java.invocation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.concurrent.TimeUnit; import org.apache.tuscany.sca.core.factory.InstanceWrapper; import org.apache.tuscany.sca.core.factory.ObjectCreationException; import org.apache.tuscany.sca.core.invocation.AsyncResponseException; import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.interfacedef.java.JavaOperation; import org.apache.tuscany.sca.invocation.Message; @@ -41,8 +41,9 @@ import org.oasisopen.sca.ServiceRuntimeException; */ public class JavaAsyncImplementationInvoker extends JavaImplementationInvoker { - public JavaAsyncImplementationInvoker(Operation operation, Method method, RuntimeComponent component) { - super( operation, method, component); + public JavaAsyncImplementationInvoker(Operation operation, Method method, RuntimeComponent component, + InterfaceContract interfaceContract) { + super( operation, method, component, interfaceContract); assert method != null : "Operation method cannot be null"; assert ((JavaOperation) operation).isAsyncServer() : "Operation must be async"; } // end constructor diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java index ea9aec5238..1fa51315c3 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java @@ -52,10 +52,13 @@ import org.apache.tuscany.sca.core.scope.TargetResolutionException; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl; import org.apache.tuscany.sca.implementation.java.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; import org.apache.tuscany.sca.implementation.java.JavaResourceImpl; +import org.apache.tuscany.sca.implementation.java.JavaScopeImpl; import org.apache.tuscany.sca.implementation.java.context.InstanceFactory; import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.interfacedef.java.JavaOperation; import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; @@ -76,6 +79,7 @@ public class JavaComponentContextProvider { private JavaInstanceFactoryProvider<?> instanceFactoryProvider; private ProxyFactory proxyFactory; private InstanceFactory instanceFactory; + private JavaScopeImpl scope; public JavaComponentContextProvider(RuntimeComponent component, JavaInstanceFactoryProvider configuration, @@ -93,6 +97,7 @@ public class JavaComponentContextProvider { // } this.component = component; this.propertyValueFactory = (JavaPropertyValueObjectFactory) propertyValueObjectFactory; + this.scope = ((JavaImplementation)component.getImplementation()).getJavaScope(); } InstanceWrapper<?> createInstanceWrapper() throws ObjectCreationException { @@ -144,6 +149,16 @@ public class JavaComponentContextProvider { } void start() { + List<JavaElementImpl> callbackInjectionList = null; + + // If the component implementation is stateless, we need to inject the callbacks on service invocation + // rather than doing it once at the component level. + if ( scope.equals(JavaScopeImpl.STATELESS)) { + callbackInjectionList = instanceFactoryProvider.getCallbackInjectionSites(); + } else { + callbackInjectionList = instanceFactoryProvider.getInjectionSites(); + } + if (!instanceFactoryProvider.getImplementation().getCallbackMembers().isEmpty()) { Map<String, List<EndpointReference>> callbackWires = new HashMap<String, List<EndpointReference>>(); for (ComponentService service : component.getServices()) { @@ -179,7 +194,7 @@ public class JavaComponentContextProvider { factory = new CallbackWireObjectFactory(businessInterface, proxyFactory, wires); } if (!(element.getAnchor() instanceof Constructor)) { - instanceFactoryProvider.getInjectionSites().add(element); + callbackInjectionList.add(element); } instanceFactoryProvider.setObjectFactory(element, factory); } @@ -288,15 +303,15 @@ public class JavaComponentContextProvider { //cleanUpPolicyHandlers(); } - Invoker createInvoker(Operation operation) throws NoSuchMethodException { + Invoker createInvoker(Operation operation, InterfaceContract interfaceContract) throws NoSuchMethodException { Class<?> implClass = instanceFactoryProvider.getImplementationClass(); Method method = JavaInterfaceUtil.findMethod(implClass, operation); if (operation instanceof JavaOperation && ((JavaOperation) operation).isAsyncServer() ) { - return new JavaAsyncImplementationInvoker(operation, method, component); + return new JavaAsyncImplementationInvoker(operation, method, component, interfaceContract); } else { - return new JavaImplementationInvoker(operation, method, component); + return new JavaImplementationInvoker(operation, method, component, interfaceContract); } // end if } // end diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java index 4d54fbd46c..13fcfbf413 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java @@ -22,17 +22,23 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.tuscany.sca.assembly.EndpointReference; -import org.apache.tuscany.sca.core.factory.InstanceWrapper; import org.apache.tuscany.sca.core.factory.ObjectCreationException; +import org.apache.tuscany.sca.core.scope.Scope; import org.apache.tuscany.sca.core.scope.ScopeContainer; import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent; import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.context.ReflectiveInstanceWrapper; +import org.apache.tuscany.sca.implementation.java.injection.Injector; +import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper; import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.oasisopen.sca.ServiceReference; import org.oasisopen.sca.ServiceRuntimeException; /** @@ -48,19 +54,22 @@ public class JavaImplementationInvoker implements Invoker { @SuppressWarnings("unchecked") protected final ScopeContainer scopeContainer; + private final InterfaceContract interfaze; - public JavaImplementationInvoker(Operation operation, Method method, RuntimeComponent component) { + public JavaImplementationInvoker(Operation operation, Method method, RuntimeComponent component, InterfaceContract intf) { assert method != null : "Operation method cannot be null"; this.method = method; this.operation = operation; this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer(); this.allowsPBR = ((JavaImplementation)component.getImplementation()).isAllowsPassByReference(method); + this.interfaze = intf; } - public JavaImplementationInvoker(Operation operation, RuntimeComponent component) { + public JavaImplementationInvoker(Operation operation, RuntimeComponent component, InterfaceContract intf) { // used if the method can't be computed statically in advance this.operation = operation; this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer(); + this.interfaze = intf; } @SuppressWarnings("unchecked") @@ -83,8 +92,14 @@ public class JavaImplementationInvoker implements Invoker { try { // The following call might create a new conversation, as a result, the msg.getConversationID() might // return a new value - InstanceWrapper wrapper = scopeContainer.getWrapper(contextId); - + ReflectiveInstanceWrapper wrapper = (ReflectiveInstanceWrapper) scopeContainer.getWrapper(contextId); + + // If there is a callback interface and the implementation is stateless, we need to + // inject callbacks at invocation time. For Composite scope, this has already been done. + if (( interfaze.getCallbackInterface() != null ) && (scopeContainer.getScope().equals(Scope.STATELESS))){ + injectCallbacks(wrapper, (JavaInterface)interfaze.getCallbackInterface()); + } + Object instance = wrapper.getInstance(); // If the method couldn't be computed statically, or the instance being @@ -149,4 +164,29 @@ public class JavaImplementationInvoker implements Invoker { return msg; } + private void injectCallbacks(ReflectiveInstanceWrapper wrapper, + JavaInterface callbackInterface) { + + for (Injector injector : wrapper.getCallbackInjectors()) { + if (injector != null) { + try { + if (ServiceReference.class.isAssignableFrom(injector.getType())) { + Class<?> intf = JavaIntrospectionHelper.getBusinessInterface(injector.getType(), injector.getGenericType()); + if ( intf.isAssignableFrom(callbackInterface.getJavaClass())) { + injector.inject(wrapper.getInstance()); + } + } else if (injector.getType().isAssignableFrom(callbackInterface.getJavaClass())) { + injector.inject(wrapper.getInstance()); + } else { + injector.injectNull(wrapper.getInstance()); + } + } catch (Exception e) { + throw new ObjectCreationException("Exception invoking injector - " + e.getMessage(), e); + } + } + } + + } + + } diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java index 3cee156d76..d7abd021f6 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java @@ -118,7 +118,7 @@ public class JavaImplementationProvider implements ScopedImplementationProvider public Invoker createInvoker(RuntimeComponentService service, Operation operation) { try { - return componentContextProvider.createInvoker(operation); + return componentContextProvider.createInvoker(operation, service.getInterfaceContract()); } catch (NoSuchMethodException e) { // It's possible that the instance being invoked is a user-specified // callback object that isn't an instance of the component implementation @@ -132,12 +132,12 @@ public class JavaImplementationProvider implements ScopedImplementationProvider if (iface instanceof JavaInterface) { try { Method method = JavaInterfaceUtil.findMethod(((JavaInterface)iface).getJavaClass(), operation); - return new JavaImplementationInvoker(operation, method, componentContextProvider.getComponent()); + return new JavaImplementationInvoker(operation, method, componentContextProvider.getComponent(), service.getInterfaceContract()); } catch (NoSuchMethodException e1) { throw new IllegalArgumentException(e1); } } else { - return new JavaImplementationInvoker(operation, componentContextProvider.getComponent()); + return new JavaImplementationInvoker(operation, componentContextProvider.getComponent(), service.getInterfaceContract()); } } } diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java index 7fcfaad615..1f1f1eefdc 100644 --- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java +++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java @@ -57,6 +57,7 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T private final EventInvoker<T> initInvoker; private final EventInvoker<T> destroyInvoker; private final Map<JavaElementImpl, Object> factories = new HashMap<JavaElementImpl, Object>(); + private final List<JavaElementImpl> callbackInjectionSites; public JavaInstanceFactoryProvider(JavaImplementation definition) { this.definition = definition; @@ -65,6 +66,7 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T this.destroyInvoker = definition.getDestroyMethod() == null ? null : new MethodEventInvoker<T>(definition .getDestroyMethod()); injectionSites = new ArrayList<JavaElementImpl>(); + callbackInjectionSites = new ArrayList<JavaElementImpl>(); } ProxyFactory getProxyFactory() { @@ -85,12 +87,15 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T @SuppressWarnings("unchecked") public InstanceFactory<T> createFactory() { ObjectFactory<?>[] initArgs = getConstructorArgs(); - Injector<T>[] injectors = getInjectors(); + Injector<T>[] injectors = getInjectors(false); + Injector<T>[] callbackInjectors = getInjectors(true); return new ReflectiveInstanceFactory<T>((Constructor<T>)definition.getConstructor().getConstructor(), - initArgs, injectors, initInvoker, destroyInvoker); + initArgs, injectors, callbackInjectors, initInvoker, destroyInvoker); } - private ObjectFactory<?>[] getConstructorArgs() { + + + private ObjectFactory<?>[] getConstructorArgs() { JavaConstructorImpl<?> constructor = definition.getConstructor(); ObjectFactory<?>[] initArgs = new ObjectFactory<?>[constructor.getParameters().length]; for (int i = 0; i < initArgs.length; i++) { @@ -101,13 +106,21 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T return initArgs; } + + @SuppressWarnings("unchecked") - private Injector<T>[] getInjectors() { + private Injector<T>[] getInjectors(boolean callback) { + List<JavaElementImpl> sites = null; + if ( callback ) + sites = callbackInjectionSites; + else + sites = injectionSites; + // work around JDK1.5 issue with allocating generic arrays - Injector<T>[] injectors = new Injector[injectionSites.size()]; + Injector<T>[] injectors = new Injector[sites.size()]; int i = 0; - for (JavaElementImpl element : injectionSites) { + for (JavaElementImpl element : sites) { Object obj = factories.get(element); if (obj != null) { if (obj instanceof ObjectFactory) { @@ -172,6 +185,13 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T return injectionSites; } + /** + * @return the callbackInjectionSites + */ + public List<JavaElementImpl> getCallbackInjectionSites() { + return callbackInjectionSites; + } + /** * @return the factories */ @@ -179,4 +199,6 @@ public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T return factories; } + + } |