Change the Operations for async services to use the sync form. So for example a method 'void operation1Async( String input, ResponseDispatch<String> handler )' would have a Operation named operation1 with a single String arg and a return of type String. This along with the other recent async changes gets async operation working with the data binding framework and jaxb
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1171130 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
454e76086a
commit
539c20cf1e
4 changed files with 132 additions and 19 deletions
sca-java-2.x/trunk/modules/interface-java/src
main/java/org/apache/tuscany/sca/interfacedef/java/impl
test/java/org/apache/tuscany/sca/interfacedef/java/impl
|
@ -197,20 +197,27 @@ public class JavaInterfaceImpl extends InterfaceImpl implements JavaInterface {
|
|||
private Operation getSyncFormOfOperation( JavaOperation operation ) {
|
||||
if( isAsyncServerOperation( operation ) ) {
|
||||
JavaOperation syncOperation = new JavaOperationImpl();
|
||||
String opName = operation.getName().substring(0, operation.getName().length() - 5 );
|
||||
// String opName = operation.getName().substring(0, operation.getName().length() - 5 );
|
||||
String opName = operation.getName();
|
||||
|
||||
// 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<List<DataType>> returnDataType = prepareSyncReturnParam( requestParams );
|
||||
// DataType<List<DataType>> inputType = prepareSyncInputParams( requestParams );
|
||||
// DataType<List<DataType>> returnDataType = prepareSyncReturnParam( requestParams );
|
||||
List<DataType> faultDataTypes = prepareSyncFaults( operation );
|
||||
|
||||
syncOperation.setName(opName);
|
||||
syncOperation.setAsyncServer(true);
|
||||
syncOperation.setInputType(inputType);
|
||||
syncOperation.setOutputType(returnDataType);
|
||||
syncOperation.setName(opName);
|
||||
syncOperation.setAsyncServer(true);
|
||||
syncOperation.setWrapper(operation.getWrapper());
|
||||
syncOperation.setWrapperStyle(operation.isWrapperStyle());
|
||||
syncOperation.setHasArrayWrappedOutput(operation.hasArrayWrappedOutput());
|
||||
syncOperation.setNotSubjectToWrapping(operation.isNotSubjectToWrapping());
|
||||
// syncOperation.setInputType(inputType);
|
||||
// syncOperation.setOutputType(returnDataType);
|
||||
syncOperation.setInputType(operation.getInputType());
|
||||
syncOperation.setOutputType(operation.getOutputType());
|
||||
syncOperation.setFaultTypes(faultDataTypes);
|
||||
syncOperation.setNonBlocking(operation.isNonBlocking());
|
||||
syncOperation.setJavaMethod(operation.getJavaMethod());
|
||||
|
@ -300,6 +307,10 @@ public class JavaInterfaceImpl extends InterfaceImpl implements JavaInterface {
|
|||
* @return - true if the operation has the form of an async operation, false otherwise
|
||||
*/
|
||||
private boolean isAsyncServerOperation( Operation operation ) {
|
||||
|
||||
if (operation.isAsyncServer()) {
|
||||
return true;
|
||||
}
|
||||
// Async form operations have:
|
||||
// 1) void return type (equivalent to an output logical List of size '0')
|
||||
// 2) name ending in "Async"
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.apache.tuscany.sca.interfacedef.java.impl;
|
||||
|
||||
import static org.apache.tuscany.sca.interfacedef.Operation.IDL_INPUT;
|
||||
import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -44,8 +47,6 @@ import org.apache.tuscany.sca.interfacedef.InvalidCallbackException;
|
|||
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
|
||||
import org.apache.tuscany.sca.interfacedef.InvalidOperationException;
|
||||
import org.apache.tuscany.sca.interfacedef.Operation;
|
||||
import static org.apache.tuscany.sca.interfacedef.Operation.IDL_INPUT;
|
||||
import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT;
|
||||
import org.apache.tuscany.sca.interfacedef.OverloadedOperationException;
|
||||
import org.apache.tuscany.sca.interfacedef.ParameterMode;
|
||||
import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
|
||||
|
@ -55,7 +56,9 @@ import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
|
|||
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.ResponseDispatch;
|
||||
import org.oasisopen.sca.annotation.AsyncFault;
|
||||
import org.oasisopen.sca.annotation.AsyncInvocation;
|
||||
import org.oasisopen.sca.annotation.OneWay;
|
||||
import org.oasisopen.sca.annotation.Remotable;
|
||||
|
||||
|
@ -173,9 +176,10 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
method.getParameterAnnotations();
|
||||
} // end method checkMethodAnnotations
|
||||
|
||||
private Class<?>[] getActualTypes(Type[] types, Class<?>[] rawTypes, Map<String, Type> typeBindings) {
|
||||
Class<?>[] actualTypes = new Class<?>[types.length];
|
||||
for (int i = 0; i < actualTypes.length; i++) {
|
||||
private Class<?>[] getActualTypes(Type[] types, Class<?>[] rawTypes, Map<String, Type> typeBindings, boolean ignoreAsyncHolder) {
|
||||
int x = ignoreAsyncHolder ? types.length -1 : types.length;
|
||||
Class<?>[] actualTypes = new Class<?>[x];
|
||||
for (int i = 0; i < x; i++) {
|
||||
actualTypes[i] = getActualType(types[i], rawTypes[i], typeBindings);
|
||||
}
|
||||
return actualTypes;
|
||||
|
@ -212,6 +216,8 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAsyncService = clazz.isAnnotationPresent(AsyncInvocation.class);
|
||||
|
||||
Method[] methods = clazz.getMethods();
|
||||
List<Operation> operations = new ArrayList<Operation>(methods.length);
|
||||
|
@ -223,6 +229,14 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
continue;
|
||||
}
|
||||
String name = method.getName();
|
||||
|
||||
Class<?> lastParameter = method.getParameterTypes().length > 0 ? method.getParameterTypes()[method.getParameterTypes().length-1] : null;
|
||||
boolean isAsyncMethod = isAsyncService && name.endsWith("Async") && lastParameter != null && ResponseDispatch.class.equals(lastParameter);
|
||||
|
||||
if (isAsyncMethod) {
|
||||
name = name.substring(0, name.length()-5);
|
||||
}
|
||||
|
||||
if (remotable && names.contains(name)) {
|
||||
throw new OverloadedOperationException(method);
|
||||
}
|
||||
|
@ -230,11 +244,18 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
names.add(name);
|
||||
}
|
||||
|
||||
Class<?> returnType = getActualType(method.getGenericReturnType(), method.getReturnType(), typeBindings);
|
||||
Class<?>[] parameterTypes =
|
||||
getActualTypes(method.getGenericParameterTypes(), method.getParameterTypes(), typeBindings);
|
||||
Class<?>[] parameterTypes = getActualTypes(method.getGenericParameterTypes(), method.getParameterTypes(), typeBindings, isAsyncMethod);
|
||||
|
||||
Class<?> returnType;
|
||||
if (isAsyncMethod) {
|
||||
ParameterizedType t = (ParameterizedType)method.getGenericParameterTypes()[method.getGenericParameterTypes().length-1];
|
||||
returnType = (Class<?>)t.getActualTypeArguments()[0];
|
||||
} else {
|
||||
returnType = getActualType(method.getGenericReturnType(), method.getReturnType(), typeBindings);
|
||||
}
|
||||
|
||||
Class<?>[] faultTypes =
|
||||
getActualTypes(method.getGenericExceptionTypes(), method.getExceptionTypes(), typeBindings);
|
||||
getActualTypes(method.getGenericExceptionTypes(), method.getExceptionTypes(), typeBindings, false);
|
||||
Class<?>[] allOutputTypes = getOutputTypes(returnType, parameterTypes);
|
||||
|
||||
// For async server interfaces, faults are described using the @AsyncFaults annotation
|
||||
|
@ -266,8 +287,11 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
if (returnType == void.class) {
|
||||
operation.setReturnTypeVoid(true);
|
||||
} else {
|
||||
returnDataType = new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, returnType,
|
||||
method.getGenericReturnType(), xmlReturnType);
|
||||
if (isAsyncMethod) {
|
||||
returnDataType = new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, returnType, returnType, xmlReturnType);
|
||||
} else {
|
||||
returnDataType = new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, returnType, method.getGenericReturnType(), xmlReturnType);
|
||||
}
|
||||
operation.setReturnTypeVoid(false);
|
||||
outputDataTypes.add(returnDataType);
|
||||
}
|
||||
|
@ -327,7 +351,8 @@ public class JavaInterfaceIntrospectorImpl {
|
|||
operation.setFaultTypes(faultDataTypes);
|
||||
operation.setNonBlocking(nonBlocking);
|
||||
operation.setJavaMethod(method);
|
||||
operation.setHasArrayWrappedOutput(hasMultipleOutputs);
|
||||
operation.setHasArrayWrappedOutput(hasMultipleOutputs);
|
||||
operation.setAsyncServer(isAsyncMethod);
|
||||
operations.add(operation);
|
||||
}
|
||||
return operations;
|
||||
|
|
|
@ -81,6 +81,8 @@ public final class JavaInterfaceUtil {
|
|||
for (Method m : implClass.getMethods()) {
|
||||
if (m.getName().equals(name) && m.getParameterTypes().length == numParams) {
|
||||
matchingMethods.add(m);
|
||||
} else if (m.getName().equals(name + "Async") && m.getParameterTypes().length == numParams + 1) {
|
||||
matchingMethods.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +115,11 @@ public final class JavaInterfaceUtil {
|
|||
* @throws NoSuchMethodException if no such method exists
|
||||
*/
|
||||
public static Method findAsyncServerMethod(Class<?> implClass, JavaOperation operation) throws NoSuchMethodException {
|
||||
|
||||
if (operation.getJavaMethod() != null) {
|
||||
return operation.getJavaMethod();
|
||||
}
|
||||
|
||||
String name = operation.getJavaMethod().getName();
|
||||
List<Operation> actualOps = (List<Operation>) operation.getInterface().getAttributes().get("ASYNC-SERVER-OPERATIONS");
|
||||
Operation matchingOp = null;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.interfacedef.java.impl;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
|
||||
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
|
||||
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
|
||||
import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
|
||||
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
|
||||
import org.junit.Test;
|
||||
import org.oasisopen.sca.ResponseDispatch;
|
||||
import org.oasisopen.sca.annotation.AsyncInvocation;
|
||||
import org.oasisopen.sca.annotation.Remotable;
|
||||
|
||||
/**
|
||||
* This test case will test that a Component that has multiple Remotable interfaces
|
||||
* that contain methods with the same name will correctly select the right method.
|
||||
*
|
||||
* @version $Rev: 826368 $ $Date: 2009-10-18 08:22:23 +0100 (Sun, 18 Oct 2009) $
|
||||
*/
|
||||
public class AsyncServiceIntefaceTestCase {
|
||||
|
||||
/**
|
||||
* Test case that validates that a @Remotable interface with Overloaded operations
|
||||
* is detected.
|
||||
*
|
||||
* This test case is for TUSCANY-2194
|
||||
* @throws InvalidInterfaceException
|
||||
*/
|
||||
@Test
|
||||
public void testAsyncIntrospection() throws InvalidInterfaceException
|
||||
{
|
||||
ExtensionPointRegistry registry = new DefaultExtensionPointRegistry();
|
||||
JavaInterfaceFactory javaFactory = new DefaultJavaInterfaceFactory(registry);
|
||||
JavaInterfaceIntrospectorImpl introspector = new JavaInterfaceIntrospectorImpl(javaFactory);
|
||||
JavaInterfaceImpl javaInterface = new JavaInterfaceImpl();
|
||||
|
||||
introspector.introspectInterface(javaInterface, AsyncServiceInterface.class);
|
||||
|
||||
assertEquals(1, javaInterface.getOperations().size());
|
||||
assertEquals("anOperation",javaInterface.getOperations().get(0).getName());
|
||||
assertEquals(1, javaInterface.getOperations().get(0).getInputType().getLogical().size());
|
||||
assertEquals(String.class,javaInterface.getOperations().get(0).getInputType().getLogical().get(0).getGenericType());
|
||||
assertEquals(String.class,javaInterface.getOperations().get(0).getOutputType().getLogical().get(0).getGenericType());
|
||||
}
|
||||
|
||||
@Remotable
|
||||
@AsyncInvocation
|
||||
private interface AsyncServiceInterface {
|
||||
void anOperationAsync(String s, ResponseDispatch<String> rd);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue