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 2009/04/09 21:06:34 UTC

svn commit: r763768 - in /tuscany/branches/sca-java-1.x/modules: core/src/main/java/org/apache/tuscany/sca/core/invocation/ implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/

Author: rfeng
Date: Thu Apr  9 19:06:34 2009
New Revision: 763768

URL: http://svn.apache.org/viewvc?rev=763768&view=rev
Log:
Add remotable check to avoid perf penality from Holder processing for local calls

Modified:
    tuscany/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java
    tuscany/branches/sca-java-1.x/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java

Modified: tuscany/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java?rev=763768&r1=763767&r2=763768&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java (original)
+++ tuscany/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java Thu Apr  9 19:06:34 2009
@@ -6,15 +6,15 @@
  * 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.    
+ * under the License.
  */
 
 package org.apache.tuscany.sca.core.invocation;
@@ -23,13 +23,13 @@
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.lang.reflect.Type;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.xml.ws.Holder;
+
 import org.apache.tuscany.sca.core.assembly.RuntimeWireImpl;
 import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
 import org.apache.tuscany.sca.core.context.InstanceWrapper;
@@ -60,10 +60,6 @@
 import org.osoa.sca.ServiceReference;
 import org.osoa.sca.ServiceRuntimeException;
 
-import java.util.Iterator;
-import javax.xml.ws.Holder;
-
-
 /**
  * @version $Rev$ $Date$
  */
@@ -156,22 +152,21 @@
             throw new IllegalArgumentException("No matching operation is found: " + method);
         }
 
-        // Holder pattern. Items stored in a Holder<T> are promoted to T.
-        // After the invoke, the returned data <T> are placed back in Holder<T>.
-        Object [] promotedArgs = promoteHolderArgs( args );
-        
-        Object result = invoke(chain, promotedArgs, wire, source);
-
-        // Returned Holder data <T> are placed back in Holder<T>.
-        Class [] parameters = method.getParameterTypes();
-        if ( parameters != null ) {
-            for ( int i = 0; i < parameters.length; i++ ) {
-               Class parameterType = parameters[ i ];              
-               if ( isHolder( parameterType ) ) {
-                  // Pop results and place in holder (demote).
-                  Holder holder = (Holder) args[ i ]; 
-                  holder.value = result;
-               }            
+        Object result = invoke(chain, args, wire, source);
+
+        Operation operation = chain.getTargetOperation();
+        if (operation != null && operation.getInterface().isRemotable()) {
+            // Returned Holder data <T> are placed back in Holder<T>.
+            Class<?>[] parameters = method.getParameterTypes();
+            if (parameters != null) {
+                for (int i = 0; i < parameters.length; i++) {
+                    Class<?> parameterType = parameters[i];
+                    if (Holder.class == parameterType) {
+                        // Pop results and place in holder (demote).
+                        Holder holder = (Holder)args[i];
+                        holder.value = result;
+                    }
+                }
             }
         }
 
@@ -205,7 +200,7 @@
 
     /**
      * Determines if the given operation matches the given method
-     * 
+     *
      * @return true if the operation matches, false if does not
      */
     // FIXME: Should it be in the InterfaceContractMapper?
@@ -226,7 +221,7 @@
             }
         }
 
-        // For remotable interface, operation is not overloaded. 
+        // For remotable interface, operation is not overloaded.
         if (operation.getInterface().isRemotable()) {
             return true;
         }
@@ -284,7 +279,7 @@
     }
 
     protected Object invoke(InvocationChain chain, Object[] args, RuntimeWire wire, EndpointReference source)
