You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2007/09/11 19:45:49 UTC

svn commit: r574648 [2/3] - in /incubator/tuscany/java/sca: itest/references/src/main/java/org/apache/tuscany/sca/itest/references/ itest/references/src/main/resources/ itest/references/src/test/java/org/apache/tuscany/sca/itest/references/ modules/ass...

Copied: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParameterProcessor.java (from r573086, incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ReferenceParameterProcessor.java)
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParameterProcessor.java?p2=incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParameterProcessor.java&p1=incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ReferenceParameterProcessor.java&r1=573086&r2=574648&rev=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ReferenceParameterProcessor.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParameterProcessor.java Tue Sep 11 10:45:36 2007
@@ -17,7 +17,7 @@
  * under the License.    
  */
 
-package org.apache.tuscany.sca.core.context;
+package org.apache.tuscany.sca.core.assembly;
 
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
@@ -29,6 +29,7 @@
 import org.apache.tuscany.sca.contribution.service.ContributionReadException;
 import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
 import org.apache.tuscany.sca.contribution.service.ContributionWriteException;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
 
 /**
  * @version $Rev$ $Date$
@@ -48,8 +49,7 @@
      * @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#read(javax.xml.stream.XMLStreamReader)
      */
     public ReferenceParameters read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
-        ReferenceParameters parameters = new ReferenceParameters();
-        parameters.setComponentURI(reader.getAttributeValue(null, "componentURI"));
+        ReferenceParameters parameters = new ReferenceParametersImpl();
         parameters.setConversationID(reader.getAttributeValue(null, "conversationID"));
         parameters.setCallbackID(reader.getAttributeValue(null, "callbackID"));
         return parameters;
@@ -64,9 +64,6 @@
                                  REFERENCE_PARAMETERS.getLocalPart(),
                                  REFERENCE_PARAMETERS.getNamespaceURI());
         writer.writeNamespace(REFERENCE_PARAMETERS.getPrefix(), REFERENCE_PARAMETERS.getNamespaceURI());
-        if (model.getComponentURI() != null) {
-            writer.writeAttribute("componentURI", model.getComponentURI());
-        }
         if (model.getConversationID() != null) {
             writer.writeAttribute("conversationID", model.getConversationID().toString());
         }

Added: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java?rev=574648&view=auto
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java (added)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java Tue Sep 11 10:45:36 2007
@@ -0,0 +1,139 @@
+/*
+ * 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.assembly;
+
+import org.apache.tuscany.sca.runtime.EndpointReference;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReferenceParametersImpl implements ReferenceParameters {
+    private Object callbackID;
+    private Object conversationID;
+    private EndpointReference callbackReference;
+    private Object callbackObjectID;
+    
+    /**
+     * @return the callbackID
+     */
+    public Object getCallbackID() {
+        return callbackID;
+    }
+    /**
+     * @param callbackID the callbackID to set
+     */
+    public void setCallbackID(Object callbackID) {
+        this.callbackID = callbackID;
+    }
+    /**
+     * @return the conversationID
+     */
+    public Object getConversationID() {
+        return conversationID;
+    }
+    /**
+     * @param conversationID the conversationID to set
+     */
+    public void setConversationID(Object conversationID) {
+        this.conversationID = conversationID;
+    }
+
+    /**
+     * @see org.apache.tuscany.sca.runtime.ReferenceParameters#getCallbackReference()
+     */
+    public EndpointReference getCallbackReference() {
+        return callbackReference;
+    }
+    /**
+     * @see org.apache.tuscany.sca.runtime.ReferenceParameters#setCallback(java.lang.Object)
+     */
+    public void setCallbackReference(EndpointReference callback) {
+        this.callbackReference = callback;
+    }
+    
+    /**
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
+    /**
+     * @return the callbackObjectID
+     */
+    public Object getCallbackObjectID() {
+        return callbackObjectID;
+    }
+    /**
+     * @param callbackObjectID the callbackObjectID to set
+     */
+    public void setCallbackObjectID(Object callbackObjectID) {
+        this.callbackObjectID = callbackObjectID;
+    }
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((callbackID == null) ? 0 : callbackID.hashCode());
+        result = prime * result + ((callbackObjectID == null) ? 0 : callbackObjectID.hashCode());
+        result = prime * result + ((callbackReference == null) ? 0 : callbackReference.hashCode());
+        result = prime * result + ((conversationID == null) ? 0 : conversationID.hashCode());
+        return result;
+    }
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (!(obj instanceof ReferenceParametersImpl))
+            return false;
+        final ReferenceParametersImpl other = (ReferenceParametersImpl)obj;
+        if (callbackID == null) {
+            if (other.callbackID != null)
+                return false;
+        } else if (!callbackID.equals(other.callbackID))
+            return false;
+        if (callbackObjectID == null) {
+            if (other.callbackObjectID != null)
+                return false;
+        } else if (!callbackObjectID.equals(other.callbackObjectID))
+            return false;
+        if (callbackReference == null) {
+            if (other.callbackReference != null)
+                return false;
+        } else if (!callbackReference.equals(other.callbackReference))
+            return false;
+        if (conversationID == null) {
+            if (other.conversationID != null)
+                return false;
+        } else if (!conversationID.equals(other.conversationID))
+            return false;
+        return true;
+    }
+}

Propchange: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/ReferenceParametersImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentReferenceImpl.java Tue Sep 11 10:45:36 2007
@@ -39,7 +39,6 @@
     private Map<Binding, ReferenceBindingProvider> bindingProviders = new HashMap<Binding, ReferenceBindingProvider>();
 
     private RuntimeComponent component;
-
     public RuntimeComponentReferenceImpl() {
         super();
     }
@@ -47,7 +46,7 @@
     public synchronized List<RuntimeWire> getRuntimeWires() {
         if (wires == null) {
             wires = new ArrayList<RuntimeWire>();
-            component.getComponentContext().activate(this);
+            component.getComponentContext().start(this);
         }
         return wires;
     }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeComponentServiceImpl.java Tue Sep 11 10:45:36 2007
@@ -39,7 +39,6 @@
     private List<RuntimeWire> wires = new ArrayList<RuntimeWire>();
     private List<RuntimeWire> callbackWires = new ArrayList<RuntimeWire>();
     private Map<Binding, ServiceBindingProvider> bindingProviders = new HashMap<Binding, ServiceBindingProvider>();
-
     public RuntimeComponentServiceImpl() {
         super();
     }
