diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation')
15 files changed, 1625 insertions, 0 deletions
diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java new file mode 100644 index 0000000000..25c09231c5 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvocationException.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import org.apache.tuscany.sca.implementation.java.injection.InjectionRuntimeException; + +/** + * Denotes an error when invoking an event on an object + * + * @version $Rev$ $Date$ + */ +public class EventInvocationException extends InjectionRuntimeException { + private static final long serialVersionUID = 1480018831708211581L; + + public EventInvocationException() { + super(); + } + + public EventInvocationException(String message, Throwable cause) { + super(message, cause); + } + + public EventInvocationException(String message) { + super(message); + } + + public EventInvocationException(Throwable cause) { + super(cause); + } + +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java new file mode 100644 index 0000000000..e6ebb5abc3 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/EventInvoker.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +/** + * Performs an invocation on an instance + * + * @version $Rev$ $Date$ + */ +public interface EventInvoker<T> { + + /** + * Performs the invocation on a given instance + * + * @throws EventInvocationException + */ + void invokeEvent(T instance) throws EventInvocationException; +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java new file mode 100644 index 0000000000..135fde09ff --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/InvalidConversationSequenceException.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import org.apache.tuscany.sca.core.invocation.TargetInvocationException; + +/** + * Denotes an unknown operation sequence in a conversation + * + * @version $Rev$ $Date$ + */ +public class InvalidConversationSequenceException extends TargetInvocationException { + private static final long serialVersionUID = -5744028391493899147L; + + public InvalidConversationSequenceException() { + super(); + } + + public InvalidConversationSequenceException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidConversationSequenceException(String message) { + super(message); + } + + public InvalidConversationSequenceException(Throwable cause) { + super(cause); + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java new file mode 100644 index 0000000000..ef4e67d79a --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaCallbackRuntimeWireProcessor.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.core.invocation.CallbackInterfaceInterceptor; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.invocation.InvocationChain; +import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.runtime.EndpointReference; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.apache.tuscany.sca.runtime.RuntimeWireProcessor; + +/** + * @version $Rev$ $Date$ + */ +public class JavaCallbackRuntimeWireProcessor implements RuntimeWireProcessor { + private static final Logger logger = Logger.getLogger(JavaCallbackRuntimeWireProcessor.class.getName()); + private InterfaceContractMapper interfaceContractMapper; + private JavaInterfaceFactory javaInterfaceFactory; + + /** + * @param interfaceContractMapper + * @param javaInterfaceFactory + */ + public JavaCallbackRuntimeWireProcessor(InterfaceContractMapper interfaceContractMapper, + JavaInterfaceFactory javaInterfaceFactory) { + super(); + this.interfaceContractMapper = interfaceContractMapper; + this.javaInterfaceFactory = javaInterfaceFactory; + } + + public void process(RuntimeWire wire) { + addCallbackInterfaceInterceptors(wire); + } + + private void addCallbackInterfaceInterceptors(RuntimeWire wire) { + Contract contract = wire.getSource().getContract(); + if (!(contract instanceof RuntimeComponentReference)) { + return; + } + RuntimeComponent component = wire.getSource().getComponent(); + Implementation implementation = component.getImplementation(); + if (!(implementation instanceof JavaImplementation)) { + return; + } + JavaImplementation javaImpl = (JavaImplementation)implementation; + EndpointReference callbackEndpoint = wire.getSource().getCallbackEndpoint(); + if (callbackEndpoint != null) { + Interface iface = callbackEndpoint.getContract().getInterfaceContract().getInterface(); + if (!supportsCallbackInterface(iface, javaImpl)) { + // callback to this impl is not possible, so ensure a callback object is set + for (InvocationChain chain : wire.getInvocationChains()) { + chain.addInterceptor(Phase.REFERENCE, new CallbackInterfaceInterceptor()); + } + } + } + } + + private boolean supportsCallbackInterface(Interface iface, JavaImplementation impl) { + if (iface instanceof JavaInterface) { + Class<?> ifaceClass = ((JavaInterface)iface).getJavaClass(); + if (ifaceClass.isAssignableFrom(impl.getJavaClass())) { + return true; + } + } + try { + Interface implType = javaInterfaceFactory.createJavaInterface(impl.getJavaClass()); + // Ignore the remotable/conversational testing + implType.setRemotable(iface.isRemotable()); + implType.setConversational(iface.isConversational()); + return interfaceContractMapper.isCompatible(iface, implType); + } catch (InvalidInterfaceException e) { + logger.log(Level.WARNING, e.getMessage(), e); + return false; + } + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java new file mode 100644 index 0000000000..2903cc6fc8 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import org.apache.tuscany.sca.core.factory.ObjectCreationException; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.osoa.sca.ComponentContext; + +/** + * @version $Rev$ $Date$ + */ +public class JavaComponentContextFactory implements ObjectFactory<ComponentContext> { + private final JavaComponentContextProvider component; + + + public JavaComponentContextFactory(JavaComponentContextProvider component) { + this.component = component; + } + + + public ComponentContext getInstance() throws ObjectCreationException { + return component.getComponent().getComponentContext(); + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java new file mode 100644 index 0000000000..a0b802d541 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentContextProvider.java @@ -0,0 +1,401 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.lang.annotation.ElementType; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.context.ComponentContextFactory; +import org.apache.tuscany.sca.context.RequestContextFactory; +import org.apache.tuscany.sca.core.context.ComponentContextImpl; +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.core.factory.ObjectCreationException; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.core.invocation.CallableReferenceObjectFactory; +import org.apache.tuscany.sca.core.invocation.CallbackReferenceObjectFactory; +import org.apache.tuscany.sca.core.invocation.CallbackWireObjectFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.core.invocation.WireObjectFactory; +import org.apache.tuscany.sca.core.scope.ScopeContainer; +import org.apache.tuscany.sca.core.scope.TargetResolutionException; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.implementation.java.impl.JavaConstructorImpl; +import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.impl.JavaResourceImpl; +import org.apache.tuscany.sca.implementation.java.injection.ConversationIDObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.InvalidAccessorException; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.java.introspect.impl.JavaIntrospectionHelper; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.osoa.sca.CallableReference; +import org.osoa.sca.annotations.ConversationID; + +/** + * The runtime instantiation of Java component implementations + * + * @version $Rev$ $Date$ + */ +public class JavaComponentContextProvider { + private JavaPropertyValueObjectFactory propertyValueFactory; + private DataBindingExtensionPoint dataBindingRegistry; + private RuntimeComponent component; + private JavaInstanceFactoryProvider<?> instanceFactoryProvider; + private ProxyFactory proxyFactory; + + public JavaComponentContextProvider(RuntimeComponent component, + JavaInstanceFactoryProvider configuration, + DataBindingExtensionPoint dataBindingExtensionPoint, + JavaPropertyValueObjectFactory propertyValueObjectFactory, + ComponentContextFactory componentContextFactory, + RequestContextFactory requestContextFactory) { + super(); + this.instanceFactoryProvider = configuration; + this.proxyFactory = configuration.getProxyFactory(); + // if (componentContextFactory != null) { + // this.componentContext = componentContextFactory.createComponentContext(component, requestContextFactory); + // } else { + // this.componentContext = new ComponentContextImpl(this, requestContextFactory, this.proxyService); + // } + this.component = component; + this.dataBindingRegistry = dataBindingExtensionPoint; + this.propertyValueFactory = propertyValueObjectFactory; + } + + InstanceWrapper<?> createInstanceWrapper() throws ObjectCreationException { + return instanceFactoryProvider.createFactory().newInstance(); + } + + void configureProperties(List<ComponentProperty> definedProperties) { + for (ComponentProperty p : definedProperties) { + configureProperty(p); + } + } + + private void configureProperty(ComponentProperty configuredProperty) { + JavaElementImpl element = + instanceFactoryProvider.getImplementation().getPropertyMembers().get(configuredProperty.getName()); + + if (element != null && configuredProperty.getValue() != null) { + if (!(element.getAnchor() instanceof Constructor)) { + if(element.getElementType() == ElementType.FIELD) { + Field field = (Field)element.getAnchor(); + if(Modifier.isPublic(field.getModifiers())) { + instanceFactoryProvider.getInjectionSites().add(element); + } else if(field.getAnnotation(org.osoa.sca.annotations.Property.class) != null) { + instanceFactoryProvider.getInjectionSites().add(element); + } + } else { + instanceFactoryProvider.getInjectionSites().add(element); + } + } + + //Class propertyJavaType = JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType()); + ObjectFactory<?> propertyObjectFactory = + createPropertyValueFactory(configuredProperty, configuredProperty.getValue(), element); + instanceFactoryProvider.setObjectFactory(element, propertyObjectFactory); + + JavaConstructorImpl constructor = instanceFactoryProvider.getImplementation().getConstructor(); + for(JavaElementImpl p: constructor.getParameters()){ + if(element.getName().equals(p.getName())) { + instanceFactoryProvider.setObjectFactory(p, propertyObjectFactory); + } + } + } + } + + void start() { + if (!instanceFactoryProvider.getImplementation().getCallbackMembers().isEmpty()) { + Map<String, List<RuntimeWire>> callbackWires = new HashMap<String, List<RuntimeWire>>(); + for (ComponentService service : component.getServices()) { + + RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference(); + if (callbackReference != null) { + List<RuntimeWire> wires = callbackReference.getRuntimeWires(); + if (!wires.isEmpty()) { + callbackWires.put(wires.get(0).getSource().getInterfaceContract().getInterface().toString(), + wires); + } + } + } + + for (Map.Entry<String, Collection<JavaElementImpl>> entry : instanceFactoryProvider.getImplementation() + .getCallbackMembers().entrySet()) { + List<RuntimeWire> wires = callbackWires.get(entry.getKey()); + if (wires == null) { + // this can happen when there are no client wires to a + // component that has a callback + continue; + } + for(JavaElementImpl element : entry.getValue()) { + Class<?> businessInterface = element.getType(); + ObjectFactory<?> factory = null; + if (CallableReference.class.isAssignableFrom(element.getType())) { + businessInterface = + JavaIntrospectionHelper.getBusinessInterface(element.getType(), element.getGenericType()); + factory = + new CallbackReferenceObjectFactory(businessInterface, proxyFactory, wires); + } else { + factory = new CallbackWireObjectFactory(businessInterface, proxyFactory, wires); + } + if (!(element.getAnchor() instanceof Constructor)) { + instanceFactoryProvider.getInjectionSites().add(element); + } + instanceFactoryProvider.setObjectFactory(element, factory); + } + } + } + for (Reference ref : instanceFactoryProvider.getImplementation().getReferences()) { + JavaElementImpl element = + instanceFactoryProvider.getImplementation().getReferenceMembers().get(ref.getName()); + if (element != null) { + if (!(element.getAnchor() instanceof Constructor)) { + if(element.getElementType() == ElementType.FIELD) { + Field field = (Field)element.getAnchor(); + if(Modifier.isPublic(field.getModifiers())) { + instanceFactoryProvider.getInjectionSites().add(element); + } else if(field.getAnnotation(org.osoa.sca.annotations.Reference.class) != null) { + instanceFactoryProvider.getInjectionSites().add(element); + } + } else { + instanceFactoryProvider.getInjectionSites().add(element); + } + } + ComponentReference componentReference = null; + List<RuntimeWire> wireList = null; + for (ComponentReference reference : component.getReferences()) { + if (reference.getName().equals(ref.getName())) { + wireList = ((RuntimeComponentReference)reference).getRuntimeWires(); + componentReference = reference; + break; + } + } + if (ref.getMultiplicity() == Multiplicity.ONE_N || ref.getMultiplicity() == Multiplicity.ZERO_N) { + List<ObjectFactory<?>> factories = new ArrayList<ObjectFactory<?>>(); + Class<?> baseType = + JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType()); + for (int i = 0; i < wireList.size(); i++) { + ObjectFactory<?> factory = null; + if (CallableReference.class.isAssignableFrom(baseType)) { + Type callableRefType = JavaIntrospectionHelper.getParameterType(element.getGenericType()); + // Type businessType = JavaIntrospectionHelper.getParameterType(callableRefType); + Class<?> businessInterface = + JavaIntrospectionHelper.getBusinessInterface(baseType, callableRefType); + factory = + new CallableReferenceObjectFactory(businessInterface, component, + (RuntimeComponentReference)wireList.get(i) + .getSource().getContract(), wireList.get(i) + .getSource().getBinding()); + } else { + factory = createObjectFactory(baseType, wireList.get(i)); + } + factories.add(factory); + } + instanceFactoryProvider.setObjectFactories(element, factories); + JavaConstructorImpl constructor = instanceFactoryProvider.getImplementation().getConstructor(); + for(JavaElementImpl p: constructor.getParameters()){ + if(element.getName().equals(p.getName())) { + instanceFactoryProvider.setObjectFactories(p, factories); + } + } + } else { + if (wireList == null && ref.getMultiplicity() == Multiplicity.ONE_ONE) { + throw new IllegalStateException("Required reference is missing: " + ref.getName()); + } + if (wireList != null && !wireList.isEmpty()) { + ObjectFactory<?> factory = null; + if (CallableReference.class.isAssignableFrom(element.getType())) { + Class<?> businessInterface = + JavaIntrospectionHelper.getBusinessInterface(element.getType(), element + .getGenericType()); + factory = + new CallableReferenceObjectFactory(businessInterface, component, + (RuntimeComponentReference)componentReference, null); + } else { + factory = createObjectFactory(element.getType(), wireList.get(0)); + } + instanceFactoryProvider.setObjectFactory(element, factory); + JavaConstructorImpl constructor = instanceFactoryProvider.getImplementation().getConstructor(); + for(JavaElementImpl p: constructor.getParameters()){ + if(element.getName().equals(p.getName())) { + instanceFactoryProvider.setObjectFactory(p, factory); + } + } + } + } + } + } + + // We need to set the PropertyValueFactory on the ComponentContextImpl + // so the ComponentContext can "de-marshal" the property type to a value + // when the getProperty() method is called + ComponentContextImpl ccImpl = (ComponentContextImpl)component.getComponentContext(); + ccImpl.setPropertyValueFactory(propertyValueFactory); + + //setUpPolicyHandlers(); + } + + void addResourceFactory(String name, ObjectFactory<?> factory) { + JavaResourceImpl resource = instanceFactoryProvider.getImplementation().getResources().get(name); + + if (resource != null && !(resource.getElement().getAnchor() instanceof Constructor)) { + instanceFactoryProvider.getInjectionSites().add(resource.getElement()); + } + + instanceFactoryProvider.setObjectFactory(resource.getElement(), factory); + } + + void addConversationIDFactories(List<Member> names) { + ObjectFactory<String> factory = new ConversationIDObjectFactory(); + for (Member name : names) { + if (name instanceof Field) { + JavaElementImpl element = new JavaElementImpl((Field)name); + element.setClassifer(ConversationID.class); + instanceFactoryProvider.setObjectFactory(element, factory); + } else if (name instanceof Method) { + JavaElementImpl element = new JavaElementImpl((Method)name, 0); + element.setName(JavaIntrospectionHelper.toPropertyName(name.getName())); + element.setClassifer(ConversationID.class); + instanceFactoryProvider.setObjectFactory(element, factory); + } else { + throw new InvalidAccessorException("Member must be a field or method: " + name.getName()); + } + } + } + + Object createInstance() throws ObjectCreationException { + return createInstanceWrapper().getInstance(); + } + + JavaInstanceFactoryProvider<?> getInstanceFactoryProvider() { + return instanceFactoryProvider; + } + + void stop() { + //cleanUpPolicyHandlers(); + } + + Invoker createInvoker(Operation operation) throws NoSuchMethodException { + Class<?> implClass = instanceFactoryProvider.getImplementationClass(); + + Method method = JavaInterfaceUtil.findMethod(implClass, operation); + return new JavaImplementationInvoker(operation, method, component); + } + + private static class OptimizedObjectFactory<T> implements ObjectFactory<T> { + private ScopeContainer scopeContainer; + + public OptimizedObjectFactory(ScopeContainer scopeContainer) { + super(); + this.scopeContainer = scopeContainer; + } + + public T getInstance() throws ObjectCreationException { + try { + return (T)scopeContainer.getWrapper(null).getInstance(); + } catch (TargetResolutionException e) { + throw new ObjectCreationException(e); + } + } + + } + + private <B> ObjectFactory<B> createObjectFactory(Class<B> interfaze, RuntimeWire wire) { + // FIXME: [rfeng] Disable the optimization for new as it needs more discussions + /* + boolean conversational = wire.getSource().getInterfaceContract().getInterface().isConversational(); + Binding binding = wire.getSource().getBinding(); + // Check if it's wireable binding for optimization + if (!conversational && binding instanceof OptimizableBinding) { + OptimizableBinding optimizableBinding = (OptimizableBinding)binding; + Component component = optimizableBinding.getTargetComponent(); + if (component != null) { + Implementation implementation = component.getImplementation(); + // Check if the target component is java component + if (implementation instanceof JavaImplementation) { + JavaImplementation javaImplementation = (JavaImplementation)implementation; + if (interfaze.isAssignableFrom(javaImplementation.getJavaClass())) { + ScopedRuntimeComponent scopedComponent = (ScopedRuntimeComponent)component; + ScopeContainer scopeContainer = scopedComponent.getScopeContainer(); + Scope scope = scopeContainer.getScope(); + if (scope == Scope.COMPOSITE || scope == Scope.STATELESS || scope == Scope.SYSTEM) { + boolean optimizable = true; + for (InvocationChain chain : wire.getInvocationChains()) { + if (chain.getHeadInvoker() != chain.getTailInvoker()) { + optimizable = false; + break; + } + } + if (optimizable) { + return new OptimizedObjectFactory<B>(scopeContainer); + } + } + } + } + } + } + */ + return new WireObjectFactory<B>(interfaze, wire, proxyFactory); + } + + private ObjectFactory<?> createPropertyValueFactory(ComponentProperty property, + Object propertyValue, + JavaElementImpl javaElement) { + return propertyValueFactory.createValueFactory(property, propertyValue, javaElement); + } + + /** + * @return the component + */ + RuntimeComponent getComponent() { + return component; + } + + /*private void setUpPolicyHandlers() { + for (PolicyHandler policyHandler : policyHandlers.values()) { + policyHandler.setUp(component.getImplementation()); + } + } + + private void cleanUpPolicyHandlers() { + for (PolicyHandler policyHandler : policyHandlers.values() ) { + policyHandler.cleanUp(this); + } + }*/ + +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java new file mode 100644 index 0000000000..4a5ad98e5b --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaComponentNameFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import org.apache.tuscany.sca.core.factory.ObjectCreationException; +import org.apache.tuscany.sca.core.factory.ObjectFactory; + +/** + * @version $Rev$ $Date$ + */ +public class JavaComponentNameFactory implements ObjectFactory<String> { + private final JavaComponentContextProvider componentContextProvider; + + + public JavaComponentNameFactory(JavaComponentContextProvider component) { + this.componentContextProvider = component; + } + + + public String getInstance() throws ObjectCreationException { + String uri = componentContextProvider.getComponent().getURI(); + return uri.substring(uri.lastIndexOf('/')+1); + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java new file mode 100644 index 0000000000..9b5f64e6cc --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.sca.core.context.InstanceWrapper; +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.interfacedef.ConversationSequence; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.DataExchangeSemantics; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.EndpointReference; +import org.apache.tuscany.sca.runtime.ReferenceParameters; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.osoa.sca.ServiceRuntimeException; + +/** + * Responsible for synchronously dispatching an invocation to a Java component + * implementation instance + * + * @version $Rev$ $Date$ + */ +public class JavaImplementationInvoker implements Invoker, DataExchangeSemantics { + protected Operation operation; + protected Method method; + protected boolean allowsPBR; + + @SuppressWarnings("unchecked") + protected final ScopeContainer scopeContainer; + + public JavaImplementationInvoker(Operation operation, Method method, RuntimeComponent component) { + 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); + } + + @SuppressWarnings("unchecked") + public Message invoke(Message msg) { + Operation op = msg.getOperation(); + if (op == null) { + op = this.operation; + } + ConversationSequence sequence = op.getConversationSequence(); + Object payload = msg.getBody(); + + Object contextId = null; + + EndpointReference from = msg.getFrom(); + ReferenceParameters parameters = null; + if (from != null) { + parameters = from.getReferenceParameters(); + } + // check what sort of context is required + if (scopeContainer != null) { + Scope scope = scopeContainer.getScope(); + if (scope == Scope.REQUEST) { + contextId = Thread.currentThread(); + } else if (scope == Scope.CONVERSATION && parameters != null) { + contextId = parameters.getConversationID(); + } + } + + 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); + + // detects whether the scope container has created a conversation Id. This will + // happen in the case that the component has conversational scope but only the + // callback interface is conversational. Or in the callback case if the service interface + // is conversational and the callback interface isn't. If we are in this situation we need + // to get the contextId of this component and remove it after we have invoked the method on + // it. It is possible that the component instance will not go away when it is removed below + // because a callback conversation will still be holding a reference to it + boolean removeTemporaryConversationalComponentAfterCall = false; + if (parameters != null && (contextId == null) && (parameters.getConversationID() != null)) { + contextId = parameters.getConversationID(); + removeTemporaryConversationalComponentAfterCall = true; + } + + Object instance = wrapper.getInstance(); + Object ret; + if (payload != null && !payload.getClass().isArray()) { + ret = method.invoke(instance, payload); + } else { + ret = method.invoke(instance, (Object[])payload); + } + + scopeContainer.returnWrapper(wrapper, contextId); + + if ((sequence == ConversationSequence.CONVERSATION_END) || (removeTemporaryConversationalComponentAfterCall)) { + // if end conversation, or we have the special case where a conversational + // object was created to service the stateless half of a stateful component + scopeContainer.remove(contextId); + parameters.setConversationID(null); + } + msg.setBody(ret); + } catch (InvocationTargetException e) { + Throwable cause = e.getTargetException(); + boolean isChecked = false; + for (DataType<?> d : operation.getFaultTypes()) { + if (d.getPhysical().isInstance(cause)) { + isChecked = true; + msg.setFaultBody(cause); + break; + } + } + + + if (sequence != ConversationSequence.CONVERSATION_NONE ){ + try { +// // If the exception is not a business exception then end the conversation +// boolean businessException = false; +// +// for (DataType dataType : operation.getFaultTypes()){ +// if ((dataType.getPhysical() == e.getCause().getClass()) && +// (contextId != null) ){ +// businessException = true; +// break; +// } +// } + + if (!isChecked && contextId != null) { + scopeContainer.remove(contextId); + parameters.setConversationID(null); + } + } catch (Exception ex){ + // TODO - sure what the best course of action is here. We have + // a system exception in the middle of a business exception + } + } + if (!isChecked) { + if (cause instanceof RuntimeException) { + throw (RuntimeException)cause; + } + if (cause instanceof Error) { + throw (Error)cause; + } else { + throw new ServiceRuntimeException(cause.getMessage(), cause); + } + } + + } catch (Exception e) { + msg.setFaultBody(e); + } + return msg; + } + + public boolean allowsPassByReference() { + return allowsPBR; + } + +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java new file mode 100644 index 0000000000..5db13befb4 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProvider.java @@ -0,0 +1,183 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.context.ComponentContextFactory; +import org.apache.tuscany.sca.context.RequestContextFactory; +import org.apache.tuscany.sca.core.context.InstanceWrapper; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.core.scope.Scope; +import org.apache.tuscany.sca.core.scope.ScopedImplementationProvider; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.impl.JavaResourceImpl; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.RequestContextObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.ResourceHost; +import org.apache.tuscany.sca.implementation.java.injection.ResourceObjectFactory; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; +import org.osoa.sca.ComponentContext; +import org.osoa.sca.RequestContext; + +/** + * @version $Rev$ $Date$ + */ +public class JavaImplementationProvider implements ScopedImplementationProvider { + private JavaImplementation implementation; + private JavaComponentContextProvider componentContextProvider; + private RequestContextFactory requestContextFactory; + + public JavaImplementationProvider(RuntimeComponent component, + JavaImplementation implementation, + ProxyFactory proxyService, + DataBindingExtensionPoint dataBindingRegistry, + JavaPropertyValueObjectFactory propertyValueObjectFactory, + ComponentContextFactory componentContextFactory, + RequestContextFactory requestContextFactory, + Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassNames) { + super(); + this.implementation = implementation; + this.requestContextFactory = requestContextFactory; + this.implementation.setPolicyHandlerClassNames(policyHandlerClassNames); + + try { + JavaInstanceFactoryProvider configuration = new JavaInstanceFactoryProvider(implementation); + configuration.setProxyFactory(proxyService); + componentContextProvider = + new JavaComponentContextProvider(component, + configuration, + dataBindingRegistry, + propertyValueObjectFactory, + componentContextFactory, + requestContextFactory); + + Scope scope = getScope(); + + if (scope == Scope.SYSTEM || scope == Scope.COMPOSITE) { + // Nothing + } else { + // Check for conversational contract if conversational scope + if (scope == Scope.CONVERSATION) { + boolean hasConversationalContract = false; + for (Service serviceDef : implementation.getServices()) { + if (serviceDef.getInterfaceContract().getInterface().isConversational()) { + hasConversationalContract = true; + break; + } + } + if (!hasConversationalContract) { + String name = implementation.getJavaClass().getName(); + throw new NoConversationalContractException(name); + } + } + } + + if (implementation.getConversationIDMembers().size() > 0) { + componentContextProvider.addConversationIDFactories(implementation.getConversationIDMembers()); + } + + componentContextProvider.configureProperties(component.getProperties()); + handleResources(implementation, proxyService); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + } + + private void handleResources(JavaImplementation componentType, ProxyFactory proxyService) { + for (JavaResourceImpl resource : componentType.getResources().values()) { + String name = resource.getName(); + + ObjectFactory<?> objectFactory = + (ObjectFactory<?>)componentContextProvider.getInstanceFactoryProvider().getFactories().get(resource.getElement()); + if (objectFactory == null) { + Class<?> type = resource.getElement().getType(); + if (ComponentContext.class.equals(type)) { + objectFactory = new JavaComponentContextFactory(componentContextProvider); + } else if (RequestContext.class.equals(type)) { + objectFactory = new RequestContextObjectFactory(requestContextFactory, proxyService); + } else if (String.class.equals(type)) { + objectFactory = new JavaComponentNameFactory(componentContextProvider); + } else { + boolean optional = resource.isOptional(); + String mappedName = resource.getMappedName(); + objectFactory = createResourceObjectFactory(type, mappedName, optional, null); + } + } + componentContextProvider.addResourceFactory(name, objectFactory); + } + } + + private <T> ResourceObjectFactory<T> createResourceObjectFactory(Class<T> type, + String mappedName, + boolean optional, + ResourceHost host) { + return new ResourceObjectFactory<T>(type, mappedName, optional, host); + } + + public Invoker createInvoker(RuntimeComponentService service, Operation operation) { + try { + return componentContextProvider.createInvoker(operation); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(e); + } + } + + public boolean supportsOneWayInvocation() { + return false; + } + + public Scope getScope() { + return new Scope(implementation.getJavaScope().getScope()); + } + + public void start() { + componentContextProvider.start(); + } + + public void stop() { + componentContextProvider.stop(); + } + + public InstanceWrapper createInstanceWrapper() { + return componentContextProvider.createInstanceWrapper(); + } + + public boolean isEagerInit() { + return implementation.isEagerInit(); + } + + public long getMaxAge() { + return implementation.getMaxAge(); + } + + public long getMaxIdleTime() { + return implementation.getMaxIdleTime(); + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java new file mode 100644 index 0000000000..fd0fc94770 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationProviderFactory.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.context.ComponentContextFactory; +import org.apache.tuscany.sca.context.RequestContextFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * @version $Rev$ $Date$ + */ +public class JavaImplementationProviderFactory implements ImplementationProviderFactory<JavaImplementation> { + private JavaPropertyValueObjectFactory propertyValueObjectFactory; + private DataBindingExtensionPoint dataBindingRegistry; + private ProxyFactory proxyService; + private ComponentContextFactory componentContextFactory; + private RequestContextFactory requestContextFactory; + private Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassNames = null; + + public JavaImplementationProviderFactory(ProxyFactory proxyService, + DataBindingExtensionPoint dataBindingRegistry, + JavaPropertyValueObjectFactory propertyValueObjectFactory, + ComponentContextFactory componentContextFactory, + RequestContextFactory requestContextFactory, + Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassNames) { + super(); + this.proxyService = proxyService; + this.dataBindingRegistry = dataBindingRegistry; + this.propertyValueObjectFactory = propertyValueObjectFactory; + this.componentContextFactory = componentContextFactory; + this.requestContextFactory = requestContextFactory; + this.policyHandlerClassNames = policyHandlerClassNames; + } + + public ImplementationProvider createImplementationProvider(RuntimeComponent component, + JavaImplementation implementation) { + return new JavaImplementationProvider(component, + implementation, + proxyService, + dataBindingRegistry, + propertyValueObjectFactory, + componentContextFactory, + requestContextFactory, + policyHandlerClassNames); + } + + public Class<JavaImplementation> getModelType() { + return JavaImplementation.class; + } +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java new file mode 100644 index 0000000000..95a9f63688 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaInstanceFactoryProvider.java @@ -0,0 +1,183 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.lang.annotation.ElementType; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.implementation.java.JavaImplementation; +import org.apache.tuscany.sca.implementation.java.context.InstanceFactory; +import org.apache.tuscany.sca.implementation.java.context.InstanceFactoryProvider; +import org.apache.tuscany.sca.implementation.java.context.ReflectiveInstanceFactory; +import org.apache.tuscany.sca.implementation.java.impl.JavaConstructorImpl; +import org.apache.tuscany.sca.implementation.java.impl.JavaElementImpl; +import org.apache.tuscany.sca.implementation.java.injection.ArrayMultiplicityObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.FieldInjector; +import org.apache.tuscany.sca.implementation.java.injection.Injector; +import org.apache.tuscany.sca.implementation.java.injection.InvalidAccessorException; +import org.apache.tuscany.sca.implementation.java.injection.ListMultiplicityObjectFactory; +import org.apache.tuscany.sca.implementation.java.injection.MethodInjector; +import org.apache.tuscany.sca.implementation.java.introspect.impl.JavaIntrospectionHelper; + +/** + * Encapsulates configuration for a Java-based atomic component + * + * @version $Rev$ $Date$ + */ +public class JavaInstanceFactoryProvider<T> implements InstanceFactoryProvider<T> { + private JavaImplementation definition; + private ProxyFactory proxyService; + + private final List<JavaElementImpl> injectionSites; + private final EventInvoker<T> initInvoker; + private final EventInvoker<T> destroyInvoker; + private final Map<JavaElementImpl, Object> factories = new HashMap<JavaElementImpl, Object>(); + + public JavaInstanceFactoryProvider(JavaImplementation definition) { + this.definition = definition; + this.initInvoker = definition.getInitMethod() == null ? null : new MethodEventInvoker<T>(definition + .getInitMethod()); + this.destroyInvoker = definition.getDestroyMethod() == null ? null : new MethodEventInvoker<T>(definition + .getDestroyMethod()); + injectionSites = new ArrayList<JavaElementImpl>(); + } + + ProxyFactory getProxyFactory() { + return proxyService; + } + + void setProxyFactory(ProxyFactory proxyService) { + this.proxyService = proxyService; + } + + /** + * @return the definition + */ + JavaImplementation getImplementation() { + return definition; + } + + @SuppressWarnings("unchecked") + public InstanceFactory<T> createFactory() { + ObjectFactory<?>[] initArgs = getConstructorArgs(); + Injector<T>[] injectors = getInjectors(); + return new ReflectiveInstanceFactory<T>((Constructor<T>)definition.getConstructor().getConstructor(), + initArgs, injectors, initInvoker, destroyInvoker); + } + + private ObjectFactory<?>[] getConstructorArgs() { + JavaConstructorImpl<?> constructor = definition.getConstructor(); + ObjectFactory<?>[] initArgs = new ObjectFactory<?>[constructor.getParameters().length]; + for (int i = 0; i < initArgs.length; i++) { + ObjectFactory<?> factory = (ObjectFactory<?>)factories.get(constructor.getParameters()[i]); + assert factory != null; + initArgs[i] = factory; + } + return initArgs; + } + + @SuppressWarnings("unchecked") + private Injector<T>[] getInjectors() { + // work around JDK1.5 issue with allocating generic arrays + @SuppressWarnings("unchecked") + Injector<T>[] injectors = new Injector[injectionSites.size()]; + + int i = 0; + for (JavaElementImpl element : injectionSites) { + Object obj = factories.get(element); + if (obj != null) { + if (obj instanceof ObjectFactory) { + ObjectFactory<?> factory = (ObjectFactory<?>)obj; + Member member = (Member)element.getAnchor(); + if (element.getElementType() == ElementType.FIELD) { + injectors[i++] = new FieldInjector<T>((Field)member, factory); + } else if (element.getElementType() == ElementType.PARAMETER && member instanceof Method) { + injectors[i++] = new MethodInjector<T>((Method)member, factory); + } else if (member instanceof Constructor) { + // Ignore + } else { + throw new AssertionError(String.valueOf(element)); + } + } else { + injectors[i++] = createMultiplicityInjector(element, (List<ObjectFactory<?>>)obj); + } + } + } + return injectors; + } + + private Injector<T> createMultiplicityInjector(JavaElementImpl element, List<ObjectFactory<?>> factories) { + Class<?> interfaceType = JavaIntrospectionHelper.getBaseType(element.getType(), element.getGenericType()); + + if (element.getAnchor() instanceof Field) { + Field field = (Field)element.getAnchor(); + if (field.getType().isArray()) { + return new FieldInjector<T>(field, new ArrayMultiplicityObjectFactory(interfaceType, factories)); + } else { + return new FieldInjector<T>(field, new ListMultiplicityObjectFactory(factories)); + } + } else if (element.getAnchor() instanceof Method) { + Method method = (Method)element.getAnchor(); + if (method.getParameterTypes()[0].isArray()) { + return new MethodInjector<T>(method, new ArrayMultiplicityObjectFactory(interfaceType, factories)); + } else { + return new MethodInjector<T>(method, new ListMultiplicityObjectFactory(factories)); + } + } else { + throw new InvalidAccessorException("Member must be a field or method: " + element.getName()); + } + } + + @SuppressWarnings("unchecked") + public Class<T> getImplementationClass() { + return (Class<T>)definition.getJavaClass(); + } + + public void setObjectFactory(JavaElementImpl element, ObjectFactory<?> objectFactory) { + factories.put(element, objectFactory); + } + + public void setObjectFactories(JavaElementImpl element, List<ObjectFactory<?>> objectFactory) { + factories.put(element, objectFactory); + } + + /** + * @return the injectionSites + */ + List<JavaElementImpl> getInjectionSites() { + return injectionSites; + } + + /** + * @return the factories + */ + Map<JavaElementImpl, Object> getFactories() { + return factories; + } + +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java new file mode 100644 index 0000000000..ee3507ef80 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaPolicyHandlingRuntimeWireProcessor.java @@ -0,0 +1,126 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ConfiguredOperation;
+import org.apache.tuscany.sca.assembly.OperationsConfigurator;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.PolicySetAttachPoint;
+import org.apache.tuscany.sca.policy.util.PolicyHandler;
+import org.apache.tuscany.sca.policy.util.PolicyHandlerUtils;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+
+/**
+ * Processor to inject policy handling interceptor whenever PolicySets are specified in a Java Implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaPolicyHandlingRuntimeWireProcessor implements RuntimeWireProcessor {
+ private static final Logger logger = Logger.getLogger(JavaPolicyHandlingRuntimeWireProcessor.class.getName());
+
+ public JavaPolicyHandlingRuntimeWireProcessor() {
+ super();
+ }
+
+ public void process(RuntimeWire wire) {
+ /*Contract contract = wire.getSource().getContract();
+ if (!(contract instanceof RuntimeComponentReference)) {
+ return;
+ }*/
+
+ RuntimeComponent component = wire.getTarget().getComponent();
+ if (component != null && component.getImplementation() instanceof JavaImplementation) {
+ JavaImplementation javaImpl = (JavaImplementation)component.getImplementation();
+ if (javaImpl instanceof PolicySetAttachPoint) {
+ PolicyHandler policyHandler = null;
+ List<PolicyHandler> implPolicyHandlers = new ArrayList<PolicyHandler>();
+ PolicySetAttachPoint policiedImpl = (PolicySetAttachPoint)javaImpl;
+
+ try {
+ //for ( PolicySet policySet : policiedImpl.getPolicySets() ) {
+ for (PolicySet policySet : component.getPolicySets()) {
+ policyHandler =
+ PolicyHandlerUtils.findPolicyHandler(policySet, javaImpl.getPolicyHandlerClassNames());
+ if (policyHandler != null) {
+ policyHandler.setUp(javaImpl);
+ implPolicyHandlers.add(policyHandler);
+ } else {
+ //FIXME: to be removed after the PolicyHandler story has crystalized..
+ //maybe replace with exception then...
+ logger.warning("No PolicyHandler registered for PolicySet - " + policySet.getName());
+ }
+ }
+
+ List<PolicyHandler> applicablePolicyHandlers = null;
+ for (InvocationChain chain : wire.getInvocationChains()) {
+ applicablePolicyHandlers = new ArrayList<PolicyHandler>();
+ if (javaImpl instanceof OperationsConfigurator) {
+ String operationName = chain.getTargetOperation().getName();
+ OperationsConfigurator opConfigurator = (OperationsConfigurator)component;
+ for (ConfiguredOperation confOp : opConfigurator.getConfiguredOperations()) {
+ if (confOp.getName().equals(operationName)) {
+ for (PolicySet policySet : confOp.getPolicySets()) {
+ policyHandler =
+ PolicyHandlerUtils.findPolicyHandler(policySet, javaImpl
+ .getPolicyHandlerClassNames());
+ if (policyHandler != null) {
+ policyHandler.setUp(javaImpl);
+ applicablePolicyHandlers.add(policyHandler);
+ } else {
+ logger.warning("No PolicyHandler registered for " + policySet);
+ }
+ }
+ break;
+ }
+ }
+
+ //if no policies have been specified at the operation level then simply
+ //apply whatever is specified for the implementation level
+ if (applicablePolicyHandlers.isEmpty()) {
+ applicablePolicyHandlers = implPolicyHandlers;
+ }
+ }
+
+ if (!applicablePolicyHandlers.isEmpty()) {
+ String phase =
+ (wire.getSource().getContract() instanceof ComponentReference) ? Phase.REFERENCE_POLICY
+ : Phase.SERVICE_POLICY;
+
+ chain.addInterceptor(Phase.IMPLEMENTATION_POLICY, new PolicyHandlingInterceptor(chain.getTargetOperation(),
+ applicablePolicyHandlers));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+}
diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java new file mode 100644 index 0000000000..515a7c8a43 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/MethodEventInvoker.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.java.invocation; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + + +/** + * Performs an wire on a method of a given instance + * + * @version $Rev$ $Date$ + */ +public class MethodEventInvoker<T> implements EventInvoker<T> { + private final Method method; + + /** + * Instantiates an invoker for the given method + */ + public MethodEventInvoker(Method method) { + assert method != null; + this.method = method; + } + + public void invokeEvent(T instance) throws EventInvocationException { + try { + method.invoke(instance, (Object[]) null); + } catch (IllegalArgumentException e) { + String name = method.getName(); + throw new EventInvocationException("Exception thrown by event method [" + name + "]", e.getCause()); + } catch (IllegalAccessException e) { + String name = method.getName(); + throw new EventInvocationException("Method is not accessible [" + name + "]"); + } catch (InvocationTargetException e) { + String name = method.getName(); + throw new EventInvocationException("Exception thrown by event method [" + name + "]", e.getCause()); + } + } + +} diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java new file mode 100644 index 0000000000..a7b175cf9b --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/NoConversationalContractException.java @@ -0,0 +1,34 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+
+/**
+ * Raised when a component has conversational scope but no conversational contract
+ *
+ * @version $Rev: 487877 $ $Date: 2006-12-16 15:32:16 -0500 (Sat, 16 Dec 2006) $
+ */
+public class NoConversationalContractException extends Exception {
+
+ private static final long serialVersionUID = -1157790036638157539L;
+
+ public NoConversationalContractException(String message) {
+ super(message);
+ }
+}
diff --git a/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java new file mode 100644 index 0000000000..8c85b46c65 --- /dev/null +++ b/sandbox/axis2-1.4/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/PolicyHandlingInterceptor.java @@ -0,0 +1,74 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.java.invocation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.policy.util.PolicyHandler;
+
+/**
+ * An interceptor to invoke policy handlers before and after the invocation of operations on
+ * an implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicyHandlingInterceptor implements Interceptor {
+ private Invoker next;
+ private List<PolicyHandler> policyHandlers = null;
+ private Operation targetOperation = null;
+
+ public PolicyHandlingInterceptor(Operation targetOperation, List<PolicyHandler> policyHandlers) {
+ this.policyHandlers = policyHandlers;
+ this.targetOperation = targetOperation;
+ }
+
+ public Message invoke(Message msg) {
+ try {
+ applyPreInvocationPolicies(targetOperation, msg);
+ msg = next.invoke(msg);
+ } finally {
+ applyPostInvocationPolices(targetOperation, msg);
+ }
+ return msg;
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+ private void applyPreInvocationPolicies(Object... context) {
+ for (PolicyHandler policyHandler : policyHandlers) {
+ policyHandler.beforeInvoke(context);
+ }
+ }
+
+ private void applyPostInvocationPolices(Object... context) {
+ for ( int count = policyHandlers.size() - 1 ; count >= 0 ; --count) {
+ policyHandlers.get(count).afterInvoke(context);
+ }
+ }
+}
|