3 import java.io.IOException;
4 import java.nio.ByteBuffer;
5 import java.util.Arrays;
6 import java.util.ArrayList;
7 import java.util.HashMap;
10 import java.lang.reflect.Method;
12 import java.util.HashSet;
16 /** Class IoTRMICall is a class that serves method calls on stub.
18 * A stub will use an object of this class to send the method
19 * information, e.g. object identifier, method identifier, and
22 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
26 public class IoTRMICall {
32 private IoTRMIUtil rmiUtil;
33 private IoTSocketClient rmiClient;
34 //private List<String> listMethodId; // Map from method ID to signature
40 public IoTRMICall(int _port, String _address, int _rev) throws IOException {
42 rmiUtil = new IoTRMIUtil();
43 rmiClient = new IoTSocketClient(_port, _address, _rev);
48 * remoteCall() calls a method remotely by passing in parameters and getting a return Object
50 public synchronized Object remoteCall(int objectId, int methodId, Class<?> retType,
51 Class<?> retGenTypeVal, Class<?>[] paramCls, Object[] paramObj) {
54 byte[] methodBytes = methodToBytes(objectId, methodId, paramCls, paramObj);
55 //System.out.println("Method RMICall: " + Arrays.toString(methodBytes));
57 rmiClient.sendBytes(methodBytes);
58 //System.out.println("Sent bytes RMICall!!!");
59 } catch (IOException ex) {
61 throw new Error("IoTRMICall: Error when sending bytes - rmiClient.sendBytes()");
63 // Receive return value and return it to caller
65 if (retType != void.class) {
66 byte[] retObjBytes = null;
68 retObjBytes = rmiClient.receiveBytes(retObjBytes);
69 } catch (IOException ex) {
71 throw new Error("IoTRMICall: Error when receiving bytes - rmiClient.receiveBytes()");
73 retObj = IoTRMIUtil.getParamObject(retType, retGenTypeVal, retObjBytes);
80 * methodToBytes() returns byte representation of a method
82 public byte[] methodToBytes(int objectId, int methId, Class<?>[] paramCls, Object[] paramObj) {
84 // Initialized to the length of method ID
85 int methodLen = IoTRMIUtil.OBJECT_ID_LEN;
86 byte[] objId = IoTRMIUtil.intToByteArray(objectId);
87 // Get method ID in bytes
88 byte[] methodId = IoTRMIUtil.intToByteArray(methId);
89 // Get byte arrays and calculate method bytes length
90 int numbParam = paramObj.length;
91 methodLen = methodLen + IoTRMIUtil.METHOD_ID_LEN;
92 byte[][] objBytesArr = new byte[numbParam][];
93 for (int i = 0; i < numbParam; i++) {
94 // Get byte arrays for the objects
95 objBytesArr[i] = IoTRMIUtil.getObjectBytes(paramObj[i]);
96 String clsName = paramCls[i].getSimpleName();
97 int paramLen = rmiUtil.getTypeSize(clsName);
98 if (paramLen == -1) { // indefinite length - store the length first
99 methodLen = methodLen + IoTRMIUtil.PARAM_LEN;
101 methodLen = methodLen + objBytesArr[i].length;
103 // Construct method in byte array
104 byte[] method = new byte[methodLen];
106 System.arraycopy(objId, 0, method, 0, IoTRMIUtil.METHOD_ID_LEN);
107 pos = pos + IoTRMIUtil.OBJECT_ID_LEN;
108 System.arraycopy(methodId, 0, method, pos, IoTRMIUtil.METHOD_ID_LEN);
109 pos = pos + IoTRMIUtil.METHOD_ID_LEN;
110 // Second iteration for copying bytes
111 for (int i = 0; i < numbParam; i++) {
113 String clsName = paramCls[i].getSimpleName();
114 int paramLen = rmiUtil.getTypeSize(clsName);
115 if (paramLen == -1) { // indefinite length
116 paramLen = objBytesArr[i].length;
117 byte[] paramLenBytes = IoTRMIUtil.intToByteArray(paramLen);
118 System.arraycopy(paramLenBytes, 0, method, pos, IoTRMIUtil.PARAM_LEN);
119 pos = pos + IoTRMIUtil.PARAM_LEN;
121 System.arraycopy(objBytesArr[i], 0, method, pos, paramLen);
122 pos = pos + paramLen;
130 * remoteCall() calls a method remotely by passing in parameters and getting a return Object
132 public synchronized Object[] getStructObjects(Class<?>[] retType, Class<?>[] retGenTypeVal) {
134 // Receive return value and return it to caller
135 Object[] retObj = null;
136 byte[] retObjBytes = null;
138 retObjBytes = rmiClient.receiveBytes(retObjBytes);
139 } catch (IOException ex) {
140 ex.printStackTrace();
141 throw new Error("IoTRMICall: Error when receiving bytes - rmiClient.receiveBytes()");
143 retObj = getReturnObjects(retObjBytes, retType, retGenTypeVal);
149 public Object[] getReturnObjects(byte[] retBytes, Class<?>[] arrCls, Class<?>[] arrGenValCls) {
151 // Byte scanning position
153 Object[] retObj = new Object[arrCls.length];
154 for (int i=0; i < arrCls.length; i++) {
156 String retType = arrCls[i].getSimpleName();
157 int retSize = rmiUtil.getTypeSize(retType);
158 // Get the 32-bit field in the byte array to get the actual
159 // length (this is a param with indefinite length)
161 byte[] bytRetLen = new byte[IoTRMIUtil.RETURN_LEN];
162 System.arraycopy(retBytes, pos, bytRetLen, 0, IoTRMIUtil.RETURN_LEN);
163 pos = pos + IoTRMIUtil.RETURN_LEN;
164 retSize = IoTRMIUtil.byteArrayToInt(bytRetLen);
166 byte[] retObjBytes = new byte[retSize];
167 System.arraycopy(retBytes, pos, retObjBytes, 0, retSize);
169 retObj[i] = IoTRMIUtil.getParamObject(arrCls[i], arrGenValCls[i], retObjBytes);