@@ -89,8 +88,10 @@
         }
         if (interfaceContract != null && interfaceContract != wire.getSource().getInterfaceContract()) {
             try {
+                // FIXME: [rfeng] We could avoid clone() using a better comparison of the two interface contracts
                 wire = (RuntimeWire)wire.clone();
                 wire.getSource().setInterfaceContract(interfaceContract);
+                wire.rebuild();
             } catch (CloneNotSupportedException e) {
                 throw new ServiceRuntimeException(e);
             }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java Tue Sep 11 10:45:36 2007
@@ -19,6 +19,7 @@
 
 package org.apache.tuscany.sca.core.assembly;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -29,11 +30,13 @@
 import org.apache.tuscany.sca.assembly.Contract;
 import org.apache.tuscany.sca.core.invocation.InvocationChainImpl;
 import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
+import org.apache.tuscany.sca.core.invocation.RuntimeWireInvoker;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
 import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.invocation.InvocationChain;
 import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.MessageFactory;
 import org.apache.tuscany.sca.provider.ImplementationProvider;
 import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
 import org.apache.tuscany.sca.provider.ReferenceBindingProvider2;
@@ -56,6 +59,8 @@
     private transient RuntimeWireProcessor wireProcessor;
     private transient InterfaceContractMapper interfaceContractMapper;
     private transient WorkScheduler workScheduler;
+    private transient MessageFactory messageFactory;
+    private transient RuntimeWireInvoker invoker;
 
     private List<InvocationChain> chains;
 
@@ -65,18 +70,22 @@
      * @param interfaceContractMapper 
      * @param workScheduler 
      * @param wireProcessor 
+     * @param messageFactory 
      */
     public RuntimeWireImpl(EndpointReference source,
                            EndpointReference target,
                            InterfaceContractMapper interfaceContractMapper,
                            WorkScheduler workScheduler,
-                           RuntimeWireProcessor wireProcessor) {
+                           RuntimeWireProcessor wireProcessor,
+                           MessageFactory messageFactory) {
         super();
         this.wireSource = source;
         this.wireTarget = target;
         this.interfaceContractMapper = interfaceContractMapper;
         this.workScheduler = workScheduler;
         this.wireProcessor = wireProcessor;
+        this.messageFactory = messageFactory;
+        this.invoker = new RuntimeWireInvoker(this.messageFactory, this);
     }
 
     public synchronized List<InvocationChain> getInvocationChains() {
@@ -103,6 +112,10 @@
         return null;
     }
 
+    public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
+        return invoker.invoke(operation, args);
+    }
+
     /**
      * Initialize the invocation chains
      */
@@ -162,7 +175,13 @@
     }
 
     public void setTarget(EndpointReference target) {
+        if (this.wireTarget != target) {
+            rebuild();
+        }
         this.wireTarget = target;
+    }
+
+    public void rebuild() {
         this.chains = null;
     }
 
@@ -247,7 +266,7 @@
         RuntimeWireImpl copy = (RuntimeWireImpl)super.clone();
         copy.wireSource = (EndpointReference)wireSource.clone();
         copy.wireTarget = (EndpointReference)wireTarget.clone();
-        copy.chains = null;
+        copy.invoker = new RuntimeWireInvoker(copy.messageFactory, copy);
         return copy;
     }
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java Tue Sep 11 10:45:36 2007
@@ -22,17 +22,18 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.net.URI;
 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.Reference;
 import org.apache.tuscany.sca.assembly.SCABinding;
 import org.apache.tuscany.sca.assembly.WireableBinding;
 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.factory.ObjectCreationException;
 import org.apache.tuscany.sca.core.factory.ObjectFactory;
 import org.apache.tuscany.sca.core.invocation.ProxyFactory;
@@ -40,6 +41,7 @@
 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;
@@ -181,10 +183,6 @@
         return callbackID;
     }
 
-    public EndpointReference getEndpointReference() {
-        return new EndpointReferenceImpl(component, reference, binding, reference.getInterfaceContract());
-    }
-
     /**
      * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
      */
@@ -203,6 +201,7 @@
                 this.compositeActivator = currentActivator;
                 Component c = componentContextHelper.fromXML(scdl);
                 this.component = (RuntimeComponent)c;
+                this.componentURI = c.getURI();
                 currentActivator.configureComponentContext(this.component);
                 this.reference = (RuntimeComponentReference)c.getReferences().get(0);
                 this.reference.setComponent(this.component);
