summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java')
-rw-r--r--sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java349
1 files changed, 349 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java b/sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java
new file mode 100644
index 0000000000..76c340fa0d
--- /dev/null
+++ b/sca-java-1.x/tags/1.0.1/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java
@@ -0,0 +1,349 @@
+/*
+ * 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.core.context;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.UUID;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.OptimizableBinding;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.SCABinding;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl;
+import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
+import org.apache.tuscany.sca.core.assembly.ReferenceParametersImpl;
+import org.apache.tuscany.sca.core.conversation.ConversationManager;
+import org.apache.tuscany.sca.core.conversation.ConversationState;
+import org.apache.tuscany.sca.core.conversation.ExtendedConversation;
+import org.apache.tuscany.sca.core.factory.ObjectCreationException;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
+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.Conversation;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Base class for implementations of service and callback references.
+ *
+ * @version $Rev$ $Date$
+ * @param <B> the type of the business interface
+ */
+public class CallableReferenceImpl<B> implements CallableReference<B>, Externalizable, ObjectFactory<B> {
+ protected transient CompositeActivator compositeActivator;
+ protected transient ProxyFactory proxyFactory;
+
+ protected transient Class<B> businessInterface;
+
+ // if the wire targets a conversational service this holds the conversation state
+ protected transient ConversationManager conversationManager;
+ protected transient ExtendedConversation conversation;
+ protected transient Object conversationID;
+ protected Object callbackID; // The callbackID should be serializable
+
+ protected transient RuntimeComponent component;
+ protected transient RuntimeComponentReference reference;
+ protected transient Binding binding;
+
+ protected String scdl;
+
+ protected CallableReferenceImpl() {
+ super();
+ }
+
+ protected CallableReferenceImpl(Class<B> businessInterface,
+ RuntimeComponent component,
+ RuntimeComponentReference reference,
+ Binding binding,
+ ProxyFactory proxyFactory,
+ CompositeActivator compositeActivator) {
+ this.proxyFactory = proxyFactory;
+ this.businessInterface = businessInterface;
+ this.component = component;
+ this.reference = reference;
+ this.binding = binding;
+ // FIXME: The SCA spec is not clear how we should handle multiplicty for CallableReference
+ if (this.binding == null) {
+ this.binding = this.reference.getBinding(SCABinding.class);
+ if (this.binding == null) {
+ this.binding = this.reference.getBindings().get(0);
+ }
+ }
+
+ // FIXME: Should we normalize the componentName/serviceName URI into an absolute SCA URI in the SCA binding?
+ // sca:component1/component11/component112/service1?
+ this.compositeActivator = compositeActivator;
+ this.conversationManager = this.compositeActivator.getConversationManager();
+ RuntimeWire wire = this.reference.getRuntimeWire(this.binding);
+ init(wire);
+ }
+
+ public CallableReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
+ this.proxyFactory = proxyFactory;
+ this.businessInterface = businessInterface;
+ bind(wire);
+ }
+
+ public RuntimeWire getRuntimeWire() {
+ if (reference != null) {
+ return reference.getRuntimeWire(binding);
+ } else {
+ return null;
+ }
+ }
+
+ protected void bind(RuntimeWire wire) {
+ if (wire != null) {
+ this.component = wire.getSource().getComponent();
+ this.reference = (RuntimeComponentReference)wire.getSource().getContract();
+ this.binding = wire.getSource().getBinding();
+ this.compositeActivator = ((ComponentContextImpl)component.getComponentContext()).getCompositeActivator();
+ this.conversationManager = this.compositeActivator.getConversationManager();
+ init(wire);
+ }
+ }
+
+ protected void init(RuntimeWire wire) {
+ EndpointReference target = wire.getTarget();
+
+ // look to see if the target is conversational and if so create a conversation
+ InterfaceContract contract = target.getInterfaceContract();
+ if (contract == null) {
+ contract = reference.getInterfaceContract();
+ }
+ Interface contractInterface = contract.getInterface();
+
+ if (contract.getCallbackInterface() != null) {
+ this.callbackID = createCallbackID();
+ }
+ }
+
+ public B getInstance() throws ObjectCreationException {
+ try {
+ resolve();
+ //FIXME Can't we just return a single proxy
+ return businessInterface.cast(proxyFactory.createProxy(this));
+ } catch (Exception e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+
+ public B getService() {
+ try {
+ return getInstance();
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public Class<B> getBusinessInterface() {
+ return businessInterface;
+ }
+
+ public boolean isConversational() {
+ return reference == null ? false : reference.getInterfaceContract().getInterface().isConversational();
+ }
+
+ public Conversation getConversation() {
+ if (conversation == null || conversation.getState() == ConversationState.ENDED) {
+ conversation = null;
+ }
+ return conversation;
+ }
+
+ public Object getCallbackID() {
+ return callbackID;
+ }
+
+ /**
+ * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+ */
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ this.scdl = in.readUTF();
+ }
+
+ /**
+ * @throws IOException
+ */
+ private synchronized void resolve() throws Exception {
+ if (scdl != null && component == null && reference == null) {
+ ComponentContextHelper componentContextHelper = ComponentContextHelper.getCurrentComponentContextHelper();
+ if (componentContextHelper != null) {
+ CompositeActivator currentActivator = ComponentContextHelper.getCurrentCompositeActivator();
+ this.compositeActivator = currentActivator;
+ this.conversationManager = this.compositeActivator.getConversationManager();
+ Component c = componentContextHelper.fromXML(scdl);
+ this.component = (RuntimeComponent)c;
+ currentActivator.configureComponentContext(this.component);
+ this.reference = (RuntimeComponentReference)c.getReferences().get(0);
+ this.reference.setComponent(this.component);
+ ReferenceParameters parameters = null;
+ for (Object ext : reference.getExtensions()) {
+ if (ext instanceof ReferenceParameters) {
+ parameters = (ReferenceParameters)ext;
+ break;
+ }
+ }
+ if (parameters != null) {
+ this.callbackID = parameters.getCallbackID();
+ this.conversationID = parameters.getConversationID();
+ }
+
+ for (Binding binding : reference.getBindings()) {
+ if (binding instanceof OptimizableBinding) {
+ String targetURI = binding.getURI();
+ int index = targetURI.lastIndexOf('/');
+ String serviceName = "";
+ if (index > -1) {
+ serviceName = targetURI.substring(index + 1);
+ targetURI = targetURI.substring(0, index);
+ }
+ Component targetComponet = compositeActivator.resolve(targetURI);
+ ComponentService targetService = null;
+ if (targetComponet != null) {
+ if ("".equals(serviceName)) {
+ targetService = ComponentContextHelper.getSingleService(targetComponet);
+ } else {
+ for (ComponentService service : targetComponet.getServices()) {
+ if (service.getName().equals(serviceName)) {
+ targetService = service;
+ break;
+ }
+ }
+ }
+ }
+ OptimizableBinding optimizableBinding = (OptimizableBinding)binding;
+ optimizableBinding.setTargetComponent(targetComponet);
+ optimizableBinding.setTargetComponentService(targetService);
+ if (targetService != null) {
+ for (Binding serviceBinding : targetService.getBindings()) {
+ if (serviceBinding.getClass() == binding.getClass()) {
+ optimizableBinding.setTargetBinding(serviceBinding);
+ break;
+ }
+ }
+ }
+ }
+ }
+ // FIXME: The SCA spec is not clear how we should handle multiplicty for CallableReference
+ if (binding == null) {
+ binding = reference.getBinding(SCABinding.class);
+ if (binding == null) {
+ binding = reference.getBindings().get(0);
+ }
+ }
+ Interface i = reference.getInterfaceContract().getInterface();
+ if (i instanceof JavaInterface) {
+ JavaInterface javaInterface = (JavaInterface)i;
+ if (javaInterface.isUnresolved()) {
+ javaInterface.setJavaClass(Thread.currentThread().getContextClassLoader()
+ .loadClass(javaInterface.getName()));
+ currentActivator.getJavaInterfaceFactory().createJavaInterface(javaInterface,
+ javaInterface.getJavaClass());
+ }
+ this.businessInterface = (Class<B>)javaInterface.getJavaClass();
+ }
+ this.proxyFactory = currentActivator.getProxyFactory();
+ }
+ }
+ }
+
+ /**
+ * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
+ */
+ public void writeExternal(ObjectOutput out) throws IOException {
+ try {
+ if (reference != null) {
+ ReferenceParameters parameters = new ReferenceParametersImpl();
+ parameters.setCallbackID(callbackID);
+ if (conversationID != null) {
+ parameters.setConversationID(conversationID);
+ } else {
+ parameters.setConversationID(null);
+ }
+ reference.getExtensions().add(parameters);
+ scdl =
+ ((CompositeActivatorImpl)compositeActivator).getComponentContextHelper()
+ .toXML(component, reference);
+ reference.getExtensions().remove(parameters);
+ }
+ out.writeUTF(scdl);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ /**
+ * Create a callback id
+ *
+ * @return the callback id
+ */
+ private String createCallbackID() {
+ return UUID.randomUUID().toString();
+ }
+
+ public void attachCallbackID(Object callbackID) {
+ this.callbackID = callbackID;
+ }
+
+ public void attachConversationID(Object conversationID) {
+ this.conversationID = conversationID;
+ }
+
+ public void attachConversation(ExtendedConversation conversation) {
+ this.conversation = conversation;
+ }
+
+
+ protected ReferenceParameters getReferenceParameters() {
+ ReferenceParameters parameters = new ReferenceParametersImpl();
+ parameters.setCallbackID(callbackID);
+ if (getConversation() != null) {
+ parameters.setConversationID(conversation.getConversationID());
+ }
+ return parameters;
+ }
+
+ public EndpointReference getEndpointReference() {
+ // Use the interface contract of the reference on the component type
+ Reference componentTypeRef = reference.getReference();
+ InterfaceContract sourceContract =
+ componentTypeRef == null ? reference.getInterfaceContract() : componentTypeRef.getInterfaceContract();
+ sourceContract = sourceContract.makeUnidirectional(false);
+ EndpointReference epr = new EndpointReferenceImpl(component, reference, binding, sourceContract);
+ ReferenceParameters parameters = getReferenceParameters();
+ epr.setReferenceParameters(parameters);
+ return epr;
+ }
+
+}