summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/binding-corba-runtime/src
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2008-07-18 18:29:28 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2008-07-18 18:29:28 +0000
commit7f87032072bad92962601c8f9ece5f71b2d4a1ef (patch)
treef5d675f60fb31c7ed6d61d3d7f2fa007eb5f2f07 /java/sca/modules/binding-corba-runtime/src
parent3d43862fc293982f39996fe09d94971b20521a2b (diff)
Apply the patch from Wojtek for TUSCANY-2397 (operations-mapping-jira-2357-15-july.patch)
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@677993 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/binding-corba-runtime/src')
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaInvoker.java11
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaReferenceBindingProvider.java11
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/DynaCorbaRequest.java75
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceInstanceCreator.java2
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceMethodInterceptor.java5
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/service/DynaCorbaServant.java91
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/types/util/Utils.java2
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/MethodFinder.java96
-rw-r--r--java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/OperationMapper.java516
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/CorbaTypesTestCase.java18
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MappingTestInterface.java45
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MethodFinderTestCase.java69
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/OperationMappingTestCase.java66
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterface.java47
-rw-r--r--java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeComponentService.java2
15 files changed, 1004 insertions, 52 deletions
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaInvoker.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaInvoker.java
index 43c471d3bc..f1640329e8 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaInvoker.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaInvoker.java
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.binding.corba.impl;
+import java.lang.reflect.Method;
+import java.util.Map;
+
import org.apache.tuscany.sca.binding.corba.impl.exceptions.RequestConfigurationException;
import org.apache.tuscany.sca.binding.corba.impl.reference.DynaCorbaRequest;
import org.apache.tuscany.sca.binding.corba.impl.reference.DynaCorbaResponse;
@@ -34,9 +37,13 @@ import org.osoa.sca.ServiceRuntimeException;
public class CorbaInvoker implements Invoker {
private Object remoteObject;
+ private Class<?> referenceClass;
+ private Map<Method, String> operationsMap;
- public CorbaInvoker(Object remoteObject) {
+ public CorbaInvoker(Object remoteObject, Class<?> referenceClass, Map<Method, String> operationsMap) {
this.remoteObject = remoteObject;
+ this.referenceClass = referenceClass;
+ this.operationsMap = operationsMap;
}
/**
@@ -45,6 +52,8 @@ public class CorbaInvoker implements Invoker {
public Message invoke(Message msg) {
try {
DynaCorbaRequest request = new DynaCorbaRequest(remoteObject, msg.getOperation().getName());
+ request.setReferenceClass(referenceClass);
+ request.setOperationsMap(operationsMap);
if (msg.getOperation().getOutputType() != null) {
request.setOutputType(msg.getOperation().getOutputType().getPhysical());
}
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaReferenceBindingProvider.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaReferenceBindingProvider.java
index dec015be38..3eb665d599 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaReferenceBindingProvider.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/CorbaReferenceBindingProvider.java
@@ -19,10 +19,15 @@
package org.apache.tuscany.sca.binding.corba.impl;
+import java.lang.reflect.Method;
+import java.util.Map;
+
import org.apache.tuscany.sca.binding.corba.CorbaBinding;
+import org.apache.tuscany.sca.binding.corba.impl.util.OperationMapper;
import org.apache.tuscany.sca.host.corba.CorbaHost;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
@@ -37,11 +42,15 @@ public class CorbaReferenceBindingProvider implements ReferenceBindingProvider {
private CorbaHost host;
private RuntimeComponentReference reference;
private Object remoteObject;
+ private Class<?> referenceClass;
+ private Map<Method, String> operationsMap = null;
public CorbaReferenceBindingProvider(CorbaBinding binding, CorbaHost host, RuntimeComponentReference reference) {
this.binding = binding;
this.host = host;
this.reference = reference;
+ this.referenceClass = ((JavaInterface)reference.getInterfaceContract().getInterface()).getJavaClass();
+ operationsMap = OperationMapper.mapMethodToOperation(referenceClass);
}
/**
@@ -52,7 +61,7 @@ public class CorbaReferenceBindingProvider implements ReferenceBindingProvider {
if (remoteObject == null) {
remoteObject = host.lookup(binding.getCorbaname());
}
- return new CorbaInvoker(remoteObject);
+ return new CorbaInvoker(remoteObject, referenceClass, operationsMap);
} catch (Exception e) {
}
return null;
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/DynaCorbaRequest.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/DynaCorbaRequest.java
index fd310a85a8..f4f82c9b88 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/DynaCorbaRequest.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/DynaCorbaRequest.java
@@ -19,7 +19,10 @@
package org.apache.tuscany.sca.binding.corba.impl.reference;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.tuscany.sca.binding.corba.impl.exceptions.CorbaException;
@@ -28,6 +31,7 @@ import org.apache.tuscany.sca.binding.corba.impl.types.TypeTree;
import org.apache.tuscany.sca.binding.corba.impl.types.TypeTreeCreator;
import org.apache.tuscany.sca.binding.corba.impl.types.util.TypeHelpersProxy;
import org.apache.tuscany.sca.binding.corba.impl.types.util.Utils;
+import org.apache.tuscany.sca.binding.corba.impl.util.MethodFinder;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Object;
@@ -44,10 +48,13 @@ public class DynaCorbaRequest {
private TypeTree returnTree;
private Map<String, TypeTree> exceptions = new HashMap<String, TypeTree>();
- private OutputStream outputStream;
private InputStream inputStream;
private ObjectImpl remoteObject;
private String operation;
+ private List<java.lang.Object> arguments = new ArrayList<java.lang.Object>();
+ private List<TypeTree> argumentsTypes = new ArrayList<TypeTree>();
+ private Class<?> referenceClass;
+ private Map<Method, String> operationsMap;
/**
* Creates request.
@@ -56,20 +63,48 @@ public class DynaCorbaRequest {
* @param operation operation to invoke
*/
public DynaCorbaRequest(Object remoteObject, String operation) {
- outputStream = ((ObjectImpl)remoteObject)._request(operation, true);
this.remoteObject = (ObjectImpl)remoteObject;
this.operation = operation;
+ }
+
+ /**
+ * Sets class which will be backed by this reference request
+ * @param referenceClass
+ */
+ public void setReferenceClass(Class<?> referenceClass) {
+ this.referenceClass = referenceClass;
+ }
+ /**
+ * Sets method to operation names mapping
+ * @param operationsMap
+ */
+ public void setOperationsMap(Map<Method, String> operationsMap) {
+ this.operationsMap = operationsMap;
}
/**
- * Adds operation argument
+ * Adds operation argument - stores arguments and caches its TypeTree
*
* @param argument
*/
public void addArgument(java.lang.Object argument) throws RequestConfigurationException {
TypeTree tree = TypeTreeCreator.createTypeTree(argument.getClass());
- TypeHelpersProxy.write(tree.getRootNode(), outputStream, argument);
+ argumentsTypes.add(tree);
+ arguments.add(argument);
+ }
+
+ /**
+ * Passing stored arguments to CORBA communication output stream
+ *
+ * @param outputStream
+ * @throws RequestConfigurationException
+ */
+ private void passArguments(OutputStream outputStream) throws RequestConfigurationException {
+ for (int i = 0; i < arguments.size(); i++) {
+ TypeTree tree = argumentsTypes.get(i);
+ TypeHelpersProxy.write(tree.getRootNode(), outputStream, arguments.get(i));
+ }
}
/**
@@ -88,7 +123,7 @@ public class DynaCorbaRequest {
*/
public void addExceptionType(Class<?> forClass) throws RequestConfigurationException {
TypeTree tree = TypeTreeCreator.createTypeTree(forClass);
- String exceptionId = Utils.getExceptionId(forClass);
+ String exceptionId = Utils.getTypeId(forClass);
exceptions.put(exceptionId, tree);
}
@@ -142,12 +177,35 @@ public class DynaCorbaRequest {
}
/**
+ * Gets operation name which is includes mapping rules
+ * @return
+ */
+ private String getFinalOperationName() {
+ String result = operation;
+ if (referenceClass != null) {
+ Class<?>[] argumentTypes = new Class<?>[arguments.size()];
+ for (int i = 0; i < arguments.size(); i++) {
+ argumentTypes[i] = arguments.get(i).getClass();
+ }
+ Method method = MethodFinder.findMethod(referenceClass, operation, argumentTypes);
+ String newOperation = (String)operationsMap.get(method);
+ if (newOperation != null) {
+ result = newOperation;
+ }
+ }
+ return result;
+ }
+
+ /**
* Invokes previously configured request
*
* @return
*/
public DynaCorbaResponse invoke() throws Exception {
DynaCorbaResponse response = new DynaCorbaResponse();
+ String finalOperationName = getFinalOperationName();
+ OutputStream outputStream = ((ObjectImpl)remoteObject)._request(finalOperationName, true);
+ passArguments(outputStream);
try {
inputStream = remoteObject._invoke(outputStream);
if (inputStream != null && returnTree != null) {
@@ -164,8 +222,11 @@ public class DynaCorbaRequest {
}
return response;
}
-
- public void release() {
+
+ /**
+ * Releases request resources
+ */
+ private void release() {
remoteObject._releaseReply(inputStream);
}
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceInstanceCreator.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceInstanceCreator.java
index 7965ecb86a..514d7055a8 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceInstanceCreator.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceInstanceCreator.java
@@ -59,7 +59,7 @@ public class InterfaceInstanceCreator {
enhancer.setCallbackTypes(new Class[] {NoOp.class, MethodInterceptor.class});
Class<?> newClass = enhancer.createClass();
Enhancer.registerStaticCallbacks(newClass, new Callback[] {NoOp.INSTANCE,
- new InterfaceMethodInterceptor(reference)});
+ new InterfaceMethodInterceptor(reference, forClass)});
result = newClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceMethodInterceptor.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceMethodInterceptor.java
index 2642601057..7fba091b41 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceMethodInterceptor.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/reference/InterfaceMethodInterceptor.java
@@ -33,9 +33,11 @@ import org.omg.CORBA.Object;
public class InterfaceMethodInterceptor implements MethodInterceptor {
private Object reference;
+ private Class<?> javaClass;
- public InterfaceMethodInterceptor(Object reference) {
+ public InterfaceMethodInterceptor(Object reference, Class<?> javaClass) {
this.reference = reference;
+ this.javaClass = javaClass;
}
/**
@@ -47,6 +49,7 @@ public class InterfaceMethodInterceptor implements MethodInterceptor {
java.lang.Object[] arguments,
MethodProxy arg3) throws Throwable {
DynaCorbaRequest request = new DynaCorbaRequest(reference, method.getName());
+ request.setReferenceClass(javaClass);
for (int i = 0; i < arguments.length; i++) {
request.addArgument(arguments[i]);
}
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/service/DynaCorbaServant.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/service/DynaCorbaServant.java
index cece057baa..6c7e2b1238 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/service/DynaCorbaServant.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/service/DynaCorbaServant.java
@@ -20,6 +20,7 @@
package org.apache.tuscany.sca.binding.corba.impl.service;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -31,8 +32,10 @@ import org.apache.tuscany.sca.binding.corba.impl.types.TypeTree;
import org.apache.tuscany.sca.binding.corba.impl.types.TypeTreeCreator;
import org.apache.tuscany.sca.binding.corba.impl.types.util.TypeHelpersProxy;
import org.apache.tuscany.sca.binding.corba.impl.types.util.Utils;
+import org.apache.tuscany.sca.binding.corba.impl.util.OperationMapper;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.portable.InputStream;
@@ -46,19 +49,63 @@ import org.omg.CORBA.portable.ResponseHandler;
*/
public class DynaCorbaServant extends ObjectImpl implements InvokeHandler {
- private static String[] DEFAULT_IDS = {"IDL:default:1.0"};
private RuntimeComponentService service;
private Binding binding;
- private String[] ids = DEFAULT_IDS;
- private Map<String, OperationTypes> operationsCache = new HashMap<String, OperationTypes>();
+ private String[] ids;
+ private Map<Operation, OperationTypes> operationsCache = new HashMap<Operation, OperationTypes>();
+ private Class<?> javaClass;
+ private Map<String, Method> operationsMap;
+ private Map<Method, Operation> methodOperationMapping;
public DynaCorbaServant(RuntimeComponentService service, Binding binding) throws RequestConfigurationException {
this.service = service;
this.binding = binding;
+ this.javaClass = ((JavaInterface)service.getInterfaceContract().getInterface()).getJavaClass();
+ this.operationsMap = OperationMapper.mapOperationToMethod(javaClass);
cacheOperationTypes(service.getInterfaceContract().getInterface().getOperations());
+ createMethod2OperationMapping();
+ setDefaultIds();
+ }
+ /**
+ * Maps Java methods to Tuscany operations
+ */
+ private void createMethod2OperationMapping() {
+ // for every operation find all methods with the same name, then
+ // compare operations and methods parameters
+ this.methodOperationMapping = new HashMap<Method, Operation>();
+ for (Operation operation : service.getInterfaceContract().getInterface().getOperations()) {
+ List<DataType> inputTypes = operation.getInputType().getLogical();
+ Method[] methods = javaClass.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].getName().equals(operation.getName()) && inputTypes.size() == methods[i]
+ .getParameterTypes().length) {
+ Class<?>[] parameterTypes = methods[i].getParameterTypes();
+ int j = 0;
+ boolean parameterMatch = true;
+ for (DataType dataType : inputTypes) {
+ if (!dataType.getPhysical().equals(parameterTypes[j])) {
+ parameterMatch = false;
+ break;
+ }
+ j++;
+ }
+ if (parameterMatch) {
+ // match found
+ methodOperationMapping.put(methods[i], operation);
+ break;
+ }
+ }
+ }
+
+ }
}
+ /**
+ * Caches TypeTree for every operation in backed component
+ * @param operations
+ * @throws RequestConfigurationException
+ */
private void cacheOperationTypes(List<Operation> operations) throws RequestConfigurationException {
for (Operation operation : operations) {
try {
@@ -80,41 +127,39 @@ public class DynaCorbaServant extends ObjectImpl implements InvokeHandler {
}
operationTypes.setInputType(inputInstances);
- operationsCache.put(operation.getName(), operationTypes);
+ operationsCache.put(operation, operationTypes);
} catch (RequestConfigurationException e) {
throw e;
}
}
}
+ /**
+ * Sets CORBA object ID
+ * @param ids
+ */
public void setIds(String[] ids) {
for (int i = 0; i < ids.length; i++) {
if (ids[i] == null || ids[i].length() == 0) {
- this.ids = DEFAULT_IDS;
+ // if invalid id was passed then set to default
+ setDefaultIds();
return;
}
}
this.ids = ids;
}
- public OutputStream _invoke(String method, InputStream in, ResponseHandler rh) {
-
+ public OutputStream _invoke(String operationName, InputStream in, ResponseHandler rh) {
Operation operation = null;
-
- List<Operation> operations = service.getInterfaceContract().getInterface().getOperations();
+ Method method = operationsMap.get(operationName);
// searching for proper operation
- for (Operation oper : operations) {
- if (oper.getName().equals(method)) {
- operation = oper;
- break;
- }
- }
+ operation = methodOperationMapping.get(method);
if (operation == null) {
// operation wasn't found
throw new org.omg.CORBA.BAD_OPERATION(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
} else {
List<Object> inputInstances = new ArrayList<Object>();
- OperationTypes types = operationsCache.get(operation.getName());
+ OperationTypes types = operationsCache.get(operation);
try {
// retrieving in arguments
for (TypeTree tree : types.getInputType()) {
@@ -129,19 +174,19 @@ public class DynaCorbaServant extends ObjectImpl implements InvokeHandler {
try {
// invocation and sending result
Object result = service.getRuntimeWire(binding).invoke(operation, inputInstances.toArray());
+ OutputStream out = rh.createReply();
if (types.getOutputType() != null) {
- OutputStream out = rh.createReply();
TypeTree tree = types.getOutputType();
TypeHelpersProxy.write(tree.getRootNode(), out, result);
- return out;
}
+ return out;
} catch (InvocationTargetException ie) {
// handling user exception
try {
OutputStream out = rh.createExceptionReply();
Class<?> exceptionClass = ie.getTargetException().getClass();
TypeTree tree = TypeTreeCreator.createTypeTree(exceptionClass);
- String exceptionId = Utils.getExceptionId(exceptionClass);
+ String exceptionId = Utils.getTypeId(exceptionClass);
out.write_string(exceptionId);
TypeHelpersProxy.write(tree.getRootNode(), out, ie.getTargetException());
return out;
@@ -163,4 +208,12 @@ public class DynaCorbaServant extends ObjectImpl implements InvokeHandler {
return ids;
}
+ /**
+ * Sets servant ID to default, based on Java class name
+ */
+ private void setDefaultIds() {
+ String id = Utils.getTypeId(javaClass);
+ this.ids = new String[] {id};
+ }
+
}
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/types/util/Utils.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/types/util/Utils.java
index 4c1467d3c3..de381f995b 100644
--- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/types/util/Utils.java
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/types/util/Utils.java
@@ -26,7 +26,7 @@ public class Utils {
* @param forClass
* @return
*/
- public static String getExceptionId(Class<?> forClass) {
+ public static String getTypeId(Class<?> forClass) {
String result = forClass.getName().replace('.', '/');
result = result.replaceAll("Package", "");
result = "IDL:" + result + ":1.0";
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/MethodFinder.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/MethodFinder.java
new file mode 100644
index 0000000000..ea18a33ce0
--- /dev/null
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/MethodFinder.java
@@ -0,0 +1,96 @@
+/*
+ * 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.binding.corba.impl.util;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility for finding method in given class.
+ */
+public class MethodFinder {
+
+ private static Map<Class<?>, Class<?>> boxingMapping;
+
+ static {
+ boxingMapping = new HashMap<Class<?>, Class<?>>();
+ boxingMapping.put(boolean.class, Boolean.class);
+ boxingMapping.put(byte.class, Byte.class);
+ boxingMapping.put(short.class, Short.class);
+ boxingMapping.put(char.class, Character.class);
+ boxingMapping.put(int.class, Integer.class);
+ boxingMapping.put(long.class, Long.class);
+ boxingMapping.put(float.class, Float.class);
+ boxingMapping.put(double.class, Double.class);
+ }
+
+ /**
+ * Converts primitive class to its object equivalent.
+ *
+ * @param parameter class to convert
+ * @return object equivalent for primitive type. If parameter wasn't
+ * primitive then returns parameter.
+ */
+ private static Class<?> normalizePrimitive(Class<?> parameter) {
+ Class<?> result = boxingMapping.get(parameter);
+ if (result != null) {
+ return result;
+ } else {
+ // not a primitive - no need to normalize
+ return parameter;
+ }
+ }
+
+ /**
+ * Finds appropriate method. This method ignores difference between
+ * primitive types and theirs object equivalents. Ie. if we want to find
+ * method "get" in java.util.List with only one parameter, which type is
+ * Integer then we'll obtain method get(int).
+ *
+ * @param forClass class which possibly contains desired method
+ * @param methodName desired methods name
+ * @param parameterTypes desired methods parameter types
+ * @return desired method, if no method was found then null will be returned
+ */
+ public static Method findMethod(Class<?> forClass, String methodName, Class<?>[] parameterTypes) {
+ Method[] methods = forClass.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].getName().equals(methodName)) {
+ Class<?>[] methodPTypes = methods[i].getParameterTypes();
+ if (methodPTypes.length == parameterTypes.length) {
+ boolean parameterMatch = true;
+ for (int j = 0; j < methodPTypes.length; j++) {
+ Class<?> nMethodPType = normalizePrimitive(methodPTypes[j]);
+ Class<?> nParameterType = normalizePrimitive(parameterTypes[j]);
+ if (!nMethodPType.equals(nParameterType)) {
+ parameterMatch = false;
+ break;
+ }
+ }
+ if (parameterMatch) {
+ return methods[i];
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/OperationMapper.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/OperationMapper.java
new file mode 100644
index 0000000000..d5f31dd723
--- /dev/null
+++ b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/util/OperationMapper.java
@@ -0,0 +1,516 @@
+/*
+ * 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.binding.corba.impl.util;
+
+import java.lang.reflect.Method;
+import java.rmi.RemoteException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.omg.CORBA.portable.IDLEntity;
+
+/**
+ * @version $Rev$ $Date$
+ * @see UtilInitializer
+ */
+public final class OperationMapper {
+
+ private static Set<Class<?>> getAllInterfaces(Class<?> intfClass) {
+ Set<Class<?>> allInterfaces = new LinkedHashSet<Class<?>>();
+
+ LinkedList<Class<?>> stack = new LinkedList<Class<?>>();
+ stack.addFirst(intfClass);
+
+ while (!stack.isEmpty()) {
+ Class<?> intf = stack.removeFirst();
+ allInterfaces.add(intf);
+ stack.addAll(0, Arrays.asList(intf.getInterfaces()));
+ }
+
+ return allInterfaces;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<Method, String> mapMethodToOperation(Class<?> intfClass) {
+ return iiopMap(intfClass, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, Method> mapOperationToMethod(Class<?> intfClass) {
+ return iiopMap(intfClass, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Map iiopMap(Class<?> intfClass, boolean operationToMethod) {
+ Method[] methods = getAllMethods(intfClass);
+
+ // find every valid getter
+ Map<Method, String> getterByMethod = new HashMap<Method, String>(methods.length);
+ Map<String, Method> getterByName = new HashMap<String, Method>(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ String methodName = method.getName();
+
+ // no arguments allowed
+ if (method.getParameterTypes().length != 0) {
+ continue;
+ }
+
+ // must start with get or is
+ String verb;
+ if (methodName.startsWith("get") && methodName.length() > 3 && method.getReturnType() != void.class) {
+ verb = "get";
+ } else if (methodName.startsWith("is") && methodName.length() > 2 && method.getReturnType() == boolean.class) {
+ verb = "is";
+ } else {
+ continue;
+ }
+
+ // must only throw Remote or Runtime Exceptions
+ boolean exceptionsValid = true;
+ Class[] exceptionTypes = method.getExceptionTypes();
+ for (int j = 0; j < exceptionTypes.length; j++) {
+ Class<?> exceptionType = exceptionTypes[j];
+ if (!RemoteException.class.isAssignableFrom(exceptionType) &&
+ !RuntimeException.class.isAssignableFrom(exceptionType) &&
+ !Error.class.isAssignableFrom(exceptionType)) {
+ exceptionsValid = false;
+ break;
+ }
+ }
+ if (!exceptionsValid) {
+ continue;
+ }
+
+ String propertyName;
+ if (methodName.length() > verb.length() + 1 && Character.isUpperCase(methodName.charAt(verb.length() + 1))) {
+ propertyName = methodName.substring(verb.length());
+ } else {
+ propertyName = Character.toLowerCase(methodName.charAt(verb.length())) + methodName.substring(verb.length() + 1);
+ }
+ getterByMethod.put(method, propertyName);
+ getterByName.put(propertyName, method);
+ }
+
+ Map<Method, String> setterByMethod = new HashMap<Method, String>(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ String methodName = method.getName();
+
+ // must have exactally one arg
+ if (method.getParameterTypes().length != 1) {
+ continue;
+ }
+
+ // must return non void
+ if (method.getReturnType() != void.class) {
+ continue;
+ }
+
+ // must start with set
+ if (!methodName.startsWith("set") || methodName.length() <= 3) {
+ continue;
+ }
+
+ // must only throw Remote or Runtime Exceptions
+ boolean exceptionsValid = true;
+ Class<?>[] exceptionTypes = method.getExceptionTypes();
+ for (int j = 0; j < exceptionTypes.length; j++) {
+ Class<?> exceptionType = exceptionTypes[j];
+ if (!RemoteException.class.isAssignableFrom(exceptionType) &&
+ !RuntimeException.class.isAssignableFrom(exceptionType) &&
+ !Error.class.isAssignableFrom(exceptionType)) {
+ exceptionsValid = false;
+ break;
+ }
+ }
+ if (!exceptionsValid) {
+ continue;
+ }
+
+ String propertyName;
+ if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) {
+ propertyName = methodName.substring(3);
+ } else {
+ propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
+ }
+
+ // must have a matching getter
+ Method getter = (Method) getterByName.get(propertyName);
+ if (getter == null) {
+ continue;
+ }
+
+ // setter property must match getter return value
+ if (!method.getParameterTypes()[0].equals(getter.getReturnType())) {
+ continue;
+ }
+ setterByMethod.put(method, propertyName);
+ }
+
+ // index the methods by name... used to determine which methods are overloaded
+ HashMap<String, List<Method>> overloadedMethods = new HashMap<String, List<Method>>(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
+ continue;
+ }
+ String methodName = method.getName();
+ List<Method> methodList = overloadedMethods.get(methodName);
+ if (methodList == null) {
+ methodList = new LinkedList<Method>();
+ overloadedMethods.put(methodName, methodList);
+ }
+ methodList.add(method);
+ }
+
+ // index the methods by lower case name... used to determine which methods differ only by case
+ Map<String, Set<String>> caseCollisionMethods = new HashMap<String, Set<String>>(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
+ continue;
+ }
+ String lowerCaseMethodName = method.getName().toLowerCase();
+ Set<String> methodSet = caseCollisionMethods.get(lowerCaseMethodName);
+ if (methodSet == null) {
+ methodSet = new HashSet<String>();
+ caseCollisionMethods.put(lowerCaseMethodName, methodSet);
+ }
+ methodSet.add(method.getName());
+ }
+
+ String className = getClassName(intfClass);
+ Map iiopMap = new HashMap(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+
+ String iiopName = (String) getterByMethod.get(method);
+ if (iiopName != null) {
+ // if we have a leading underscore prepend with J
+ if (iiopName.charAt(0) == '_') {
+ iiopName = "J_get_" + iiopName.substring(1);
+ } else {
+ iiopName = "_get_" + iiopName;
+ }
+ } else {
+ iiopName = (String) setterByMethod.get(method);
+ if (iiopName != null) {
+ // if we have a leading underscore prepend with J
+ if (iiopName.charAt(0) == '_') {
+ iiopName = "J_set_" + iiopName.substring(1);
+ } else {
+ iiopName = "_set_" + iiopName;
+ }
+ } else {
+ iiopName = method.getName();
+
+ // if we have a leading underscore prepend with J
+ if (iiopName.charAt(0) == '_') {
+ iiopName = "J" + iiopName;
+ }
+ }
+ }
+
+ // if this name only differs by case add the case index to the end
+ Set<String> caseCollisions = caseCollisionMethods.get(method.getName().toLowerCase());
+ if (caseCollisions != null && caseCollisions.size() > 1) {
+ iiopName += upperCaseIndexString(iiopName);
+ }
+
+ // if this is an overloaded method append the parameter string
+ List<Method> overloads = overloadedMethods.get(method.getName());
+ if (overloads != null && overloads.size() > 1) {
+ iiopName += buildOverloadParameterString(method.getParameterTypes());
+ }
+
+ // if we have a leading underscore prepend with J
+ iiopName = replace(iiopName, '$', "U0024");
+
+ // if we have matched a keyword prepend with an underscore
+ if (keywords.contains(iiopName.toLowerCase())) {
+ iiopName = "_" + iiopName;
+ }
+
+ // if the name is the same as the class name, append an underscore
+ if (iiopName.equalsIgnoreCase(className)) {
+ iiopName += "_";
+ }
+
+ if (operationToMethod) {
+ iiopMap.put(iiopName, method);
+ } else {
+ iiopMap.put(method, iiopName);
+ }
+ }
+
+ return iiopMap;
+ }
+
+ private static Method[] getAllMethods(Class<?> intfClass) {
+ List<Method> methods = new LinkedList<Method>();
+ for (Iterator<Class<?>> iterator = getAllInterfaces(intfClass).iterator(); iterator.hasNext();) {
+ Class<?> intf = iterator.next();
+ methods.addAll(Arrays.asList(intf.getDeclaredMethods()));
+ }
+
+ return (Method[]) methods.toArray(new Method[methods.size()]);
+ }
+
+ /**
+ * Return the a string containing an underscore '_' index of each uppercase
+ * character in the IIOP name. This is used for distinction of names that
+ * only differ by case, since CORBA does not support case sensitive names.
+ */
+ private static String upperCaseIndexString(String iiopName) {
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < iiopName.length(); i++) {
+ char c = iiopName.charAt(i);
+ if (Character.isUpperCase(c)) {
+ stringBuffer.append('_').append(i);
+ }
+ }
+ return stringBuffer.toString();
+ }
+
+ /**
+ * Replaces any occurances of the specified "oldChar" with the new string.
+ * This is used to replace occurances if '$' in CORBA names since '$' is a
+ * special character
+ */
+ private static String replace(String source, char oldChar, String newString) {
+ StringBuffer stringBuffer = new StringBuffer(source.length());
+ for (int i = 0; i < source.length(); i++) {
+ char c = source.charAt(i);
+ if (c == oldChar) {
+ stringBuffer.append(newString);
+ } else {
+ stringBuffer.append(c);
+ }
+ }
+ return stringBuffer.toString();
+ }
+
+ /**
+ * Return the a string containing a double underscore '__' list of parameter
+ * types encoded using the Java to IDL rules. This is used for distinction
+ * of methods that only differ by parameter lists.
+ */
+ private static String buildOverloadParameterString(Class<?>[] parameterTypes) {
+ String name = "";
+ if (parameterTypes.length == 0) {
+ name += "__";
+ } else {
+ for (int i = 0; i < parameterTypes.length; i++) {
+ Class<?> parameterType = parameterTypes[i];
+ name += buildOverloadParameterString(parameterType);
+ }
+ }
+ return name.replace('.', '_');
+ }
+
+ /**
+ * Returns a single parameter type encoded using the Java to IDL rules.
+ */
+ private static String buildOverloadParameterString(Class<?> parameterType) {
+ String name = "_";
+
+ int arrayDimensions = 0;
+ while (parameterType.isArray()) {
+ arrayDimensions++;
+ parameterType = parameterType.getComponentType();
+ }
+
+ // arrays start with org_omg_boxedRMI_
+ if (arrayDimensions > 0) {
+ name += "_org_omg_boxedRMI";
+ }
+
+ // IDLEntity types must be prefixed with org_omg_boxedIDL_
+ if (IDLEntity.class.isAssignableFrom(parameterType)) {
+ name += "_org_omg_boxedIDL";
+ }
+
+ // add package... some types have special mappings in corba
+ String packageName = (String)specialTypePackages.get(parameterType.getName());
+ if (packageName == null) {
+ packageName = getPackageName(parameterType.getName());
+ }
+ if (packageName.length() > 0) {
+ name += "_" + packageName;
+ }
+
+ // arrays now contain a dimension indicator
+ if (arrayDimensions > 0) {
+ name += "_" + "seq" + arrayDimensions;
+ }
+
+ // add the class name
+ String className = (String)specialTypeNames.get(parameterType.getName());
+ if (className == null) {
+ className = buildClassName(parameterType);
+ }
+ name += "_" + className;
+
+ return name;
+ }
+
+ /**
+ * Returns a string containing an encoded class name.
+ */
+ private static String buildClassName(Class<?> type) {
+ if (type.isArray()) {
+ throw new IllegalArgumentException("type is an array: " + type);
+ }
+
+ // get the classname
+ String typeName = type.getName();
+ int endIndex = typeName.lastIndexOf('.');
+ if (endIndex < 0) {
+ return typeName;
+ }
+ StringBuffer className = new StringBuffer(typeName.substring(endIndex + 1));
+
+ // for innerclasses replace the $ separator with two underscores
+ // we can't just blindly replace all $ characters since class names can
+ // contain the $ character
+ if (type.getDeclaringClass() != null) {
+ String declaringClassName = getClassName(type.getDeclaringClass());
+ assert className.toString().startsWith(declaringClassName + "$");
+ className.replace(declaringClassName.length(), declaringClassName.length() + 1, "__");
+ }
+
+ // if we have a leading underscore prepend with J
+ if (className.charAt(0) == '_') {
+ className.insert(0, "J");
+ }
+ return className.toString();
+ }
+
+ private static String getClassName(Class<?> type) {
+ if (type.isArray()) {
+ throw new IllegalArgumentException("type is an array: " + type);
+ }
+
+ // get the classname
+ String typeName = type.getName();
+ int endIndex = typeName.lastIndexOf('.');
+ if (endIndex < 0) {
+ return typeName;
+ }
+ return typeName.substring(endIndex + 1);
+ }
+
+ private static String getPackageName(String interfaceName) {
+ int endIndex = interfaceName.lastIndexOf('.');
+ if (endIndex < 0) {
+ return "";
+ }
+ return interfaceName.substring(0, endIndex);
+ }
+
+ private static final Map<String, String> specialTypeNames;
+ private static final Map<String, String> specialTypePackages;
+ private static final Set<String> keywords;
+
+ static {
+ specialTypeNames = new HashMap<String, String>();
+ specialTypeNames.put("boolean", "boolean");
+ specialTypeNames.put("char", "wchar");
+ specialTypeNames.put("byte", "octet");
+ specialTypeNames.put("short", "short");
+ specialTypeNames.put("int", "long");
+ specialTypeNames.put("long", "long_long");
+ specialTypeNames.put("float", "float");
+ specialTypeNames.put("double", "double");
+ specialTypeNames.put("java.lang.Class", "ClassDesc");
+ specialTypeNames.put("java.lang.String", "WStringValue");
+ specialTypeNames.put("org.omg.CORBA.Object", "Object");
+
+ specialTypePackages = new HashMap<String, String>();
+ specialTypePackages.put("boolean", "");
+ specialTypePackages.put("char", "");
+ specialTypePackages.put("byte", "");
+ specialTypePackages.put("short", "");
+ specialTypePackages.put("int", "");
+ specialTypePackages.put("long", "");
+ specialTypePackages.put("float", "");
+ specialTypePackages.put("double", "");
+ specialTypePackages.put("java.lang.Class", "javax.rmi.CORBA");
+ specialTypePackages.put("java.lang.String", "CORBA");
+ specialTypePackages.put("org.omg.CORBA.Object", "");
+
+ keywords = new HashSet<String>();
+ keywords.add("abstract");
+ keywords.add("any");
+ keywords.add("attribute");
+ keywords.add("boolean");
+ keywords.add("case");
+ keywords.add("char");
+ keywords.add("const");
+ keywords.add("context");
+ keywords.add("custom");
+ keywords.add("default");
+ keywords.add("double");
+ keywords.add("enum");
+ keywords.add("exception");
+ keywords.add("factory");
+ keywords.add("false");
+ keywords.add("fixed");
+ keywords.add("float");
+ keywords.add("in");
+ keywords.add("inout");
+ keywords.add("interface");
+ keywords.add("long");
+ keywords.add("module");
+ keywords.add("native");
+ keywords.add("object");
+ keywords.add("octet");
+ keywords.add("oneway");
+ keywords.add("out");
+ keywords.add("private");
+ keywords.add("public");
+ keywords.add("raises");
+ keywords.add("readonly");
+ keywords.add("sequence");
+ keywords.add("short");
+ keywords.add("string");
+ keywords.add("struct");
+ keywords.add("supports");
+ keywords.add("switch");
+ keywords.add("true");
+ keywords.add("truncatable");
+ keywords.add("typedef");
+ keywords.add("union");
+ keywords.add("unsigned");
+ keywords.add("valuebase");
+ keywords.add("valuetype");
+ keywords.add("void");
+ keywords.add("wchar");
+ keywords.add("wstring");
+ }
+
+}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/CorbaTypesTestCase.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/CorbaTypesTestCase.java
index 4419dce132..e41a60d86a 100644
--- a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/CorbaTypesTestCase.java
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/CorbaTypesTestCase.java
@@ -558,8 +558,6 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
try {
@@ -568,8 +566,6 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
try {
@@ -578,17 +574,13 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
-
+
try {
request = new DynaCorbaRequest(refArraysSetter, "whatever");
request.setOutputType(SomeStruct.class);
} catch (Exception e) {
fail();
- } finally {
- request.release();
}
}
@@ -604,8 +596,6 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
try {
@@ -614,8 +604,6 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
try {
@@ -624,8 +612,6 @@ public class CorbaTypesTestCase {
fail();
} catch (Exception e) {
assertTrue(e instanceof RequestConfigurationException);
- } finally {
- request.release();
}
try {
@@ -633,8 +619,6 @@ public class CorbaTypesTestCase {
request.setOutputType(Color.class);
} catch (Exception e) {
fail();
- } finally {
- request.release();
}
}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MappingTestInterface.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MappingTestInterface.java
new file mode 100644
index 0000000000..11bcdc195e
--- /dev/null
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MappingTestInterface.java
@@ -0,0 +1,45 @@
+/*
+ * 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.binding.corba.testing;
+
+/**
+ * Interface that can be tested for operations mapping
+ */
+public interface MappingTestInterface {
+
+ int getIntField();
+
+ void setIntField(int intField);
+
+ boolean isBoolField();
+
+ void setBoolField(boolean boolField);
+
+ void overloadedName();
+
+ void overloadedName(String arg1);
+
+ void overloadedName(String arg1, int arg2);
+
+ void caseCollision();
+
+ void CaseCollision();
+
+}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MethodFinderTestCase.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MethodFinderTestCase.java
new file mode 100644
index 0000000000..fa64afca8b
--- /dev/null
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/MethodFinderTestCase.java
@@ -0,0 +1,69 @@
+/*
+ * 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.binding.corba.testing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.binding.corba.impl.util.MethodFinder;
+import org.junit.Test;
+
+/**
+ * Various tests for MethodFinder
+ */
+public class MethodFinderTestCase {
+
+ /**
+ * Tests finding existing methods
+ */
+ @Test
+ public void test_findExistingMethod() {
+ try {
+ String methodName = "rotateLeft";
+ Method sample = Integer.class.getMethod(methodName, new Class<?>[] {int.class, int.class});
+ Method m1 = MethodFinder.findMethod(Integer.class, methodName, new Class<?>[] {int.class, int.class});
+ Method m2 =
+ MethodFinder.findMethod(Integer.class, methodName, new Class<?>[] {Integer.class, Integer.class});
+ assertEquals(sample, m1);
+ assertEquals(sample, m2);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ /**
+ * Tests null result value for not existing method
+ */
+ @Test
+ public void test_findNotExistingMethod() {
+ try {
+ String methodName = "rotateLeft";
+ Method method = MethodFinder.findMethod(Integer.class, methodName, new Class<?>[] {});
+ assertEquals(null, method);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/OperationMappingTestCase.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/OperationMappingTestCase.java
new file mode 100644
index 0000000000..8d3f34f48c
--- /dev/null
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/OperationMappingTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * 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.binding.corba.testing;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tuscany.sca.binding.corba.impl.util.OperationMapper;
+import org.junit.Test;
+
+/**
+ * Various tests for OperationsMapping
+ */
+public class OperationMappingTestCase {
+
+ /**
+ * Tests if Java2IDLUtil maps methods to operations correctly
+ */
+ @Test
+ public void test_mappingRules() {
+ Map<Method, String> met2op = OperationMapper.mapMethodToOperation(MappingTestInterface.class);
+ for (Method method : met2op.keySet()) {
+ String name = method.getName();
+ String translatedName = met2op.get(method);
+ if (name.equals("getIntField")) {
+ assertEquals("_get_intField", translatedName);
+ } else if (name.equals("setIntField")) {
+ assertEquals("_set_intField", translatedName);
+ } else if (name.equals("isBoolField")) {
+ assertEquals("_get_boolField", translatedName);
+ } else if (name.equals("setBoolField")) {
+ assertEquals("_set_boolField", translatedName);
+ } else if (name.equals("overloadedName") && method.getParameterTypes().length == 0) {
+ assertEquals("overloadedName__", translatedName);
+ } else if (name.equals("overloadedName") && method.getParameterTypes().length == 1) {
+ assertEquals("overloadedName__CORBA_WStringValue", translatedName);
+ } else if (name.equals("overloadedName") && method.getParameterTypes().length == 2) {
+ assertEquals("overloadedName__CORBA_WStringValue__long", translatedName);
+ } else if (name.equals("caseCollision")) {
+ assertEquals("caseCollision_4", translatedName);
+ } else if (name.equals("CaseCollision")) {
+ assertEquals("CaseCollision_0_4", translatedName);
+ }
+ }
+ }
+
+}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterface.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterface.java
index 8c74fd3a8c..1fcacca732 100644
--- a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterface.java
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestInterface.java
@@ -21,8 +21,10 @@ package org.apache.tuscany.sca.binding.corba.testing.service.mocks;
import java.util.List;
-import org.apache.tuscany.sca.interfacedef.Interface;
+import javax.xml.namespace.QName;
+
import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.IntentAttachPointType;
import org.apache.tuscany.sca.policy.PolicySet;
@@ -30,12 +32,14 @@ import org.apache.tuscany.sca.policy.PolicySet;
/**
* Mock TestInterface implementation. Only few methods needs to be implemented.
*/
-public class TestInterface implements Interface {
+public class TestInterface implements JavaInterface {
private List<Operation> operations;
+ private Class<?> javaClass;
- public TestInterface(List<Operation> opearations) {
+ public TestInterface(List<Operation> opearations, Class<?> javaClass) {
this.operations = opearations;
+ this.javaClass = javaClass;
}
public List<Operation> getOperations() {
@@ -94,4 +98,41 @@ public class TestInterface implements Interface {
return null;
}
+ public Class<?> getCallbackClass() {
+ return null;
+ }
+
+ public Class<?> getJavaClass() {
+ return javaClass;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public QName getQName() {
+ return null;
+ }
+
+ public void setCallbackClass(Class<?> arg0) {
+ }
+
+ public void setJavaClass(Class<?> javaClass) {
+ this.javaClass = javaClass;
+ }
+
+ public void setName(String arg0) {
+ }
+
+ public void setQName(QName arg0) {
+
+ }
+
+ public boolean isUnresolved() {
+ return false;
+ }
+
+ public void setUnresolved(boolean arg0) {
+ }
+
}
diff --git a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeComponentService.java b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeComponentService.java
index 58793c044e..e105c5f3de 100644
--- a/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeComponentService.java
+++ b/java/sca/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestRuntimeComponentService.java
@@ -73,7 +73,7 @@ public class TestRuntimeComponentService implements RuntimeComponentService {
operation.setName(methods[i].getName());
}
}
- TestInterface iface = new TestInterface(operations);
+ TestInterface iface = new TestInterface(operations, invocationTarget.getClass());
interfaceContract = new TestInterfaceContract();
interfaceContract.setInterface(iface);
}