@@ -215,9 +214,8 @@
                 }
                 if (parameters != null) {
                     this.callbackID = parameters.getCallbackID();
-                    this.componentURI = parameters.getComponentURI();
-                    
-                    if (conversation != null){
+
+                    if (conversation != null) {
                         conversation.setConversationID(parameters.getConversationID());
                     }
                 }
@@ -227,7 +225,7 @@
                         String targetURI = binding.getURI();
                         int index = targetURI.lastIndexOf('/');
                         String serviceName = "";
-                        if (index > -1){
+                        if (index > -1) {
                             serviceName = targetURI.substring(index + 1);
                             targetURI = targetURI.substring(0, index);
                         }
@@ -286,18 +284,20 @@
      */
     public void writeExternal(ObjectOutput out) throws IOException {
         try {
-            ReferenceParameters parameters = new ReferenceParameters();
-            parameters.setCallbackID(callbackID);
-            parameters.setComponentURI(componentURI);
-            if (conversation != null){
-                parameters.setConversationID(conversation.getConversationID());
-            } else {
-                parameters.setConversationID(null);
+            if (reference != null) {
+                ReferenceParameters parameters = new ReferenceParametersImpl();
+                parameters.setCallbackID(callbackID);
+                if (conversation != null) {
+                    parameters.setConversationID(conversation.getConversationID());
+                } else {
+                    parameters.setConversationID(null);
+                }
+                reference.getExtensions().add(parameters);
+                scdl =
+                    ((CompositeActivatorImpl)compositeActivator).getComponentContextHelper()
+                        .toXML(component, reference);
+                reference.getExtensions().remove(parameters);
             }
-            reference.getExtensions().add(parameters);
-            String scdl =
-                ((CompositeActivatorImpl)compositeActivator).getComponentContextHelper().toXML(component, reference);
-            reference.getExtensions().remove(parameters);
             out.writeUTF(scdl);
         } catch (Exception e) {
             e.printStackTrace();
@@ -320,6 +320,27 @@
 
     public void attachConversationID(Object conversationID) {
         conversation.setConversationID(conversationID);
+    }
+
+    protected ReferenceParameters getReferenceParameters() {
+        ReferenceParameters parameters = new ReferenceParametersImpl();
+        parameters.setCallbackID(callbackID);
+        if (conversation != 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;
     }
 
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextHelper.java Tue Sep 11 10:45:36 2007
@@ -46,6 +46,7 @@
 import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
 import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
 import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.ReferenceParameterProcessor;
 import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
 import org.apache.tuscany.sca.interfacedef.Interface;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ComponentContextImpl.java Tue Sep 11 10:45:36 2007
@@ -97,7 +97,7 @@
         try {
             for (ComponentReference ref : component.getReferences()) {
                 if (referenceName.equals(ref.getName())) {
-                    return getServiceReference(businessInterface, (RuntimeComponentReference)ref);
+                    return getServiceReference(businessInterface, (RuntimeComponentReference)ref, null);
                 }
             }
             throw new ServiceRuntimeException("Reference not found: " + referenceName);
@@ -152,7 +152,7 @@
             RuntimeComponentReference ref =
                 (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
             ref.setComponent(component);
-            return getServiceReference(businessInterface, ref);
+            return getServiceReference(businessInterface, ref, null);
         } catch (Exception e) {
             throw new ServiceRuntimeException(e);
         }
@@ -173,7 +173,7 @@
      * @throws CloneNotSupportedException
      * @throws InvalidInterfaceException
      */
-    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, RuntimeComponentReference reference) {
+    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, RuntimeComponentReference reference, Binding binding) {
         try {
             RuntimeComponentReference ref = (RuntimeComponentReference)reference;
             InterfaceContract interfaceContract = reference.getInterfaceContract();
@@ -187,11 +187,11 @@
                 ref.setInterfaceContract(interfaceContract);
             }
             ref.setComponent(component);
-            return new ServiceReferenceImpl<B>(businessInterface, component, ref, proxyFactory, compositeActivator);
+            return new ServiceReferenceImpl<B>(businessInterface, component, ref, binding, proxyFactory, compositeActivator);
         } catch (Exception e) {
             throw new ServiceRuntimeException(e);
         }
-    }
+    }    
 
     /**
      * Bind a component reference to a component service
@@ -327,10 +327,10 @@
     }
 
     /**
-     * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#activate(org.apache.tuscany.sca.runtime.RuntimeComponentReference)
+     * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#start(org.apache.tuscany.sca.runtime.RuntimeComponentReference)
      */
-    public void activate(RuntimeComponentReference reference) {
-        compositeActivator.activate(component, reference);
+    public void start(RuntimeComponentReference reference) {
+        compositeActivator.start(component, reference);
     }
 
     /**

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ConversationImpl.java Tue Sep 11 10:45:36 2007
@@ -20,16 +20,27 @@
 
 import org.osoa.sca.Conversation;
 
-
 /**
  * Default implementation of a Conversation.
  *
  * @version $Rev: 557524 $ $Date: 2007-07-19 09:46:56 +0100 (Thu, 19 Jul 2007) $
  */
 public class ConversationImpl implements Conversation {
-    
+
     private Object conversationId;
 
+    /**
+     * @param conversationId
+     */
+    public ConversationImpl(Object conversationId) {
+        super();
+        this.conversationId = conversationId;
+    }
+
+    public ConversationImpl() {
+        super();
+    }
+
     public Object getConversationID() {
         return conversationId;
     }
@@ -37,8 +48,49 @@
     public void setConversationID(Object conversationId) {
         this.conversationId = conversationId;
     }
-    
+
     public void end() {
         conversationId = null;
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((conversationId == null) ? 0 : conversationId.hashCode());
+        return result;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof ConversationImpl)) {
+            return false;
+        }
+        final ConversationImpl other = (ConversationImpl)obj;
+        if (conversationId == null) {
+            if (other.conversationId != null) {
+                return false;
+            }
+        } else if (!conversationId.equals(other.conversationId)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Conversation (id=" + conversationId + ")";
     }
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/RequestContextImpl.java Tue Sep 11 10:45:36 2007
@@ -26,7 +26,9 @@
 import org.apache.tuscany.sca.core.invocation.ProxyFactory;
 import org.apache.tuscany.sca.core.invocation.ThreadMessageContext;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+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.apache.tuscany.sca.runtime.RuntimeComponentReference;
 import org.apache.tuscany.sca.runtime.RuntimeComponentService;
@@ -55,15 +57,17 @@
 
     @SuppressWarnings("unchecked")
     public <B> CallableReference<B> getServiceReference() {
+        Message msgContext = ThreadMessageContext.getMessageContext();
         // FIXME: [rfeng] Is this the service reference matching the caller side?
-        EndpointReference to = ThreadMessageContext.getMessageContext().getTo();
+        EndpointReference to = msgContext.getTo();
         RuntimeComponentService service = (RuntimeComponentService) to.getContract();
         RuntimeComponent component = (RuntimeComponent) to.getComponent();
         
         CallableReference<B> callableReference = component.getComponentContext().getCallableReference(null, component, service);
-        ((CallableReferenceImpl<B>) callableReference).attachCallbackID(ThreadMessageContext.getMessageContext().getCorrelationID());
+        ReferenceParameters parameters = msgContext.getTo().getReferenceParameters();
+        ((CallableReferenceImpl<B>) callableReference).attachCallbackID(parameters.getCallbackID());
         if (callableReference.getConversation() != null) {
-            ((CallableReferenceImpl<B>) callableReference).attachConversationID(ThreadMessageContext.getMessageContext().getConversationID());
+            ((CallableReferenceImpl<B>) callableReference).attachConversationID(parameters.getConversationID());
         }
         return callableReference;
     }
@@ -75,7 +79,8 @@
 
     @SuppressWarnings("unchecked")
     public <CB> CallableReference<CB> getCallbackReference() {
-        EndpointReference to = ThreadMessageContext.getMessageContext().getTo();
+        Message msgContext = ThreadMessageContext.getMessageContext();
+        EndpointReference to = msgContext.getTo();
         RuntimeComponentService service = (RuntimeComponentService) to.getContract();
         RuntimeComponentReference callbackReference = (RuntimeComponentReference)service.getCallbackReference();
         if (callbackReference == null) {
@@ -86,9 +91,10 @@
         List<RuntimeWire> wires = callbackReference.getRuntimeWires();
         CallbackWireObjectFactory factory = new CallbackWireObjectFactory(javaClass, proxyFactory, wires);
         factory.resolveTarget();
-        factory.attachCallbackID(ThreadMessageContext.getMessageContext().getCorrelationID());
+        ReferenceParameters parameters = msgContext.getTo().getReferenceParameters();
+        factory.attachCallbackID(parameters.getCallbackID());
         if (factory.getConversation() != null) {
-            factory.attachConversationID(ThreadMessageContext.getMessageContext().getConversationID());
+            factory.attachConversationID(parameters.getConversationID());
         }
         return factory;
     }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/ServiceReferenceImpl.java Tue Sep 11 10:45:36 2007
@@ -23,11 +23,12 @@
 import org.apache.tuscany.sca.assembly.Binding;
 import org.apache.tuscany.sca.core.assembly.CompositeActivator;
 import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+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.ServiceReference;
 
 /**
@@ -53,7 +54,7 @@
     public ServiceReferenceImpl(Class<B> businessInterface, RuntimeWire wire, ProxyFactory proxyFactory) {
         super(businessInterface, wire, proxyFactory);
     }
-    
+
     public ServiceReferenceImpl(Class<B> businessInterface,
                                 RuntimeComponent component,
                                 RuntimeComponentReference reference,
@@ -88,10 +89,9 @@
                 conversation.setConversationID(conversationID);
             }
         } else {
-            throw new IllegalStateException("Trying to set conversation id " + 
-                                            conversationID.toString() +
-                                            "on non conversational reference " + 
-                                            reference.getName());
+            throw new IllegalStateException("Trying to set conversation id " + conversationID.toString()
+                + "on non conversational reference "
+                + reference.getName());
         }
     }
 
@@ -107,7 +107,22 @@
         if (callback != null && !(callback instanceof CallableReference)) {
             //FIXME: need to check if callback object supports the callback interface
             // returned by reference.getInterfaceContract().getCallbackInterface()
-        }    
+        }
         this.callback = callback;
+    }
+
+    protected ReferenceParameters getReferenceParameters() {
+        ReferenceParameters parameters = super.getReferenceParameters();
+        if (callback != null) {
+            if (callback instanceof ServiceReference) {
+                EndpointReference callbackRef = ((CallableReferenceImpl)callback).getEndpointReference();
+                parameters.setCallbackReference(callbackRef);
+            } else {
+                EndpointReference callbackRef = getRuntimeWire().getSource().getCallbackEndpoint();
+                parameters.setCallbackReference(callbackRef);
+                parameters.setCallbackObjectID("java:"+System.identityHashCode(callback));
+            }
+        }
+        return parameters;
     }
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallableReferenceObjectFactory.java Tue Sep 11 10:45:36 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.tuscany.sca.core.invocation;
 
+import org.apache.tuscany.sca.assembly.Binding;
 import org.apache.tuscany.sca.core.factory.ObjectCreationException;
 import org.apache.tuscany.sca.core.factory.ObjectFactory;
 import org.apache.tuscany.sca.runtime.RuntimeComponent;
@@ -44,10 +45,12 @@
      */
     public CallableReferenceObjectFactory(Class<?> businessInterface,
                                           RuntimeComponent component,
-                                          RuntimeComponentReference reference) {
-        this.callableReference = component.getComponentContext().getServiceReference(businessInterface, reference);
+                                          RuntimeComponentReference reference,
+                                          Binding binding) {
+        this.callableReference =
+            component.getComponentContext().getServiceReference(businessInterface, reference, binding);
     }
-    
+
     public CallableReferenceObjectFactory(CallableReference<?> callableReference) {
         this.callableReference = callableReference;
     }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackInterfaceInterceptor.java Tue Sep 11 10:45:36 2007
@@ -21,9 +21,8 @@
 import org.apache.tuscany.sca.invocation.Interceptor;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
-import org.osoa.sca.CallableReference;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
 import org.osoa.sca.NoRegisteredCallbackException;
-import org.osoa.sca.ServiceReference;
 
 /**
  * An interceptor applied to the forward direction of a wire that ensures the callback target implements the required
@@ -38,8 +37,9 @@
     }
 
     public Message invoke(Message msg) {
-        CallableReference<?> callableReference = msg.getCallableReference();
-        if (callableReference instanceof ServiceReference && ((ServiceReference<?>)callableReference).getCallback() != null) {
+        ReferenceParameters parameters = msg.getTo().getReferenceParameters();
+        if (parameters.getCallbackObjectID() != null || parameters.getCallbackReference() != msg.getFrom()
+            .getCallbackEndpoint()) {
             return next.invoke(msg);
         } else {
             throw new NoRegisteredCallbackException("Callback target does not implement the callback interface");

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackWireObjectFactory.java Tue Sep 11 10:45:36 2007
@@ -30,6 +30,7 @@
 import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
 import org.apache.tuscany.sca.runtime.RuntimeComponentService;
 import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.ServiceRuntimeException;
 
 /**
  * Returns proxy instance for a wire callback
@@ -53,7 +54,7 @@
             //FIXME: need better exception
             throw new RuntimeException("No callback wire found for " + msgContext.getFrom().getURI());
         }
-        resolvedEndpoint = msgContext.getFrom();
+        this.resolvedEndpoint = getCallbackEndpoint(msgContext);
         bind(wire);
     }
 
@@ -62,6 +63,7 @@
         if (wire != null) {
             // wire and endpoint already resolved, so return a pre-wired proxy
             wire.setTarget(resolvedEndpoint);
+            wire.rebuild();
             return super.getInstance();
         } else {
             // wire not yet selected, so return a proxy that resolves the target dynamically
@@ -81,7 +83,11 @@
         // first choice is wire with matching destination endpoint
         for (RuntimeWire wire : wires) {
             if (from.getURI().equals(wire.getTarget().getURI())) {
-                return wire;
+                try {
+                    return (RuntimeWire)wire.clone();
+                } catch (CloneNotSupportedException e) {
+                    throw new ServiceRuntimeException(e);
+                }
             }
         }
 
@@ -118,15 +124,33 @@
         return null;
     }
 
+    /**
+     * @param msgContext
+     */
+    private static EndpointReference getCallbackEndpoint(Message msgContext) {
+        EndpointReference to = msgContext.getTo();
+        if (to == null) {
+            return null;
+        }
+        return to.getReferenceParameters().getCallbackReference();
+    }
+
     private static RuntimeWire cloneAndBind(Message msgContext, RuntimeWire wire) {
-        EndpointReference callback = msgContext.getFrom();
+        EndpointReference callback = getCallbackEndpoint(msgContext);
         if (callback != null && callback.getContract() != null) {
             try {
-                RuntimeComponentReference ref =
-                    bind((RuntimeComponentReference)wire.getSource().getContract(),
-                         callback.getComponent(),
-                         (RuntimeComponentService)callback.getContract());
-                return ref.getRuntimeWires().get(0);
+                RuntimeComponentReference ref = null;
+                if (callback.getContract() instanceof RuntimeComponentReference) {
+                    ref = (RuntimeComponentReference)callback.getContract();
+                    return ref.getRuntimeWire(callback.getBinding());
+                } else {
+                    ref =
+                        bind((RuntimeComponentReference)wire.getSource().getContract(),
+                             callback.getComponent(),
+                             (RuntimeComponentService)callback.getContract());
+
+                    return ref.getRuntimeWires().get(0);
+                }
             } catch (CloneNotSupportedException e) {
                 // will not happen
                 return null;
@@ -155,5 +179,5 @@
         }
         return ref;
     }
-    
+
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java Tue Sep 11 10:45:36 2007
@@ -20,7 +20,6 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.List;
 
 import org.apache.tuscany.sca.assembly.Binding;
 import org.apache.tuscany.sca.core.context.ConversationImpl;
@@ -29,8 +28,8 @@
 import org.apache.tuscany.sca.invocation.MessageFactory;
 import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
 import org.apache.tuscany.sca.runtime.RuntimeWire;
-import org.osoa.sca.CallableReference;
 import org.osoa.sca.NoRegisteredCallbackException;
+import org.osoa.sca.ServiceRuntimeException;
 
 /**
  * Responsible for dispatching to a callback through a wire. <p/> TODO cache
@@ -41,8 +40,7 @@
 public class JDKCallbackInvocationHandler extends JDKInvocationHandler {
     private static final long serialVersionUID = -3350283555825935609L;
 
-    public JDKCallbackInvocationHandler(MessageFactory messageFactory,
-                                        CallbackWireObjectFactory wireFactory) {
+    public JDKCallbackInvocationHandler(MessageFactory messageFactory, CallbackWireObjectFactory wireFactory) {
         super(messageFactory, wireFactory);
         this.fixedWire = false;
     }
@@ -50,14 +48,8 @@
     @Override
     @SuppressWarnings( {"unchecked"})
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
-            return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
-        } else if (method.getDeclaringClass().equals(Object.class) && "equals".equals(method.getName())) {
-            // TODO implement
-            throw new UnsupportedOperationException();
-        } else if (Object.class.equals(method.getDeclaringClass()) && "hashCode".equals(method.getName())) {
-            return hashCode();
-            // TODO beter hash algorithm
+        if (Object.class == method.getDeclaringClass()) {
+            return invokeObjectMethod(method, args);
         }
 
         // wire not pre-selected, so select a wire now to be used for the callback
@@ -65,13 +57,13 @@
         RuntimeWire wire = ((CallbackWireObjectFactory)callableReference).selectCallbackWire(msgContext);
         if (wire == null) {
             //FIXME: need better exception
-            throw new RuntimeException("No callback wire found for " + msgContext.getFrom().getURI());
+            throw new ServiceRuntimeException("No callback wire found for " + msgContext.getFrom().getURI());
         }
-        
+
         // set the conversational state based on the interface that
         // is specified for the reference that this wire belongs to
-        setConversational(wire);
-        
+        init(wire);
+
         // set the conversation id into the conversation object. This is
         // a special case for callbacks as, unless otherwise set manually,
         // the callback should use the same conversation id as was received
@@ -83,37 +75,36 @@
                 // will have been constructed yet
                 conversation = new ConversationImpl();
             }
-            
-            Object conversationId = conversation.getConversationID();
+
+            Object convID = conversation.getConversationID();
 
             // create a conversation id if one doesn't exist 
             // already, i.e. the conversation is just starting
-            if (conversationId == null) {
-                conversationId = msgContext.getConversationID();
-                conversation.setConversationID(conversationId);
-            } 
+            if (convID == null) {
+                conversationID = msgContext.getTo().getReferenceParameters().getConversationID();
+                conversation.setConversationID(conversationID);
+            }
         }
-        
-        callbackID = msgContext.getCorrelationID();
+
+        callbackID = msgContext.getTo().getReferenceParameters().getCallbackID();
         ((CallbackWireObjectFactory)callableReference).attachCallbackID(callbackID);
-        setEndpoint(msgContext.getFrom());
-        
-        
         
+        setEndpoint(msgContext.getFrom().getCallbackEndpoint());
+
         // need to set the endpoint on the binding also so that when the chains are created next
         // the sca binding can decide whether to provide local or remote invokers. 
         // TODO - there is a problem here though in that I'm setting a target on a 
         //        binding that may possibly be trying to point at two things in the multi threaded 
         //        case. Need to confirm the general model here and how the clone and bind part
         //        is intended to work
-        wire.getSource().getBinding().setURI(msgContext.getFrom().getURI());
-        
+        wire.getSource().getBinding().setURI(msgContext.getFrom().getCallbackEndpoint().getURI());
+
         // also need to set the target contract as it varies for the sca binding depending on 
         // whether it is local or remote
         RuntimeComponentReference ref = (RuntimeComponentReference)wire.getSource().getContract();
         Binding binding = wire.getSource().getBinding();
         wire.getTarget().setInterfaceContract(ref.getBindingProvider(binding).getBindingInterfaceContract());
-        
+
         //FIXME: can we use the same code as JDKInvocationHandler to select the chain? 
         InvocationChain chain = getInvocationChain(method, wire);
         if (chain == null) {

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java Tue Sep 11 10:45:36 2007
@@ -34,6 +34,8 @@
 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.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetResolutionException;
 import org.apache.tuscany.sca.interfacedef.ConversationSequence;
 import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.Interface;
@@ -44,10 +46,12 @@
 import org.apache.tuscany.sca.invocation.Message;
 import org.apache.tuscany.sca.invocation.MessageFactory;
 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.RuntimeWire;
 import org.osoa.sca.CallableReference;
 import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
 
 /**
  * @version $Rev$ $Date$
@@ -57,9 +61,10 @@
 
     protected boolean conversational;
     protected ConversationImpl conversation;
-    protected boolean conversationStarted;
+    // protected boolean conversationStarted;
     protected MessageFactory messageFactory;
     protected EndpointReference endpoint;
+    protected Object conversationID;
     protected Object callbackID;
     protected Object callbackObject;
     protected RuntimeWire wire;
@@ -73,7 +78,7 @@
         this.messageFactory = messageFactory;
         this.wire = wire;
         this.businessInterface = businessInterface;
-        setConversational(wire);
+        init(this.wire);
     }
 
     public JDKInvocationHandler(MessageFactory messageFactory, CallableReference<?> callableReference) {
@@ -85,15 +90,24 @@
             this.conversation = (ConversationImpl)callableReference.getConversation();
             this.wire = ((CallableReferenceImpl<?>)callableReference).getRuntimeWire();
             if (callableReference instanceof ServiceReference) {
+                this.conversationID = ((ServiceReference)callableReference).getConversationID();
                 this.callbackObject = ((ServiceReference)callableReference).getCallback();
             }
             if (wire != null) {
-                setConversational(wire);
+                init(wire);
             }
         }
     }
 
-    protected void setConversational(RuntimeWire wire) {
+    protected void init(RuntimeWire wire) {
+        if (wire != null) {
+            try {
+                // Clone the wire so that reference parameters can be changed
+                this.wire = (RuntimeWire)wire.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new ServiceRuntimeException(e);
+            }
+        }
         InterfaceContract contract = wire.getSource().getInterfaceContract();
         this.conversational = contract.getInterface().isConversational();
     }
@@ -103,8 +117,7 @@
             return invokeObjectMethod(method, args);
         }
         if (wire == null) {
-            //FIXME: need better exception
-            throw new RuntimeException("Destination for call is not known");
+            throw new ServiceRuntimeException("No runtime wire is available");
         }
         InvocationChain chain = getInvocationChain(method, wire);
         if (chain == null) {
@@ -118,10 +131,11 @@
     }
 
     /**
+     * Handle the methods on the Object.class
      * @param method
      * @param args
      */
-    private Object invokeObjectMethod(Method method, Object[] args) throws Throwable {
+    protected Object invokeObjectMethod(Method method, Object[] args) throws Throwable {
         String name = method.getName();
         if ("toString".equals(name)) {
             return "[Proxy - " + toString() + "]";
@@ -188,138 +202,150 @@
         return found;
     }
 
-    public void setEndpoint(EndpointReference endpoint) {
+    protected void setEndpoint(EndpointReference endpoint) {
         this.endpoint = endpoint;
     }
 
-    public void setCallbackID(Object callbackID) {
-        this.callbackID = callbackID;
-    }
-
     protected Object invoke(InvocationChain chain, Object[] args, RuntimeWire wire) throws Throwable {
 
-        Message msgContext = ThreadMessageContext.getMessageContext();
-        Object msgContextConversationId = msgContext.getConversationID();
-
         Message msg = messageFactory.createMessage();
-
-        // make sure that the conversation id is set so it can be put in the 
-        // outgoing messages.        
-        if (conversational) {
-            Object conversationId = conversation.getConversationID();
-
-            // create a conversation id if one doesn't exist 
-            // already, i.e. the conversation is just starting
-            // If this is a callback the conversation id will have been
-            // set to the conversation from the message context already
-            if (conversationId == null) {
-                // create a new conversation Id
-                conversationId = createConversationID();
-                conversation.setConversationID(conversationId);
-            }
-
-            msg.setConversationID(conversationId);
-            
-            // If we are passing out a callback target register the calling component instance against 
-            // this new conversation id so that stateful callbacks will be able to find it
-            // we don't check if the callback has conversation scope here as non-conversational
-            // scoped components still need to have the conversation ids on the calling reference set
-            // to null
-            if (wire.getSource().getCallbackEndpoint() != null && callbackObject == null) {
-                // the component instance will already registered by now so add another registration
-                ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
-
-                if (scopeContainer != null) {
-                    scopeContainer.addWrapperReference(msgContextConversationId, conversation);
-                }
-            }
+        msg.setFrom(wire.getSource());
+        if (endpoint != null) {
+            msg.setTo(endpoint);
+        } else {
+            msg.setTo(wire.getTarget());
         }
-        
         Invoker headInvoker = chain.getHeadInvoker();
-        msg.setCorrelationID(callbackID);
         Operation operation = chain.getTargetOperation();
         msg.setOperation(operation);
-        Interface contract = operation.getInterface();
-        if (contract != null && contract.isConversational()) {
-            ConversationSequence sequence = operation.getConversationSequence();
-            if (sequence == ConversationSequence.CONVERSATION_END) {
-                msg.setConversationSequence(ConversationSequence.CONVERSATION_END);
-                conversationStarted = false;
-            } else if (sequence == ConversationSequence.CONVERSATION_CONTINUE) {
-                if (conversationStarted) {
-                    msg.setConversationSequence(ConversationSequence.CONVERSATION_CONTINUE);
-                } else {
-                    conversationStarted = true;
-                    msg.setConversationSequence(ConversationSequence.CONVERSATION_START);
-                }
+        msg.setBody(args);
+
+        Message msgContext = ThreadMessageContext.getMessageContext();
+        Object currentConversationID = msgContext.getTo().getReferenceParameters().getConversationID();
+
+        conversationPreinvoke(msg, wire);
+        handleCallback(msg, wire, currentConversationID);
+        ThreadMessageContext.setMessageContext(msg);
+        try {
+            // dispatch the wire down the chain and get the response
+            Message resp = headInvoker.invoke(msg);
+            Object body = resp.getBody();
+            if (resp.isFault()) {
+                throw (Throwable)body;
             }
+            return body;
+        } finally {
+            conversationPostInvoke(wire, operation);
+            ThreadMessageContext.setMessageContext(msgContext);
         }
-        msg.setCallableReference(callableReference);
-        msg.setBody(args);
-        if (wire.getSource() != null) {
-            EndpointReference callbackEndpoint = wire.getSource().getCallbackEndpoint();
-            if (callbackEndpoint != null) {
-                if (callbackObject != null) {
-                    if (callbackObject instanceof ServiceReference) {
-                        msg.setFrom(((CallableReferenceImpl)callbackObject).getRuntimeWire().getTarget());
+    }
+
+    /**
+     * @param msg
+     * @param wire
+     * @param interfaze
+     * @throws TargetResolutionException
+     */
+    private void handleCallback(Message msg, RuntimeWire wire, Object currentConversationID)
+        throws TargetResolutionException {
+        ReferenceParameters parameters = msg.getTo().getReferenceParameters();
+        parameters.setCallbackID(callbackID);
+        if (wire.getSource() == null || wire.getSource().getCallbackEndpoint() == null) {
+            return;
+        }
+
+        parameters.setCallbackReference(wire.getSource().getCallbackEndpoint());
+
+        // If we are passing out a callback target
+        // register the calling component instance against this 
+        // new conversation id so that stateful callbacks will be
+        // able to find it
+        if (conversational && callbackObject == null) {
+            // the component instance is already registered
+            // so add another registration
+            ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
+
+            if (scopeContainer != null) {
+                scopeContainer.addWrapperReference(currentConversationID, conversation);
+            }
+        }
+
+        Interface interfaze = msg.getOperation().getInterface();
+        if (callbackObject != null) {
+            if (callbackObject instanceof ServiceReference) {
+                EndpointReference callbackRef = ((CallableReferenceImpl)callbackObject).getEndpointReference();
+                parameters.setCallbackReference(callbackRef);
+            } else {
+                parameters.setCallbackReference(wire.getSource().getCallbackEndpoint());
+                if (interfaze != null) {
+                    if (!interfaze.isConversational()) {
+                        throw new IllegalArgumentException(
+                                                           "Callback object for stateless callback is not a ServiceReference");
                     } else {
-                        if (contract != null) {
-                            if (!contract.isConversational()) {
-                                throw new IllegalArgumentException
-                                        ("Callback object for stateless callback is not a ServiceReference");
-                            } else {
-                                ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
-                                if (scopeContainer != null) {
-                                    InstanceWrapper<Object> wrapper = new CallbackObjectWrapper(callbackObject);
-                                    scopeContainer.registerWrapper(wrapper, conversation.getConversationID());
-                                }
-                                msg.setFrom(callbackEndpoint);
-                            }
+                        ScopeContainer scopeContainer = getConversationalScopeContainer(wire);
+                        if (scopeContainer != null) {
+                            InstanceWrapper wrapper = new CallbackObjectWrapper(callbackObject);
+                            scopeContainer.registerWrapper(wrapper, conversation.getConversationID());
                         }
+                        parameters.setCallbackObjectID("java:" + System.identityHashCode(callbackObject));
                     }
-                } else {
-                    msg.setFrom(callbackEndpoint);
                 }
             }
         }
-        if (endpoint != null) {
-            msg.setTo(endpoint);
-        } else {
-            msg.setTo(wire.getTarget());
+    }
+
+    /**
+     * Pre-invoke for the conversation handling
+     * @param msg
+     * @param wire
+     * @throws TargetResolutionException
+     */
+    private void conversationPreinvoke(Message msg, RuntimeWire wire) throws TargetResolutionException {
+        if (!conversational) {
+            // Not conversational or the conversation has been started
+            return;
         }
+        // make sure that the conversation id is set so it can be put in the 
+        // outgoing messages.        
+        Object convID = conversation.getConversationID();
 
-        ThreadMessageContext.setMessageContext(msg);
-        try {
-            // dispatch the wire down the chain and get the response
-            Message resp = headInvoker.invoke(msg);
-            Object body = resp.getBody();
-            
-            // Mark the object instance for removal if the conversation has ended
-            if (contract != null && contract.isConversational()) {
-                ConversationSequence sequence = operation.getConversationSequence();
-                if (sequence == ConversationSequence.CONVERSATION_END) {
-                    if (conversation != null) {
+        // create a conversation id if one doesn't exist 
+        // already, i.e. the conversation is just starting
+        // If this is a callback the conversation id will have been
+        // set to the conversation from the message context already
+        if (convID == null) {
+            // create a new conversation Id
+            convID = createConversationID();
+            conversation.setConversationID(convID);
+        }
+        // TODO - assuming that the conversation ID is a string here when
+        //       it can be any object that is serializable to XML
+        msg.getTo().getReferenceParameters().setConversationID(conversation.getConversationID());
+    }
 
-                        // remove conversation id from scope container
-                        ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
+    /**
+     * Post-invoke for the conversation handling
+     * @param wire
+     * @param operation
+     * @throws TargetDestructionException
+     */
+    private void conversationPostInvoke(RuntimeWire wire, Operation operation) throws TargetDestructionException {
+        ConversationSequence sequence = operation.getConversationSequence();
+        if (sequence == ConversationSequence.CONVERSATION_END) {
+            if (conversation != null) {
 
-                        if (scopeContainer != null) {
-                            scopeContainer.remove(conversation.getConversationID());
-                        }
+                // remove conversation id from scope container
+                ScopeContainer<Object> scopeContainer = getConversationalScopeContainer(wire);
 
-                        conversation.setConversationID(null);
-                    }
+                if (scopeContainer != null) {
+                    scopeContainer.remove(conversation.getConversationID());
+                }
+
+                if (conversation.getConversationID() != null) {
+                    conversation.end();
                 }
-            }               
-            
-            if (resp.isFault()) {
-                throw (Throwable)body;
             }
-            return body;
-        } finally {
-            ThreadMessageContext.setMessageContext(msgContext);
         }
-        
 
     }
 
@@ -345,8 +371,11 @@
      * 
      * @return the conversational id
      */
-    private String createConversationID() {
-        return UUID.randomUUID().toString();
+    private Object createConversationID() {
+        if (conversationID == null) {
+            return UUID.randomUUID().toString();
+        }
+        return conversationID;
     }
 
     /**
@@ -381,7 +410,7 @@
         public void start() {
             // do nothing
         }
-        
+
         public void stop() {
             // do nothing
         }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/MessageImpl.java Tue Sep 11 10:45:36 2007
@@ -18,11 +18,10 @@
  */
 package org.apache.tuscany.sca.core.invocation;
 
-import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.invocation.Message;
 import org.apache.tuscany.sca.runtime.EndpointReference;
-import org.osoa.sca.CallableReference;
 
 /**
  * The default implementation of a message flowed through a wire during an invocation
@@ -34,26 +33,20 @@
     private Object messageID;
     private Object correlationID;
     private boolean isFault;
-    private ConversationSequence conversationSequence;
-    private Object conversationId;
-    private Operation op;
-    private CallableReference<?> callableReference;
-    
+    private Operation operation;
+
     private EndpointReference from;
     private EndpointReference to;
-
-    public MessageImpl(String conversationId, ConversationSequence conversationSequence, Object body) {
-        this.conversationId = conversationId;
-        this.conversationSequence = conversationSequence;
-        this.body = body;
-    }
+    private EndpointReference replyTo;
 
     public MessageImpl() {
+        this.from = new EndpointReferenceImpl("/");
+        this.to = new EndpointReferenceImpl("/");
     }
 
     @SuppressWarnings("unchecked")
     public <T> T getBody() {
-        return (T) body;
+        return (T)body;
     }
 
     public <T> void setBody(T body) {
@@ -62,19 +55,11 @@
     }
 
     public Object getConversationID() {
-        return conversationId;
-    }
-
-    public void setConversationID(Object conversationId) {
-        this.conversationId = conversationId;
-    }
-    
-    public ConversationSequence getConversationSequence() {
-        return conversationSequence;
+        return getTo().getReferenceParameters().getConversationID();
     }
 
-    public void setConversationSequence(ConversationSequence conversationSequence) {
-        this.conversationSequence = conversationSequence;
+    public void setConversationID(Object conversationID) {
+        getTo().getReferenceParameters().setConversationID(conversationID);
     }
 
     public Object getMessageID() {
@@ -119,25 +104,25 @@
     }
 
     public Operation getOperation() {
-        return op;
+        return operation;
     }
 
     public void setOperation(Operation op) {
-        this.op = op;
+        this.operation = op;
     }
 
     /**
-     * @see org.apache.tuscany.sca.invocation.Message#getCallableReference()
+     * @return the replyTo
      */
-    public <B> CallableReference<B> getCallableReference() {
-        return (CallableReference<B>) callableReference;
+    public EndpointReference getReplyTo() {
+        return replyTo;
     }
 
     /**
-     * @see org.apache.tuscany.sca.invocation.Message#setCallableReference(org.osoa.sca.CallableReference)
+     * @param replyTo the replyTo to set
      */
-    public <B> void setCallableReference(CallableReference<B> callableReference) {
-        this.callableReference = callableReference;
+    public void setReplyTo(EndpointReference replyTo) {
+        this.replyTo = replyTo;
     }
 
 }

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/NonBlockingInterceptor.java Tue Sep 11 10:45:36 2007
@@ -20,7 +20,6 @@
 
 import java.util.LinkedList;
 
-import org.apache.tuscany.sca.interfacedef.ConversationSequence;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.invocation.Interceptor;
 import org.apache.tuscany.sca.invocation.Invoker;
@@ -28,7 +27,6 @@
 import org.apache.tuscany.sca.runtime.EndpointReference;
 import org.apache.tuscany.sca.runtime.RuntimeWire;
 import org.apache.tuscany.sca.work.WorkScheduler;
-import org.osoa.sca.CallableReference;
 import org.osoa.sca.ServiceRuntimeException;
 
 /**
@@ -143,14 +141,6 @@
             throw new UnsupportedOperationException();
         }
 
-        public void setConversationSequence(ConversationSequence sequence) {
-            throw new UnsupportedOperationException();
-        }
-        
-        public ConversationSequence getConversationSequence() {
-            return null;
-        }
-
         public EndpointReference getFrom() {
             return null;
         }
@@ -174,18 +164,18 @@
         public void setOperation(Operation op) {
             throw new UnsupportedOperationException();
         }
-        
+
         /**
-         * @see org.apache.tuscany.sca.invocation.Message#getCallableReference()
+         * @see org.apache.tuscany.sca.invocation.Message#getReplyTo()
          */
-        public <B> CallableReference<B> getCallableReference() {
+        public EndpointReference getReplyTo() {
             return null;
         }
 
         /**
-         * @see org.apache.tuscany.sca.invocation.Message#setCallableReference(org.osoa.sca.CallableReference)
+         * @see org.apache.tuscany.sca.invocation.Message#setReplyTo(org.apache.tuscany.sca.runtime.EndpointReference)
          */
-        public <B> void setCallableReference(CallableReference<B> callableReference) {
+        public void setReplyTo(EndpointReference replyTo) {
             throw new UnsupportedOperationException();
         }
 

Added: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java?rev=574648&view=auto
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java (added)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java Tue Sep 11 10:45:36 2007
@@ -0,0 +1,315 @@
+/*
+ * 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.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.UUID;
+
+import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
+import org.apache.tuscany.sca.core.context.ConversationImpl;
+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.core.scope.TargetDestructionException;
+import org.apache.tuscany.sca.core.scope.TargetResolutionException;
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+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.RuntimeWire;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RuntimeWireInvoker {
+    protected boolean conversational;
+    protected ConversationImpl conversation;
+    protected boolean conversationStarted;
+    protected MessageFactory messageFactory;
+    protected EndpointReference endpoint;
+    protected Object conversationID;
+    protected Object callbackID;
+    protected Object callbackObject;
+    protected RuntimeWire wire;
+
+    public RuntimeWireInvoker(MessageFactory messageFactory, RuntimeWire wire) {
+        this.messageFactory = messageFactory;
+        this.wire = wire;
+        init(wire);
+    }
+
+    protected void init(RuntimeWire wire) {
+        ReferenceParameters parameters = wire.getSource().getReferenceParameters();
+        this.callbackID = parameters.getCallbackID();
+        this.callbackObject = parameters.getCallbackReference();
+        this.conversationID = parameters.getConversationID();
+        InterfaceContract contract = wire.getSource().getInterfaceContract();
+        this.conversational = contract.getInterface().isConversational();
+    }
+
+    public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
+        return invoke(wire, operation, args);
+    }
+
+    public Object invoke(RuntimeWire wire, Operation operation, Object[] args) throws InvocationTargetException {
+        RuntimeWire runtimeWire = wire == null ? this.wire : wire;
+        InvocationChain chain = runtimeWire.getInvocationChain(operation);
+        return invoke(chain, args, runtimeWire);
+    }
+
+    protected Object invoke(InvocationChain chain, Object[] args, RuntimeWire wire) throws InvocationTargetException {
+
+        Message msg = messageFactory.createMessage();
+        msg.setFrom(wire.getSource());
+        if (endpoint != null) {
+            msg.setTo(endpoint);
+        } else {
+            msg.setTo(wire.getTarget());
+        }
+        Invoker headInvoker = chain.getHeadInvoker();
+        Operation operation = chain.getTargetOperation();
+        msg.setOperation(operation);
+        msg.setBody(args);
+
+        Message msgContext = ThreadMessageContext.getMessageContext();
+        Object currentConversationID = msgContext.getTo().getReferenceParameters().getConversationID();
+
+        ThreadMessageContext.setMessageContext(msg);
+        try {
+            conversationPreinvoke(msg);
+            handleCallback(msg, currentConversationID);
+            // dispatch the wire down the chain and get the response
+            Message resp = headInvoker.invoke(msg);
+            Object body = resp.getBody();
+            if (resp.isFault()) {
+                throw new InvocationTargetException((Throwable)body);
+            }
+            return body;
+        } catch (InvocationTargetException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ServiceRuntimeException(e);
+        } finally {
+            try {
+                conversationPostInvoke(msg);
+            } catch (TargetDestructionException e) {
+                throw new ServiceRuntimeException(e);
+            } finally {
+                ThreadMessageContext.setMessageContext(msgContext);
+            }
+        }
+    }
+
+    /**
+     * @param msgContext
+     */
+    protected EndpointReference getCallbackEndpoint(Message msgContext) {
+        EndpointReference to = msgContext.getTo();
+        return to == null ? null : to.getReferenceParameters().getCallbackReference();
+    }
+
+    /**
+     * @param msg
+     * @param wire
+     * @param interfaze
+     * @throws TargetResolutionException
+     */
+    @SuppressWarnings("unchecked")
+    private void handleCallback(Message msg, Object currentConversationID) throws TargetResolutionException {
+        EndpointReference from = msg.getFrom();
+        EndpointReference to = msg.getTo();
+        msg.getTo().getReferenceParameters().setCallbackID(callbackID);
+        if (from == null || from.getCallbackEndpoint() == null) {
+            return;
+        }
+        // If we are passing out a callback target
+        // register the calling component instance against this 
+        // new conversation id so that stateful callbacks will be
+        // able to find it
+        if (conversational && callbackObject == null) {
+            // the component instance is already registered
+            // so add another registration
+            ScopeContainer scopeContainer = getConversationalScopeContainer(msg);
+
+            if (scopeContainer != null) {
+                scopeContainer.addWrapperReference(currentConversationID, to.getReferenceParameters()
+                    .getConversationID());
+            }
+        }
+
+        ReferenceParameters parameters = msg.getTo().getReferenceParameters();
+        Interface interfaze = msg.getOperation().getInterface();
+        if (callbackObject != null) {
+            if (callbackObject instanceof ServiceReference) {
+                EndpointReference callbackRef = ((CallableReferenceImpl)callbackObject).getEndpointReference();
+                parameters.setCallbackReference(callbackRef);
+            } else {
+                parameters.setCallbackReference(wire.getSource().getCallbackEndpoint());
+                if (interfaze != null) {
+                    if (!interfaze.isConversational()) {
+                        throw new IllegalArgumentException(
+                                                           "Callback object for stateless callback is not a ServiceReference");
+                    } else {
+                        ScopeContainer scopeContainer = getConversationalScopeContainer(msg);
+                        if (scopeContainer != null) {
+                            InstanceWrapper wrapper = new CallbackObjectWrapper(callbackObject);
+                            scopeContainer.registerWrapper(wrapper, conversation.getConversationID());
+                        }
+                        parameters.setCallbackObjectID("java:" + System.identityHashCode(callbackObject));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Pre-invoke for the conversation handling
+     * @param msg
+     * @param wire
+     * @throws TargetResolutionException
+     */
+    private void conversationPreinvoke(Message msg) throws TargetResolutionException {
+        if (!conversational) {
+            // Not conversational or the conversation has been started
+            return;
+        }
+        if (!conversationStarted) {
+            // make sure that the conversation id is set so it can be put in the 
+            // outgoing messages.        
+            if (conversation == null) {
+                // this call is via an automatic proxy rather than a
+                // callable/service reference so no conversation object 
+                // will have been constructed yet
+                conversation = new ConversationImpl();
+            }
+
+            Object convID = conversation.getConversationID();
+
+            // create a conversation id if one doesn't exist 
+            // already, i.e. the conversation is just starting
+            // If this is a callback the conversation id will have been
+            // set to the conversation from the message context already
+            if (convID == null) {
+                // create a new conversation Id
+                convID = createConversationID();
+
+                // we have just created a new conversation Id so 
+                // put it back in the conversation object
+                conversation.setConversationID(convID);
+            }
+            conversationStarted = true;
+        }
+        // TODO - assuming that the conversation ID is a string here when
+        //       it can be any object that is serializable to XML
+        msg.getTo().getReferenceParameters().setConversationID(conversation.getConversationID());
+
+    }
+
+    /**
+     * Post-invoke for the conversation handling
+     * @param wire
+     * @param operation
+     * @throws TargetDestructionException
+     */
+    @SuppressWarnings("unchecked")
+    private void conversationPostInvoke(Message msg) throws TargetDestructionException {
+        Operation operation = msg.getOperation();
+        ConversationSequence sequence = operation.getConversationSequence();
+        if (sequence == ConversationSequence.CONVERSATION_END) {
+            conversationStarted = false;
+            if (conversation != null) {
+
+                // remove conversation id from scope container
+                ScopeContainer scopeContainer = getConversationalScopeContainer(msg);
+
+                if (scopeContainer != null) {
+                    scopeContainer.remove(conversation.getConversationID());
+                }
+
+                conversation.setConversationID(null);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private ScopeContainer getConversationalScopeContainer(Message msg) {
+        ScopeContainer scopeContainer = null;
+
+        RuntimeComponent component = msg.getFrom().getComponent();
+
+        if (component instanceof ScopedRuntimeComponent) {
+            ScopedRuntimeComponent scopedRuntimeComponent = (ScopedRuntimeComponent)component;
+            ScopeContainer container = scopedRuntimeComponent.getScopeContainer();
+
+            if ((container != null) && (container.getScope() == Scope.CONVERSATION)) {
+                scopeContainer = container;
+            }
+        }
+
+        return scopeContainer;
+    }
+
+    /**
+     * Creates a new conversational id
+     * 
+     * @return the conversational id
+     */
+    private Object createConversationID() {
+        if (conversationID == null) {
+            return UUID.randomUUID().toString();
+        }
+        return conversationID;
+    }
+
+    /**
+     * Minimal wrapper for a callback object contained in a ServiceReference
+     */
+    private static class CallbackObjectWrapper<T> implements InstanceWrapper<T> {
+
+        private T instance;
+
+        private CallbackObjectWrapper(T instance) {
+            this.instance = instance;
+        }
+
+        public T getInstance() {
+            return instance;
+        }
+
+        public void start() {
+            // do nothing
+        }
+
+        public void stop() {
+            // do nothing
+        }
+    }
+
+}

Propchange: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/RuntimeWireInvoker.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java?rev=574648&r1=574647&r2=574648&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java (original)
+++ incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ThreadMessageContext.java Tue Sep 11 10:45:36 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.tuscany.sca.core.invocation;
 
+import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
 import org.apache.tuscany.sca.invocation.Message;
 
 /**
@@ -30,7 +31,9 @@
     private static final ThreadLocal<Message> CONTEXT = new ThreadLocal<Message>() {
         @Override
         protected synchronized Message initialValue() {
-            return new MessageImpl();
+            Message msg =  new MessageImpl();
+            msg.setFrom(new EndpointReferenceImpl("/"));
+            return msg;
         }
     };
 



---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org