tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edward...@apache.org
Subject svn commit: r957877 - in /tuscany/sca-java-2.x/trunk/modules/interface-java: META-INF/ src/main/java/org/apache/tuscany/sca/interfacedef/java/ src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/
Date Fri, 25 Jun 2010 10:21:29 GMT
Author: edwardsmj
Date: Fri Jun 25 10:21:28 2010
New Revision: 957877

URL: http://svn.apache.org/viewvc?rev=957877&view=rev
Log:
Introspection of SCA Async Server form on Java interface and Equivalence mapping of Async
Server interface to Synchronous Java interface, as described in TUSCANY-3609 and TUSCANY-3610

Modified:
    tuscany/sca-java-2.x/trunk/modules/interface-java/META-INF/MANIFEST.MF
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaOperation.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceImpl.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/META-INF/MANIFEST.MF?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/META-INF/MANIFEST.MF (original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/META-INF/MANIFEST.MF Fri Jun 25 10:21:28
2010
@@ -21,6 +21,7 @@ Bundle-License: http://www.apache.org/li
 Bundle-Description: Apache Tuscany SCA Java Interface Model
 Import-Package: javax.xml.namespace,
  javax.xml.stream,
+ org.oasisopen.sca;version="2.0.0",
  org.apache.tuscany.sca.assembly;version="2.0.0",
  org.apache.tuscany.sca.assembly.xml;version="2.0.0",
  org.apache.tuscany.sca.contribution.processor;version="2.0.0",

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaOperation.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaOperation.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaOperation.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaOperation.java
Fri Jun 25 10:21:28 2010
@@ -54,5 +54,17 @@ public interface JavaOperation extends O
      * @param action the action value
      */
     void setAction(String action);
+    
+    /**
+     * Sets whether this operation has async server style
+     * @param isAsync - "true" marks this operation as async server style
+     */
+    public void setAsyncServer( boolean isAsync );
+    
+    /** 
+     * Indicates whether this operation is async server style
+     * @return - true if the operation is async server style
+     */
+    public boolean isAsyncServer();
 
 }

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
Fri Jun 25 10:21:28 2010
@@ -58,6 +58,8 @@ public abstract class JavaInterfaceFacto
             if (javaInterface == null) {
                 javaInterface = createJavaInterface();
                 introspector.introspectInterface(javaInterface, interfaceClass);
+                // Now that all introspection is complete we can mark the interface resolved
+                javaInterface.setUnresolved(false);
                 cache.put(interfaceClass, javaInterface);
             }
             return javaInterface;

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceImpl.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceImpl.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceImpl.java
Fri Jun 25 10:21:28 2010
@@ -19,10 +19,25 @@
 package org.apache.tuscany.sca.interfacedef.java.impl;
 
 import java.lang.ref.WeakReference;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.List;
+import java.lang.reflect.ParameterizedType;
 
 import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
 import org.apache.tuscany.sca.interfacedef.impl.InterfaceImpl;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.apache.tuscany.sca.policy.Intent;