-                         throws Throwable {
+        throws Throwable {
         Message msg = messageFactory.createMessage();
         msg.setFrom(source);
         if (target != null) {
@@ -294,9 +289,15 @@
         }
         Invoker headInvoker = chain.getHeadInvoker();
         Operation operation = chain.getTargetOperation();
-        
-        msg.setOperation(operation);       
-        msg.setBody( args );
+
+        msg.setOperation(operation);
+
+        // Holder pattern. Items stored in a Holder<T> are promoted to T.
+        // After the invoke, the returned data <T> are placed back in Holder<T>.
+        if (operation != null && operation.getInterface().isRemotable()) {
+            args = promoteHolderArgs(args);
+        }
+        msg.setBody(args);
 
         Message msgContext = ThreadMessageContext.getMessageContext();
         Object currentConversationID = msgContext.getFrom().getReferenceParameters().getConversationID();
@@ -311,23 +312,23 @@
             Object body = resp.getBody();
             if (resp.isFault()) {
                 // mark the conversation as ended if the exception is not a business exception
-                if (currentConversationID != null ){
+                if (currentConversationID != null) {
                     try {
                         boolean businessException = false;
-                        
-                        for (DataType dataType : operation.getFaultTypes()){
-                            if (dataType.getPhysical() == ((Throwable)body).getClass()){
+
+                        for (DataType dataType : operation.getFaultTypes()) {
+                            if (dataType.getPhysical() == ((Throwable)body).getClass()) {
                                 businessException = true;
                                 break;
                             }
                         }
-                        
-                        if (businessException == false){
+
+                        if (businessException == false) {
                             abnormalEndConversation = true;
                         }
-                    } catch (Exception ex){
+                    } catch (Exception ex) {
                         // TODO - sure what the best course of action is here. We have
-                        //        a system exception in the middle of a business exception 
+                        //        a system exception in the middle of a business exception
                     }
                 }
                 throw (Throwable)body;
@@ -356,7 +357,7 @@
         parameters.setCallbackReference(msg.getFrom().getCallbackEndpoint());
 
         // If we are passing out a callback target
-        // register the calling component instance against this 
+        // register the calling component instance against this
         // new conversation id so that stateful callbacks will be
         // able to find it
         Object callbackObject = getCallbackObject();
@@ -383,7 +384,7 @@
                     } else {
                         if (!(callbackObject instanceof Serializable)) {
                             throw new IllegalArgumentException(
-                                          "Callback object for stateful callback is not Serializable");
+                                                               "Callback object for stateful callback is not Serializable");
                         }
                         ScopeContainer scopeContainer = getConversationalScopeContainer(wire);
                         if (scopeContainer != null) {
@@ -413,25 +414,25 @@
         if (conversation == null || conversation.getState() == ConversationState.ENDED) {
 
             conversation = conversationManager.startConversation(getConversationID());
-            
-            // if this is a local wire then set up the conversation timeouts here based on the 
+
+            // if this is a local wire then set up the conversation timeouts here based on the
             // parameters from the component
-            if (wire.getTarget().getComponent() != null){
+            if (wire.getTarget().getComponent() != null) {
                 conversation.initializeConversationAttributes(wire.getTarget().getComponent());
             }
-            
+
             // connect the conversation to the CallableReference so it can be retrieve in the future
             if (callableReference != null) {
                 ((CallableReferenceImpl)callableReference).attachConversation(conversation);
             }
         } else if (conversation.isExpired()) {
-            throw new ConversationEndedException("Conversation " +  conversation.getConversationID() + " has expired.");
+            throw new ConversationEndedException("Conversation " + conversation.getConversationID() + " has expired.");
         }
 
         // if this is a local wire then schedule conversation timeouts based on the timeout
         // parameters from the service implementation. If this isn't a local wire then
         // the RuntimeWireInvoker will take care of this
-        if (wire.getTarget().getComponent() != null){
+        if (wire.getTarget().getComponent() != null) {
             conversation.updateLastReferencedTime();
         }
 
@@ -447,14 +448,13 @@
      */
     @SuppressWarnings("unchecked")
     private void conversationPostInvoke(Message msg, RuntimeWire wire, boolean abnormalEndConversation)
-                     throws TargetDestructionException {
+        throws TargetDestructionException {
         Operation operation = msg.getOperation();
         ConversationSequence sequence = operation.getConversationSequence();
         // We check that conversation has not already ended as there is only one
-        // conversation manager in the runtime and so, in the case of remote bindings, 
+        // conversation manager in the runtime and so, in the case of remote bindings,
         // the conversation will already have been stopped when we get back to the client
-        if ((sequence == ConversationSequence.CONVERSATION_END || abnormalEndConversation) &&
-            (conversation.getState() != ConversationState.ENDED)) {
+        if ((sequence == ConversationSequence.CONVERSATION_END || abnormalEndConversation) && (conversation.getState() != ConversationState.ENDED)) {
 
             // remove conversation id from scope container
             ScopeContainer scopeContainer = getConversationalScopeContainer(wire);
@@ -486,7 +486,7 @@
 
     /**
      * Creates a new conversation id
-     * 
+     *
      * @return the conversation id
      */
     private Object createConversationID() {
@@ -536,58 +536,40 @@
 
     }
 
-    
     /**
      * Creates a copy of arguments. Holder<T> values are promoted to T.
      * Note. It is essential that arg Holders not be destroyed here.
      * PromotedArgs should not destroy holders. They are used on response return.
      * @param args containing Holders and other objects.
-     * @return Object [] 
+     * @return Object []
      */
-    protected static Object [] promoteHolderArgs( Object [] args ) {
-       if ( args == null )
-           return args;
-       Object [] promotedArgs = new Object[ args.length ];
-       
-       for ( int i = 0; i < args.length; i++ ) {
-          Object argument = args[ i ];
-          if ( argument != null ) {
-              if ( isHolder( argument ) ) {
-                 promotedArgs[ i ] = ((Holder)argument).value;      
-              } else {
-                 promotedArgs[ i ] = args[ i ];
-              }
-              
-          }
-       }
-       return promotedArgs;
-    }
+    protected static Object[] promoteHolderArgs(Object[] args) {
+        if (args == null)
+            return args;
+
+        Object[] promotedArgs = new Object[args.length];
+
+        for (int i = 0; i < args.length; i++) {
+            Object argument = args[i];
+            if (argument != null) {
+                if (isHolder(argument)) {
+                    promotedArgs[i] = ((Holder)argument).value;
+                } else {
+                    promotedArgs[i] = args[i];
+                }
 
-    /**
-     * Given a Class, tells if it is a Holder by comparing to "javax.xml.ws.Holder"
-     * @param testClass
-     * @return boolean whether class is Holder type.
-     */
-    protected static boolean isHolder( Class testClass ) {
-        if ( testClass.getName().startsWith( "javax.xml.ws.Holder" )) {
-            return true;
+            }
         }
-        return false;        
+        return promotedArgs;
     }
 
-     
     /**
      * Given an Object, tells if it is a Holder by comparing to "javax.xml.ws.Holder"
      * @param testClass
      * @return boolean stating whether Object is a Holder type.
      */
-    protected static boolean isHolder( Object object ) {
-        String objectName = object.getClass().getName();
-        if ( object instanceof javax.xml.ws.Holder ) {
-            return true;
-        }
-        return false;        
+    protected static boolean isHolder(Object object) {
+        return Holder.class.isInstance(object);
     }
 
-
 }

Modified: tuscany/branches/sca-java-1.x/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java?rev=763768&r1=763767&r2=763768&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.x/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java (original)
+++ tuscany/branches/sca-java-1.x/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java Thu Apr  9 19:06:34 2009
@@ -6,22 +6,22 @@
  * 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.    
+ * under the License.
  */
 package org.apache.tuscany.sca.implementation.java.invocation;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Vector;
 
 import javax.xml.ws.Holder;
 
@@ -45,7 +45,7 @@
 /**
  * Responsible for synchronously dispatching an invocation to a Java component
  * implementation instance
- * 
+ *
  * @version $Rev$ $Date$
  */
 public class JavaImplementationInvoker implements Invoker, DataExchangeSemantics {
@@ -65,7 +65,7 @@
     }
 
     public JavaImplementationInvoker(Operation operation, RuntimeComponent component) {
-        // used if the method can't be computed statically in advance 
+        // used if the method can't be computed statically in advance
         this.operation = operation;
         this.scopeContainer = ((ScopedRuntimeComponent)component).getScopeContainer();
     }
@@ -98,7 +98,7 @@
         }
 
         try {
-            // The following call might create a new conversation, as a result, the msg.getConversationID() might 
+            // The following call might create a new conversation, as a result, the msg.getConversationID() might
             // return a new value
             InstanceWrapper wrapper = scopeContainer.getWrapper(contextId);
 
@@ -106,8 +106,8 @@
             // happen in the case that the component has conversational scope but only the
             // callback interface is conversational. Or in the callback case if the service interface
             // is conversational and the callback interface isn't. If we are in this situation we need
-            // to get the contextId of this component and remove it after we have invoked the method on 
-            // it. It is possible that the component instance will not go away when it is removed below 
+            // to get the contextId of this component and remove it after we have invoked the method on
+            // it. It is possible that the component instance will not go away when it is removed below
             // because a callback conversation will still be holding a reference to it
             boolean removeTemporaryConversationalComponentAfterCall = false;
             if (parameters != null && (contextId == null) && (parameters.getConversationID() != null)) {
@@ -129,32 +129,33 @@
                     throw new IllegalArgumentException("Callback object does not provide method " + e.getMessage());
                 }
             }
-            
+
             // Holder pattern. Any payload parameters <T> which are should be in holders are placed in Holder<T>.
-            if ( imethod != null) {
-                Class<?> [] params = imethod.getParameterTypes();
-                if ( params != null ) {
-                    for ( int i = 0; i < params.length; i++ ) {
-                        Class<?> parameter = params[ i ];
-                        if ( isHolder( parameter )) {
+            // Only check Holder for remotable interfaces
+            if (imethod != null && op.getInterface().isRemotable()) {
+                Class<?>[] params = imethod.getParameterTypes();
+                if (params != null) {
+                    for (int i = 0; i < params.length; i++) {
+                        Class<?> parameter = params[i];
+                        if (Holder.class == parameter) {
                             // System.out.println( "JavaImplementationInvoker.invoke parameter " + i + " is Holder. Payload isArray=" + (payload != null ? payload.getClass().isArray() : "null" ));
                             if (payload != null && !payload.getClass().isArray()) {
                                 // Promote single param from <T> to Holder<T>
-                                payload = new Holder( payload );                               
+                                payload = new Holder(payload);
                             } else {
                                 // Promote array params from [<T>] to [Holder<T>]
-                                Object [] payloadArray = (Object[]) payload;
-                                for ( int j = 0; j < payloadArray.length; j++ ) {
-                                    Object item = payloadArray[ j ];
-                                    payloadArray[ j ] = new Holder( item );
+                                Object[] payloadArray = (Object[])payload;
+                                for (int j = 0; payloadArray != null && j < payloadArray.length; j++) {
+                                    Object item = payloadArray[j];
+                                    payloadArray[j] = new Holder(item);
                                 }
                             }
                             argumentHolderCount++;
                         }
                     }
-                }                
+                }
             }
-            
+
             Object ret;
             if (payload != null && !payload.getClass().isArray()) {
                 ret = imethod.invoke(instance, payload);
@@ -170,49 +171,49 @@
                 scopeContainer.remove(contextId);
                 parameters.setConversationID(null);
             }
-            
+
             if (argumentHolderCount > 0) {
                 // Holder pattern. Any payload Holder<T> types are returned as the message body.
-                List returnArgs = new Vector<Object>();
+                List returnArgs = new ArrayList<Object>();
                 int foundHolders = 0;
-                if ( imethod != null) {
-                    Class<?> [] params = imethod.getParameterTypes();
-                    if ( params != null ) {
-                        for ( int i = 0; i < params.length; i++ ) {
-                            Class<?> parameter = params[ i ];
+                if (imethod != null) {
+                    Class<?>[] params = imethod.getParameterTypes();
+                    if (params != null) {
+                        for (int i = 0; i < params.length; i++) {
+                            Class<?> parameter = params[i];
                             // System.out.println( "JavaImplementationInvoker.invoke return parameter " + i + " type=" + parameter.getClass().getName() );
-                            if ( isHolder( parameter )) {
+                            if (Holder.class == parameter) {
                                 if (payload != null && !payload.getClass().isArray()) {
                                     // Demote params from Holder<T> to <T>.
-                                    Holder<Object> holder = (Holder<Object>) payload;
-                                    returnArgs.add( holder.value );
+                                    Holder<Object> holder = (Holder<Object>)payload;
+                                    returnArgs.add(holder.value);
                                     foundHolders++;
                                 } else {
                                     // Demote array params from Holder<T> to <T>.
-                                    Object [] payloadArray = (Object[]) payload;
-                                    for ( int j = 0; j < payloadArray.length; j++ ) {
-                                        Holder<Object> item = (Holder<Object>) payloadArray[ j ];
-                                        payloadArray[ j ] = item.value;
-                                        returnArgs.add( payloadArray[ j ] );
+                                    Object[] payloadArray = (Object[])payload;
+                                    for (int j = 0; j < payloadArray.length; j++) {
+                                        Holder<Object> item = (Holder<Object>)payloadArray[j];
+                                        payloadArray[j] = item.value;
+                                        returnArgs.add(payloadArray[j]);
                                     }
                                     foundHolders++;
                                 }
                             }
                         }
-                    }                
+                    }
                 }
                 // Although payload items are returned in a list, currently only support 1 return type.
-                if ( returnArgs.size() == 1 ) {
-                    Object value = returnArgs.get( 0 );
-                    if (( value != null ) && ( value.getClass().isArray() )) {
-                       Object [] values = (Object []) value;
-                       if (( values != null ) && ( values.length > 0 )) {
-                          msg.setBody( values[ 0 ] );
-                       }
-                    } else 
-                        msg.setBody(value);                
-                } else 
-                   msg.setBody(returnArgs.toArray());                
+                if (returnArgs.size() == 1) {
+                    Object value = returnArgs.get(0);
+                    if ((value != null) && (value.getClass().isArray())) {
+                        Object[] values = (Object[])value;
+                        if ((values != null) && (values.length > 0)) {
+                            msg.setBody(values[0]);
+                        }
+                    } else
+                        msg.setBody(value);
+                } else
+                    msg.setBody(returnArgs.toArray());
             } else {
                 msg.setBody(ret);
             }
@@ -227,27 +228,26 @@
                 }
             }
 
-            
-            if (sequence != ConversationSequence.CONVERSATION_NONE ){
+            if (sequence != ConversationSequence.CONVERSATION_NONE) {
                 try {
-//                    // If the exception is not a business exception then end the conversation
-//                    boolean businessException = false;
-//                    
-//                    for (DataType dataType : operation.getFaultTypes()){
-//                        if ((dataType.getPhysical() == e.getCause().getClass()) &&
-//                            (contextId != null) ){
-//                            businessException = true;
-//                            break;
-//                        }
-//                    }
-                    
+                    //                    // If the exception is not a business exception then end the conversation
+                    //                    boolean businessException = false;
+                    //
+                    //                    for (DataType dataType : operation.getFaultTypes()){
+                    //                        if ((dataType.getPhysical() == e.getCause().getClass()) &&
+                    //                            (contextId != null) ){
+                    //                            businessException = true;
+                    //                            break;
+                    //                        }
+                    //                    }
+
                     if (!isChecked && contextId != null) {
                         scopeContainer.remove(contextId);
                         parameters.setConversationID(null);
                     }
-                } catch (Exception ex){
+                } catch (Exception ex) {
                     // TODO - sure what the best course of action is here. We have
-                    //        a system exception in the middle of a business exception 
+                    //        a system exception in the middle of a business exception
                 }
             }
             if (!isChecked) {
@@ -259,10 +259,10 @@
                 } else {
                     throw new ServiceRuntimeException(cause.getMessage(), cause);
                 }
-            }            
-                
+            }
+
         } catch (Exception e) {
-            msg.setFaultBody(e);           
+            msg.setFaultBody(e);
         }
         return msg;
     }
@@ -270,16 +270,4 @@
     public boolean allowsPassByReference() {
         return allowsPBR;
     }
-
-    /**
-     * Given a Class, tells if it is a Holder by comparing to "javax.xml.ws.Holder"
-     * @param testClass
-     * @return
-     */
-    public static boolean isHolder( Class testClass ) {
-        if ( testClass.getName().equals( "javax.xml.ws.Holder" )) {
-            return true;
-        }
-        return false;        
-    }
 }