summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-1.x/modules/binding-erlang-runtime
diff options
context:
space:
mode:
authorwjaniszewski <wjaniszewski@13f79535-47bb-0310-9956-ffa450edef68>2009-04-16 18:01:41 +0000
committerwjaniszewski <wjaniszewski@13f79535-47bb-0310-9956-ffa450edef68>2009-04-16 18:01:41 +0000
commitca64a758cac9b5bd066eda16d569f1a0e3952c9e (patch)
tree75ab46a42e06450187bc6757474a4c0539ef974a /branches/sca-java-1.x/modules/binding-erlang-runtime
parentc86f42066a6a005d52f534694aecd6fdc1692217 (diff)
Added support for Erlang Atoms
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@765708 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-1.x/modules/binding-erlang-runtime')
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java23
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java62
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AnnotatedListTypeHelper.java71
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AtomTypeHelper.java39
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/ListTypeHelper.java9
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TupleTypeHelper.java9
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java73
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/meta/ErlangAtom.java28
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/AtomTuple.java30
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxInterface.java14
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxListener.java18
-rw-r--r--branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/ReferenceServiceTestCase.java69
12 files changed, 393 insertions, 52 deletions
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java
index 6750e292d9..2fe9ae38b9 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java
@@ -19,12 +19,14 @@
package org.apache.tuscany.sca.binding.erlang.impl;
+import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tuscany.sca.binding.erlang.ErlangBinding;
import org.apache.tuscany.sca.binding.erlang.impl.exceptions.ErlangException;
import org.apache.tuscany.sca.binding.erlang.impl.types.TypeHelpersProxy;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
@@ -81,9 +83,13 @@ public class ErlangInvoker implements Invoker {
}
tmpMbox = node.createMbox();
Object[] args = msg.getBody();
+ Method jmethod = ((JavaOperation) msg.getOperation())
+ .getJavaMethod();
// create and send msg with self pid in the beginning
- OtpErlangObject[] argsArray = { tmpMbox.self(),
- TypeHelpersProxy.toErlang(args) };
+ OtpErlangObject[] argsArray = {
+ tmpMbox.self(),
+ TypeHelpersProxy.toErlang(args, jmethod
+ .getParameterAnnotations()) };
OtpErlangObject otpArgs = new OtpErlangTuple(argsArray);
tmpMbox.send(msg.getOperation().getName(), binding.getNode(),
otpArgs);
@@ -96,7 +102,8 @@ public class ErlangInvoker implements Invoker {
}
OtpErlangObject result = resultMsg.getMsg();
msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation()
- .getOutputType().getPhysical()));
+ .getOutputType().getPhysical(), jmethod
+ .getAnnotations()));
}
} catch (InterruptedException e) {
// TODO: externalize message?
@@ -129,8 +136,10 @@ public class ErlangInvoker implements Invoker {
}
other = new OtpPeer(binding.getNode());
connection = self.connect(other);
- OtpErlangList params = TypeHelpersProxy
- .toErlangAsList((Object[]) msg.getBody());
+ Method jmethod = ((JavaOperation) msg.getOperation())
+ .getJavaMethod();
+ OtpErlangList params = TypeHelpersProxy.toErlangAsList(msg
+ .getBody(), jmethod.getParameterAnnotations());
OtpErlangTuple message = MessageHelper.rpcMessage(self.pid(), self
.createRef(), binding.getModule(), msg.getOperation()
.getName(), params);
@@ -152,8 +161,10 @@ public class ErlangInvoker implements Invoker {
reportProblem(msg, e);
msg.setBody(null);
} else if (msg.getOperation().getOutputType() != null) {
+ jmethod.getAnnotations();
msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation()
- .getOutputType().getPhysical()));
+ .getOutputType().getPhysical(), jmethod
+ .getAnnotations()));
}
} catch (OtpAuthException e) {
// TODO: externalize message?
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java
index e42b93c313..26b772f5e3 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java
@@ -20,7 +20,9 @@
package org.apache.tuscany.sca.binding.erlang.impl;
import java.io.IOException;
+import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@@ -30,6 +32,7 @@ import org.apache.tuscany.sca.binding.erlang.ErlangBinding;
import org.apache.tuscany.sca.binding.erlang.impl.types.TypeHelpersProxy;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import com.ericsson.otp.erlang.OtpAuthException;
@@ -104,6 +107,7 @@ public class ServiceExecutor implements Runnable {
argsList = new OtpErlangList(args);
}
if (!nodeElement.getBinding().getModule().equals(module)) {
+ // module not found
// TODO: externalize message?
OtpErlangObject errorMsg = MessageHelper.functionUndefMessage(
module, function, argsList,
@@ -111,6 +115,7 @@ public class ServiceExecutor implements Runnable {
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_BADRPC, errorMsg);
} else {
+ // module found, looking for operation
RuntimeComponentService service = nodeElement.getService();
ErlangBinding binding = nodeElement.getBinding();
List<Operation> operations = service.getInterfaceContract()
@@ -123,6 +128,7 @@ public class ServiceExecutor implements Runnable {
}
}
if (operation != null) {
+ // operation found
List<DataType> iTypes = operation.getInputType()
.getLogical();
Class<?>[] forClasses = new Class<?>[iTypes.size()];
@@ -130,22 +136,35 @@ public class ServiceExecutor implements Runnable {
forClasses[i] = iTypes.get(i).getPhysical();
}
try {
+ // invoke operation
+ Method jmethod = ((JavaOperation) operation)
+ .getJavaMethod();
Object result = service.getRuntimeWire(binding,
service.getInterfaceContract()).invoke(
operation,
TypeHelpersProxy.toJavaFromList(argsList,
- forClasses));
+ forClasses, jmethod
+ .getParameterAnnotations()));
OtpErlangObject response = null;
+
+ // send reply
if (operation.getOutputType() != null
&& operation.getOutputType().getPhysical()
.isArray()) {
- response = TypeHelpersProxy.toErlangAsList(result);
+ // output type is array
+ Annotation[][] outNotes = new Annotation[][] { jmethod
+ .getAnnotations() };
+ response = TypeHelpersProxy.toErlangAsList(result,
+ outNotes);
} else if (operation.getOutputType() == null) {
+ // output type is void, create empty reply
Object[] arrArg = new Object[] {};
- response = TypeHelpersProxy.toErlang(arrArg);
+ response = TypeHelpersProxy.toErlang(arrArg,
+ new Annotation[0][0]);
} else {
- Object[] arrArg = new Object[] { result };
- response = TypeHelpersProxy.toErlang(arrArg);
+ // output type is not void and not array
+ response = TypeHelpersProxy.toErlang(result,
+ jmethod.getAnnotations());
}
sendMessage(connection, senderPid, senderRef, null,
response);
@@ -156,6 +175,7 @@ public class ServiceExecutor implements Runnable {
IllegalArgumentException.class))
|| e.getClass().equals(
TypeMismatchException.class)) {
+ // wrong params
// TODO: externalize message?
OtpErlangObject errorMsg = MessageHelper
.functionUndefMessage(module, function,
@@ -164,10 +184,12 @@ public class ServiceExecutor implements Runnable {
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_BADRPC, errorMsg);
} else {
+ // unexpected error
throw e;
}
}
} else {
+ // operation not found
// TODO: externalize message?
OtpErlangObject errorMsg = MessageHelper
.functionUndefMessage(module, function, argsList,
@@ -177,6 +199,7 @@ public class ServiceExecutor implements Runnable {
}
}
} catch (ClassCastException e) {
+ // invalid request
// TODO: externalize message?
try {
logger
@@ -189,6 +212,7 @@ public class ServiceExecutor implements Runnable {
} catch (OtpErlangDecodeException e1) {
}
} catch (Exception e) {
+ // unknown error
try {
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_ERROR, new OtpErlangString(
@@ -224,10 +248,12 @@ public class ServiceExecutor implements Runnable {
msgNoSender = msg.getMsg();
}
} catch (Exception e) {
+ // TODO: check when this exception can occur
e.printStackTrace();
}
if (operations == null) {
+ // operation name not found
// TODO: externalize message?
// NOTE: I assume in Erlang sender doesn't get confirmation so
// no message will be send
@@ -235,7 +261,9 @@ public class ServiceExecutor implements Runnable {
+ "' received message addressed to non exising mbox: "
+ msg.getRecipientName());
} else {
+ // find proper operation for received parameters
for (Operation operation : operations) {
+ Method method = ((JavaOperation) operation).getJavaMethod();
List<DataType> iTypes = operation.getInputType().getLogical();
Class<?>[] forClasses = new Class<?>[iTypes.size()];
for (int i = 0; i < iTypes.size(); i++) {
@@ -243,7 +271,7 @@ public class ServiceExecutor implements Runnable {
}
try {
args = TypeHelpersProxy.toJavaAsArgs(msgNoSender,
- forClasses);
+ forClasses, method.getParameterAnnotations());
matchedOperation = operation;
break;
} catch (Exception e) {
@@ -252,22 +280,33 @@ public class ServiceExecutor implements Runnable {
}
}
if (matchedOperation != null) {
+ // operation found, invoke it
try {
+ Method jmethod = ((JavaOperation) matchedOperation)
+ .getJavaMethod();
Object result = nodeElement.getService().getRuntimeWire(
nodeElement.getBinding()).invoke(matchedOperation,
args);
OtpErlangObject response = null;
+
+ // create and send send reply
if (matchedOperation.getOutputType() != null
&& matchedOperation.getOutputType().getPhysical()
.isArray()) {
- response = TypeHelpersProxy.toErlangAsList(result);
+ // result type is array
+ Annotation[][] outNotes = new Annotation[][] { jmethod
+ .getAnnotations() };
+ response = TypeHelpersProxy.toErlangAsList(result,
+ outNotes);
} else if (matchedOperation.getOutputType() != null) {
- Object[] arrArg = new Object[] { result };
- response = TypeHelpersProxy.toErlang(arrArg);
+ // result type is not array and not void
+ response = TypeHelpersProxy.toErlang(result, jmethod
+ .getAnnotations());
}
if (response != null && senderPid != null) {
connection.send(senderPid, response);
} else if (response != null && senderPid == null) {
+ // couldn't send reply - sender pid unavailable
// TODO: externalize message?
// TODO: do we need to send this reply?
logger
@@ -288,13 +327,13 @@ public class ServiceExecutor implements Runnable {
new OtpErlangString(
"Operation name found in SCA component, but parameters types didn't match."));
} catch (IOException e1) {
- // TODO Auto-generated catch block
e1.printStackTrace();
}
} else {
+ // unknown/unhandled error
+ // TODO: decide what to do with this exception
e.printStackTrace();
}
- // } catch (IOException e) {
} catch (Exception e) {
// FIXME: log this problem? use linking feature? send error?
e.printStackTrace();
@@ -319,6 +358,7 @@ public class ServiceExecutor implements Runnable {
} else {
msg = connection.receiveMsg();
}
+ // check if request is message or RPC
if (msg.getRecipientName().equals(MessageHelper.RPC_MBOX)
&& !nodeElement.getBinding().isMbox()) {
handleRpc(msg);
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AnnotatedListTypeHelper.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AnnotatedListTypeHelper.java
new file mode 100644
index 0000000000..154f0c27fc
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AnnotatedListTypeHelper.java
@@ -0,0 +1,71 @@
+/*
+ * 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.erlang.impl.types;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ericsson.otp.erlang.OtpErlangList;
+import com.ericsson.otp.erlang.OtpErlangObject;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AnnotatedListTypeHelper implements TypeHelper {
+
+ private Annotation[] notes;
+
+ public AnnotatedListTypeHelper(Annotation[] notes) {
+ this.notes = notes;
+ }
+
+ public OtpErlangObject toErlang(Object object) {
+ int i = 0;
+ List<OtpErlangObject> elements = new ArrayList<OtpErlangObject>();
+ while (true) {
+ try {
+ elements.add(TypeHelpersProxy.toErlang(Array.get(object, i),
+ notes));
+ i++;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ break;
+ }
+ }
+ return new OtpErlangList(elements.toArray(new OtpErlangObject[elements
+ .size()]));
+ }
+
+ public Object toJava(OtpErlangObject object, Class<?> forClass)
+ throws Exception {
+ OtpErlangList erlangList = (OtpErlangList) object;
+ Object result = Array.newInstance(forClass.getComponentType(),
+ erlangList.arity());
+ for (int i = 0; i < erlangList.arity(); i++) {
+ Array.set(result, i, TypeHelpersProxy.toJava(erlangList
+ .elementAt(i), forClass.getComponentType(),
+ new Annotation[0]));
+ }
+ return result;
+ }
+
+}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AtomTypeHelper.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AtomTypeHelper.java
new file mode 100644
index 0000000000..94285c66bf
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/AtomTypeHelper.java
@@ -0,0 +1,39 @@
+/*
+ * 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.erlang.impl.types;
+
+import com.ericsson.otp.erlang.OtpErlangAtom;
+import com.ericsson.otp.erlang.OtpErlangObject;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AtomTypeHelper implements TypeHelper {
+
+ public OtpErlangObject toErlang(Object object) {
+ return new OtpErlangAtom((String) object);
+ }
+
+ public Object toJava(OtpErlangObject object, Class<?> forClass)
+ throws Exception {
+ return ((OtpErlangAtom) object).atomValue();
+ }
+
+}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/ListTypeHelper.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/ListTypeHelper.java
index adac10bcef..7bb62d4cf8 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/ListTypeHelper.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/ListTypeHelper.java
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.binding.erlang.impl.types;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
@@ -36,9 +37,8 @@ public class ListTypeHelper implements TypeHelper {
List<OtpErlangObject> elements = new ArrayList<OtpErlangObject>();
while (true) {
try {
- Object arrElement = Array.get(object, i);
- Object[] args = new Object[] { arrElement };
- elements.add(TypeHelpersProxy.toErlang(args));
+ elements.add(TypeHelpersProxy.toErlang(Array.get(object, i),
+ new Annotation[0]));
i++;
} catch (ArrayIndexOutOfBoundsException e) {
// expected
@@ -56,7 +56,8 @@ public class ListTypeHelper implements TypeHelper {
erlangList.arity());
for (int i = 0; i < erlangList.arity(); i++) {
Array.set(result, i, TypeHelpersProxy.toJava(erlangList
- .elementAt(i), forClass.getComponentType()));
+ .elementAt(i), forClass.getComponentType(),
+ new Annotation[0]));
}
return result;
}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TupleTypeHelper.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TupleTypeHelper.java
index 474459b9dc..64ea57f836 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TupleTypeHelper.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TupleTypeHelper.java
@@ -36,16 +36,15 @@ public class TupleTypeHelper implements TypeHelper {
List<OtpErlangObject> tupleMembers = new ArrayList<OtpErlangObject>();
Field[] fields = forClass.getFields();
for (int i = 0; i < fields.length; i++) {
- Object[] args = null;
try {
- args = new Object[] { fields[i].get(object) };
+ OtpErlangObject member = TypeHelpersProxy.toErlang(fields[i]
+ .get(object), fields[i].getAnnotations());
+ tupleMembers.add(member);
} catch (IllegalArgumentException e) {
// no problem should occur here
} catch (IllegalAccessException e) {
// and here
}
- OtpErlangObject member = TypeHelpersProxy.toErlang(args);
- tupleMembers.add(member);
}
OtpErlangObject result = new OtpErlangTuple(tupleMembers
.toArray(new OtpErlangObject[tupleMembers.size()]));
@@ -61,7 +60,7 @@ public class TupleTypeHelper implements TypeHelper {
for (int i = 0; i < tuple.arity(); i++) {
OtpErlangObject tupleMember = tuple.elementAt(i);
Object javaMember = TypeHelpersProxy.toJava(tupleMember, fields[i]
- .getType());
+ .getType(), fields[i].getAnnotations());
fields[i].setAccessible(true);
fields[i].set(result, javaMember);
}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java
index cbfd93796f..380abb852b 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.binding.erlang.impl.types;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
@@ -26,6 +27,7 @@ import java.util.List;
import java.util.Map;
import org.apache.tuscany.sca.binding.erlang.impl.TypeMismatchException;
+import org.apache.tuscany.sca.binding.erlang.meta.ErlangAtom;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
@@ -60,13 +62,34 @@ public class TypeHelpersProxy {
primitiveTypes.put(Float.class, primitiveTypes.get(float.class));
primitiveTypes.put(Double.class, primitiveTypes.get(double.class));
primitiveTypes.put(byte[].class, new BinaryTypeHelper());
+ primitiveTypes.put(ErlangAtom.class, new AtomTypeHelper());
}
- private static TypeHelper getTypeHelper(Class<?> forClass) {
- TypeHelper typeHelper = primitiveTypes.get(forClass);
+ private static TypeHelper getTypeHelper(Class<?> forClass,
+ Annotation[] notes) {
+ TypeHelper typeHelper = null;
+ // check for special types marked by annotations
+ for (int i = 0; i < notes.length; i++) {
+ typeHelper = primitiveTypes.get(notes[i].annotationType());
+ if (typeHelper != null) {
+ // annotation found, check if it points to array
+ // FIXME: check if annotation points to proper type
+ // ie. ErlangAtom -> String. If not, then log? exception?
+ if (forClass.isArray()) {
+ typeHelper = new AnnotatedListTypeHelper(notes);
+ }
+ break;
+ }
+ }
+ // check for standard types
+ if (typeHelper == null) {
+ typeHelper = primitiveTypes.get(forClass);
+ }
+ // check for arrays
if (typeHelper == null && forClass.isArray()) {
typeHelper = new ListTypeHelper();
}
+ // others would be tuples
if (typeHelper == null) {
typeHelper = new TupleTypeHelper();
}
@@ -74,13 +97,26 @@ public class TypeHelpersProxy {
}
/**
+ * Converts single Java object into Erlang
+ *
+ * @param object
+ * @param notes
+ * @return
+ */
+ public static OtpErlangObject toErlang(Object object, Annotation[] notes) {
+ TypeHelper helper = getTypeHelper(object.getClass(), notes);
+ return helper.toErlang(object);
+ }
+
+ /**
* Converts Java objects arrays to Erlang: 1. single object (if array arity
* == 1) or 2. tuple (if array arity > 1)
*
* @param objects
* @return
*/
- public static OtpErlangObject toErlang(Object[] objects) {
+ public static OtpErlangObject toErlang(Object[] objects,
+ Annotation[][] notes) {
OtpErlangObject result = null;
if (objects != null) {
TypeHelper helper = null;
@@ -89,13 +125,13 @@ public class TypeHelpersProxy {
result = new OtpErlangList();
break;
case 1:
- helper = getTypeHelper(objects[0].getClass());
+ helper = getTypeHelper(objects[0].getClass(), notes[0]);
result = helper.toErlang(objects[0]);
break;
default:
OtpErlangObject[] erlObjects = new OtpErlangObject[objects.length];
for (int i = 0; i < objects.length; i++) {
- helper = getTypeHelper(objects[i].getClass());
+ helper = getTypeHelper(objects[i].getClass(), notes[i]);
erlObjects[i] = helper.toErlang(objects[i]);
}
result = new OtpErlangTuple(erlObjects);
@@ -111,15 +147,24 @@ public class TypeHelpersProxy {
* @param array
* @return
*/
- public static OtpErlangList toErlangAsList(Object array) {
+ public static OtpErlangList toErlangAsList(Object array,
+ Annotation[][] notes) {
OtpErlangList result = null;
if (array != null) {
List<OtpErlangObject> attrsList = new ArrayList<OtpErlangObject>();
int i = 0;
while (true) {
try {
+ // FIXME: if notes.length == 1 then its used to annotate
+ // array. Clean up.
+ Annotation[] currNotes = null;
+ if (notes.length == 1) {
+ currNotes = notes[0];
+ } else {
+ currNotes = notes[i];
+ }
TypeHelper helper = getTypeHelper(Array.get(array, i)
- .getClass());
+ .getClass(), currNotes);
attrsList.add(helper.toErlang(Array.get(array, i)));
i++;
} catch (ArrayIndexOutOfBoundsException e) {
@@ -142,10 +187,10 @@ public class TypeHelpersProxy {
* @return
* @throws Exception
*/
- public static Object toJava(OtpErlangObject object, Class<?> forClass)
- throws Exception {
+ public static Object toJava(OtpErlangObject object, Class<?> forClass,
+ Annotation[] notes) throws Exception {
try {
- TypeHelper helper = getTypeHelper(forClass);
+ TypeHelper helper = getTypeHelper(forClass, notes);
return helper.toJava(object, forClass);
} catch (ClassCastException e) {
throw new TypeMismatchException(forClass, object.getClass());
@@ -161,11 +206,11 @@ public class TypeHelpersProxy {
* @throws Exception
*/
public static Object[] toJavaFromList(OtpErlangList objects,
- Class<?>[] forClass) throws Exception {
+ Class<?>[] forClass, Annotation[][] notes) throws Exception {
Object[] result = new Object[objects.arity()];
try {
for (int i = 0; i < objects.arity(); i++) {
- TypeHelper helper = getTypeHelper(forClass[i]);
+ TypeHelper helper = getTypeHelper(forClass[i], notes[i]);
result[i] = helper.toJava(objects.elementAt(i), forClass[i]);
}
} catch (Exception e) {
@@ -187,7 +232,7 @@ public class TypeHelpersProxy {
* @throws Exception
*/
public static Object[] toJavaAsArgs(OtpErlangObject objects,
- Class<?>[] forClass) throws Exception {
+ Class<?>[] forClass, Annotation[][] notes) throws Exception {
OtpErlangObject[] args = null;
// normalize input
if (objects.getClass().equals(OtpErlangTuple.class)) {
@@ -202,7 +247,7 @@ public class TypeHelpersProxy {
Object[] result = new Object[args.length];
try {
for (int i = 0; i < args.length; i++) {
- TypeHelper helper = getTypeHelper(forClass[i]);
+ TypeHelper helper = getTypeHelper(forClass[i], notes[i]);
result[i] = helper.toJava(args[i], forClass[i]);
}
} catch (Exception e) {
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/meta/ErlangAtom.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/meta/ErlangAtom.java
new file mode 100644
index 0000000000..48037eaa1c
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/meta/ErlangAtom.java
@@ -0,0 +1,28 @@
+/*
+ * 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.erlang.meta;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ErlangAtom {
+
+}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/AtomTuple.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/AtomTuple.java
new file mode 100644
index 0000000000..f0930295a7
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/AtomTuple.java
@@ -0,0 +1,30 @@
+/*
+ * 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.erlang.testing;
+
+import org.apache.tuscany.sca.binding.erlang.meta.ErlangAtom;
+
+public class AtomTuple {
+
+ @ErlangAtom
+ public String field1;
+ public int field2;
+
+}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxInterface.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxInterface.java
index 74ec613018..8f950d54f7 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxInterface.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxInterface.java
@@ -19,6 +19,8 @@
package org.apache.tuscany.sca.binding.erlang.testing;
+import org.apache.tuscany.sca.binding.erlang.meta.ErlangAtom;
+
/**
* @version $Rev$ $Date$
*/
@@ -49,7 +51,15 @@ public interface MboxInterface {
String[] sendArgs(String[] arg) throws Exception;
String[][] sendArgs(String[][] arg);
-
+
byte[] sendArgs(byte[] arg);
-
+
+ @ErlangAtom
+ String[] sendArgs(@ErlangAtom String arg1, AtomTuple arg2);
+
+ @ErlangAtom
+ String[][] sendArgs(@ErlangAtom String[][] arg1, int arg2);
+
+ void sendArgs();
+
}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxListener.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxListener.java
index fe643fcff6..0cab5c0b0e 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxListener.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/MboxListener.java
@@ -19,6 +19,8 @@
package org.apache.tuscany.sca.binding.erlang.testing;
+import java.lang.annotation.Annotation;
+
import org.apache.tuscany.sca.binding.erlang.impl.types.TypeHelpersProxy;
import com.ericsson.otp.erlang.OtpErlangObject;
@@ -53,14 +55,16 @@ public class MboxListener implements Runnable {
Thread.sleep(duration);
OtpErlangPid senderPid = null;
if (response != null) {
- Object[] args = new Object[1];
- args[0] = response;
- if (msg.getMsg().getClass().equals(OtpErlangTuple.class) && ((OtpErlangTuple) msg.getMsg()).elementAt(0).getClass().equals(OtpErlangPid.class)) {
- senderPid = (OtpErlangPid) ((OtpErlangTuple) msg.getMsg()).elementAt(0);
+ if (msg.getMsg().getClass().equals(OtpErlangTuple.class)
+ && ((OtpErlangTuple) msg.getMsg()).elementAt(0)
+ .getClass().equals(OtpErlangPid.class)) {
+ senderPid = (OtpErlangPid) ((OtpErlangTuple) msg.getMsg())
+ .elementAt(0);
} else {
senderPid = msg.getSenderPid();
}
- mbox.send(senderPid, TypeHelpersProxy.toErlang(args));
+ mbox.send(senderPid, TypeHelpersProxy.toErlang(response,
+ new Annotation[0]));
}
} catch (Exception e) {
e.printStackTrace();
@@ -84,9 +88,9 @@ public class MboxListener implements Runnable {
}
}
}
- return msg.getMsg();
+ return ((OtpErlangTuple) msg.getMsg()).elementAt(1);
} catch (Exception e) {
-
+ e.printStackTrace();
}
return null;
}
diff --git a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/ReferenceServiceTestCase.java b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/ReferenceServiceTestCase.java
index 3e0a60725e..0c80df7a04 100644
--- a/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/ReferenceServiceTestCase.java
+++ b/branches/sca-java-1.x/modules/binding-erlang-runtime/src/test/java/org/apache/tuscany/sca/binding/erlang/testing/ReferenceServiceTestCase.java
@@ -32,6 +32,7 @@ import org.apache.tuscany.sca.host.embedded.SCADomain;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -292,6 +293,11 @@ public class ReferenceServiceTestCase {
String testString = "TupleString";
int testInt = 10;
mboxReference.sendArgs(testInt, testString);
+ // FIXME:
+ // without following sleep an exception occurs:
+ // com.ericsson.otp.erlang.OtpErlangDecodeException: Cannot read from
+ // input stream
+ Thread.sleep(100);
assertEquals(testInt, ((OtpErlangLong) ((OtpErlangTuple) mboxListener
.getMsg()).elementAt(0)).longValue());
assertEquals(testString,
@@ -412,6 +418,52 @@ public class ReferenceServiceTestCase {
}
/**
+ * Tests passing Erlang atoms. It provides cases for annotating result
+ * types, parameters and fields in java classes - tuples.
+ *
+ * @throws Exception
+ */
+ @Test(timeout = 1000)
+ public void testAtoms() throws Exception {
+ AtomTuple arg2 = new AtomTuple();
+ arg2.field1 = "test";
+ String arg1 = "First arg";
+ String[] strResult = { "Hello", "World" };
+ MboxListener mboxListener = new MboxListener(serMbox, strResult);
+ Thread mboxThread = new Thread(mboxListener);
+ mboxThread.start();
+ String[] testResult = mboxReference.sendArgs(arg1, arg2);
+ assertEquals(strResult[0], testResult[0]);
+ assertEquals(strResult[1], testResult[1]);
+
+ assertEquals(arg1, ((OtpErlangAtom) ((OtpErlangTuple) mboxListener
+ .getMsg()).elementAt(0)).atomValue());
+
+ assertEquals(
+ arg2.field1,
+ ((OtpErlangAtom) ((OtpErlangTuple) ((OtpErlangTuple) mboxListener
+ .getMsg()).elementAt(1)).elementAt(0)).atomValue());
+
+ // test multi dimensional arrays
+ String[][] arg = { { "this", "is" }, { "a" }, { "test" } };
+ mboxListener = new MboxListener(serMbox, arg);
+ mboxThread = new Thread(mboxListener);
+ mboxThread.start();
+ String[][] multiDimRes = mboxReference.sendArgs(arg, 1);
+ for (int i = 0; i < arg.length; i++) {
+ for (int j = 0; j < arg[i].length; j++) {
+ assertEquals(arg[i][j], multiDimRes[i][j]);
+ assertEquals(
+ arg[i][j],
+ ((OtpErlangAtom) ((OtpErlangList) ((OtpErlangList) ((OtpErlangTuple) mboxListener
+ .getMsg()).elementAt(0)).elementAt(i))
+ .elementAt(j)).atomValue());
+ }
+ }
+
+ }
+
+ /**
* Tests mismatched interface
*
* @throws Exception
@@ -644,14 +696,16 @@ public class ReferenceServiceTestCase {
OtpErlangObject[] argsWithSender = new OtpErlangObject[2];
argsWithSender[0] = refMbox.self();
argsWithSender[1] = tuple;
- refMbox.send("sayHello", "RPCServerMbox", new OtpErlangTuple(argsWithSender));
+ refMbox.send("sayHello", "RPCServerMbox", new OtpErlangTuple(
+ argsWithSender));
OtpErlangString result = (OtpErlangString) refMbox.receiveMsg()
.getMsg();
assertEquals("Hello world !", result.stringValue());
}
-
+
/**
* Tests receiving reply without sending self PID
+ *
* @throws Exception
*/
@Test(timeout = 1000)
@@ -698,7 +752,8 @@ public class ReferenceServiceTestCase {
OtpErlangObject[] withSender = new OtpErlangObject[2];
withSender[0] = refMbox.self();
withSender[1] = args;
- refMbox.send("passComplexArgs", "RPCServerMbox", new OtpErlangTuple(withSender));
+ refMbox.send("passComplexArgs", "RPCServerMbox", new OtpErlangTuple(
+ withSender));
OtpErlangObject result = refMbox.receiveMsg().getMsg();
assertEquals(arg1,
((OtpErlangLong) ((OtpErlangTuple) ((OtpErlangTuple) result)
@@ -831,4 +886,12 @@ public class ReferenceServiceTestCase {
cookieModuleReference.sayHellos();
}
+ @Test(timeout = 1000)
+ @Ignore("Nothing to test yet")
+ public void testMboxNoArgs() throws Exception {
+ // FIXME: decide what to do while invoking mbox reference with no params
+ // exception? log?
+ mboxReference.sendArgs();
+ }
+
}