+
+import org.oasisopen.sca.ResponseDispatch;
 
 /**
  * Represents a Java interface.
@@ -37,6 +52,10 @@ public class JavaInterfaceImpl extends I
     private QName qname;
     
     protected JavaInterfaceImpl() {
+    	super();
+    	// Mark the interface as unresolved until all the basic processing is complete
+    	// including Intent & Policy introspection
+    	this.setUnresolved(true);
     }
 
     public String getName() {
@@ -135,5 +154,172 @@ public class JavaInterfaceImpl extends I
 
         return true;
     }
+    
+    public List<Operation> getOperations() {
+    	if( !isUnresolved() && isAsyncServer() ) {
+    		return equivalentSyncOperations();
+    	} else {
+    		return super.getOperations();
+    	}
+    } // end method getOperations
+    
+
+    private List<Operation> syncOperations = null;
+    private List<Operation> equivalentSyncOperations() {
+    	if( syncOperations != null ) return syncOperations;
+    	List<Operation> allOperations = super.getOperations();
+    	syncOperations = new ArrayList<Operation>();
+    	for( Operation operation: allOperations) {
+    		syncOperations.add( getSyncFormOfOperation( (JavaOperation) operation ) );
+    	// Store the actual async operations under the attribute "ASYNC-SERVER-OPERATIONS"
+    	this.getAttributes().put("ASYNC-SERVER-OPERATIONS", allOperations);
+    	} // end for
+    	
+    	return syncOperations;
+    } // end method equivalentSyncOperations
+    
+    private static final String UNKNOWN_DATABINDING = null;
+    /**
+     * Prepares the synchronous form of an asynchronous operation
+     * - async form:      void someOperationAsync( FooType inputParam, DispatchResponse<BarType>
)
+     * - sync form:       BarType someOperation( FooType inputParam )
+     * @param operation - the operation to convert
+     * @return - the synchronous form of the operation - for an input operation that is not
async server in form, this 
+     *           method simply returns the original operation unchanged
+     */
+    private Operation getSyncFormOfOperation( JavaOperation operation ) {
+    	if( isAsyncServerOperation( operation ) ) {
+            JavaOperation syncOperation = new JavaOperationImpl();
+            String opName = operation.getName().substring(0, operation.getName().length()
- 5 );
+        	
+            // Prepare the list of equivalent input parameters, which simply excludes the
(final) DispatchResponse object
+            // and the equivalent return parameter, which is the (generic) type from the
DispatchResponse object
+            DataType<List<DataType>> requestParams = operation.getInputType();
+
+        	DataType<List<DataType>> inputType = prepareSyncInputParams( requestParams
);
+            DataType<XMLType> returnDataType = prepareSyncReturnParam( requestParams
);
+            List<DataType> faultDataTypes = prepareSyncFaults( operation );
+        	
+        	syncOperation.setName(opName);
+        	syncOperation.setAsyncServer(true);
+            syncOperation.setInputType(inputType);
+            syncOperation.setOutputType(returnDataType);
+            syncOperation.setFaultTypes(faultDataTypes);
+            syncOperation.setNonBlocking(operation.isNonBlocking());
+            syncOperation.setJavaMethod(operation.getJavaMethod());
+            syncOperation.setInterface(this);
+    		return syncOperation;
+    	} else {
+    		// If it's not Async form, then it's a synchronous operation
+    		return operation;
+    	} // end if
+    } // end getSyncFormOfOperation
+    
+    /**
+     * Produce the equivalent sync method input parameters from the input parameters of the
async method
+     * @param requestParams - async method input parameters
+     * @return - the equivalent sync method input parameters
+     */
+    private DataType<List<DataType>> prepareSyncInputParams( DataType<List<DataType>>
requestParams ) {
+        List<DataType> requestLogical = requestParams.getLogical();
+    	int paramCount = requestLogical.size();
+    	
+    	// Copy the list of async parameters, removing the final DispatchResponse
+    	List<DataType> asyncParams = new ArrayList<DataType>( paramCount - 1);
+    	for( int i = 0 ; i < (paramCount - 1) ; i++ ) {
+    		asyncParams.add( requestLogical.get(i) );
+    	} // end for
+    	
+    	DataType<List<DataType>> inputType =
+            new DataTypeImpl<List<DataType>>(requestParams.getDataBinding(),
+            		                         requestParams.getPhysical(), asyncParams);
+    	return inputType;
+    } // end method prepareSyncInputParams
+    
+    /**
+     * Prepare the return data type of the equivalent sync operation, based on the parameterization
of the ResponseDispatch object
+     * of the async operation - the return data type is the Generic type of the final DispatchResponse<?>
+     * @param requestParams - - async method input parameters
+     * @return - the sync method return parameter
+     */
+    private DataType<XMLType> prepareSyncReturnParam( DataType<List<DataType>>
requestParams ) {
+    	List<DataType> requestLogical = requestParams.getLogical();
+    	int paramCount = requestLogical.size();
+    	
+    	DataType<?> finalParam = requestLogical.get( paramCount - 1 );
+    	ParameterizedType t = (ParameterizedType)finalParam.getGenericType();
+    	XMLType returnXMLType = (XMLType)finalParam.getLogical();
+    	
+    	String namespace = null;
+    	if( returnXMLType.isElement() ) {
+    		namespace = returnXMLType.getElementName().getNamespaceURI();
+    	} else {
+    		namespace = returnXMLType.getTypeName().getNamespaceURI();
+    	}
+    	
+    	Type[] typeArgs = t.getActualTypeArguments();
+    	if( typeArgs.length != 1 ) throw new IllegalArgumentException( "ResponseDispatch parameter
is not parameterized correctly");
+    	
+    	Class<?> returnType = (Class<?>)typeArgs[0];
+        
+    	// Set outputType to null for void
+        XMLType xmlReturnType = new XMLType(new QName(namespace, "return"), null);
+        DataType<XMLType> returnDataType =
+            returnType == void.class ? null : new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING,
returnType, xmlReturnType);
+        
+        return returnDataType;
+    } // end method prepareSyncReturnParam
+    
+    /**
+     * Prepare the set of equivalent sync faults for a given async operation
+     * @return - the list of faults
+     */
+    private List<DataType> prepareSyncFaults( JavaOperation operation ) {
+    	//TODO - deal with Faults - for now just copy through whatever is associated with the
async operation
+    	return operation.getFaultTypes();
+    }
+    
+    /**
+     * Determines if an interface operation has the form of an async server operation
+     * - async form:      void someOperationAsync( FooType inputParam, ...., DispatchResponse<BarType>
)
+     * @param operation - the operation to examine
+     * @return - true if the operation has the form of an async operation, false otherwise
+     */
+    private boolean isAsyncServerOperation( Operation operation ) {
+    	// Async form operations have:
+    	// 1) void return type
+    	// 2) name ending in "Async"
+    	// 3) final parameter which is of ResponseDispatch<?> type
+    	DataType<?> response = operation.getOutputType();
+    	if( response != null ) {
+    	   if ( response.getPhysical() != void.class ) return false;
+    	} // end if
+    	
+    	if ( !operation.getName().endsWith("Async") ) return false;
+    	
+    	DataType<List<DataType>> requestParams = operation.getInputType();
+    	int paramCount = requestParams.getLogical().size();
+    	if( paramCount < 1 ) return false;
+    	DataType<?> finalParam = requestParams.getLogical().get( paramCount - 1 );
+    	if ( finalParam.getPhysical() != ResponseDispatch.class ) return false;
+    	
+    	return true;
+    } // end method isAsyncServerOperation
+    
+    static QName ASYNC_INVOCATION = new QName(Constants.SCA11_NS, "asyncInvocation");
+    /**
+     * Indicates if this interface is an Async Server interface
+     * @return true if the interface is Async Server, false otherwise
+     */
+    private boolean isAsyncServer() {
+    	
+    	List<Intent> intents = getRequiredIntents();
+    	for( Intent intent: intents ) {
+    		if ( intent.getName().equals(ASYNC_INVOCATION) ) {
+    			return true;
+    		}
+    	} // end for
+    	return false;
+    } // end method isAsyncServer
 
 }

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
Fri Jun 25 10:21:28 2010
@@ -51,6 +51,7 @@ import org.apache.tuscany.sca.interfaced
 import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
 import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
 import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.oasisopen.sca.annotation.AsyncFault;
 import org.oasisopen.sca.annotation.OneWay;
 import org.oasisopen.sca.annotation.Remotable;
 
@@ -199,6 +200,11 @@ public class JavaInterfaceIntrospectorIm
                 getActualTypes(method.getGenericParameterTypes(), method.getParameterTypes(),
typeBindings);
             Class<?>[] faultTypes =
                 getActualTypes(method.getGenericExceptionTypes(), method.getExceptionTypes(),
typeBindings);
+            
+            // For async server interfaces, faults are described using the @AsyncFaults annotation
+            if( method.isAnnotationPresent(AsyncFault.class) ) {
+            	faultTypes = readAsyncFaultTypes( method );
+            } // end if 
 
             boolean nonBlocking = method.isAnnotationPresent(OneWay.class);
             if (nonBlocking) {
@@ -256,6 +262,17 @@ public class JavaInterfaceIntrospectorIm
         }
         return operations;
     }
+    
+    /**
+     * Reads the fault types declared in an @AsyncFault annotation on an async server method
+     * @param method - the Method
+     * @return - an array of fault/exception classes
+     */
+    private  Class<?>[] readAsyncFaultTypes( Method method ) {
+    	AsyncFault theFaults = method.getAnnotation(AsyncFault.class);
+    	if ( theFaults == null ) return null;
+    	return theFaults.value();
+    } // end method readAsyncFaultTypes
 
     private boolean jaxwsAsyncMethod(Method method) {
         if (method.getName().endsWith("Async")) {

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java
Fri Jun 25 10:21:28 2010
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.Interface;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
 import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
 
 /**
@@ -54,7 +55,12 @@ public final class JavaInterfaceUtil {
     public static Method findMethod(Class<?> implClass, Operation operation) throws
NoSuchMethodException {
         String name = operation.getName();
         if (operation instanceof JavaOperation) {
-            name = ((JavaOperation)operation).getJavaMethod().getName();
+        	if( ((JavaOperation)operation).isAsyncServer() ) {
+        		// In this case, the operation is a mapped async server style method and needs
special handling
+        		return findAsyncServerMethod( implClass, (JavaOperation)operation );
+        	} else {
+        		name = ((JavaOperation)operation).getJavaMethod().getName();
+        	} // end if
         }
         Interface interface1 = operation.getInterface();
         int numParams = operation.getInputType().getLogical().size();
@@ -85,6 +91,49 @@ public final class JavaInterfaceUtil {
         Class<?>[] paramTypes = getPhysicalTypes(operation);
         return implClass.getMethod(name, paramTypes);
     }
+    
+    /**
+     * Return the method on the implementation class that matches the async server version
of the operation.
+     * 
+     * @param implClass the implementation class or interface
+     * @param operation the operation to match - this is the sync equivalent of an async
server operation
+     * @return the method described by the operation
+     * @throws NoSuchMethodException if no such method exists
+     */
+    public static Method findAsyncServerMethod(Class<?> implClass, JavaOperation operation)
throws NoSuchMethodException {
+        String name = operation.getJavaMethod().getName();
+        List<Operation> actualOps = (List<Operation>) operation.getInterface().getAttributes().get("ASYNC-SERVER-OPERATIONS");
+        Operation matchingOp = null;
+        for( Operation op: actualOps ) {
+        	if( op.getName().equals(name) ) {
+        		matchingOp = op;
+        		break;
+        	}
+        } // end for
+        if( matchingOp == null ) throw new NoSuchMethodException("No matching async method
for operation " + operation.getName());
+        
+        int numParams = matchingOp.getInputType().getLogical().size();
+        
+        List<Method> matchingMethods = new ArrayList<Method>();
+        for (Method m : implClass.getMethods()) {
+            if (m.getName().equals(name) && m.getParameterTypes().length == (numParams)
) {
+                matchingMethods.add(m);
+            }
+        }
+        
+        if (matchingMethods.size() == 1) {
+            return matchingMethods.get(0);
+        }
+        if (matchingMethods.size() > 1) {
+            Class<?>[] paramTypes = getPhysicalTypes(matchingOp);
+            return implClass.getMethod(name, paramTypes);
+        } 
+        
+        // No matching method found
+        throw new NoSuchMethodException("No matching method for operation " + operation.getName()
+            + " is found on " + implClass);
+        
+    } // end method findAsyncServerMethod
 
     /**
      * @Deprecated

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java?rev=957877&r1=957876&r2=957877&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java
(original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java
Fri Jun 25 10:21:28 2010
@@ -33,6 +33,7 @@ public class JavaOperationImpl extends O
 
     private Method method;
     private String action;
+    private boolean isAsyncServer = false;
 
     public Method getJavaMethod() {
         return method;
@@ -74,6 +75,22 @@ public class JavaOperationImpl extends O
             return false;
         return true;
     }
+    
+    /**
+     * Sets whether this operation has async server style
+     * @param isAsync - "true" marks this operation as async server style
+     */
+    public void setAsyncServer( boolean isAsync ) {
+    	isAsyncServer = isAsync;
+    }
+    
+    /** 
+     * Indicates whether this operation is async server style
+     * @return - true if the operation is async server style
+     */
+    public boolean isAsyncServer() {
+    	return isAsyncServer;
+    }
 
     @Override
     public String toString() {



Mime
View raw message