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, String[] _methodSign) throws IOException {
42 rmiUtil = new IoTRMIUtil();
43 rmiClient = new IoTSocketClient(_port, _address, _rev);
44 listMethodId = Arrays.asList(_methodSign); // Initialize the method ID map
49 * remoteCall() calls a method remotely by passing in parameters and getting a return Object
51 public Object remoteCall(int objectId, String methodSign, Class<?> retType, Class<?> retGenTypeKey,
52 Class<?> retGenTypeVal, Class<?>[] paramCls, Object[] paramObj) {
55 byte[] methodBytes = methodToBytes(objectId, methodSign, paramCls, paramObj);
57 rmiClient.sendBytes(methodBytes);
58 } catch (IOException ex) {
60 throw new Error("IoTRMICall: Error when sending bytes - rmiClient.sendBytes()");
62 // Receive return value and return it to caller
64 if (retType != void.class) {
65 byte[] retObjBytes = null;
67 retObjBytes = rmiClient.receiveBytes(retObjBytes);
68 } catch (IOException ex) {
70 throw new Error("IoTRMICall: Error when receiving bytes - rmiClient.receiveBytes()");
72 retObj = IoTRMIUtil.getParamObject(retType, retGenTypeKey, retGenTypeVal, retObjBytes);
79 * methodToBytes() returns byte representation of a method
81 public byte[] methodToBytes(int objectId, String methodSign, Class<?>[] paramCls, Object[] paramObj) {
83 // Initialized to the length of method ID
84 int methodLen = IoTRMIUtil.OBJECT_ID_LEN;
85 byte[] objId = IoTRMIUtil.intToByteArray(objectId);
86 // Get method ID in bytes
87 int methId = listMethodId.indexOf(methodSign);
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;
129 public static void main(String[] args) throws Exception {
131 String[] test = { "123", "456", "789" };
132 byte[] b = IoTRMIUtil.getObjectBytes(test);
134 Boolean[] test2 = new Boolean[] { true, false, false };
135 byte[] b2 = IoTRMIUtil.getObjectBytes(test2);
137 System.out.println(Arrays.toString(b));
138 System.out.println(Arrays.toString(b2));
140 String[] c = (String[]) IoTRMIUtil.getParamObjectArray(String[].class, b);
141 System.out.println(Arrays.toString(c));
143 Boolean[] c2 = (Boolean[]) IoTRMIUtil.getParamObjectArray(Boolean[].class, b2);
144 System.out.println(Arrays.toString(c2));
147 /*Set<String> set = new HashSet<String>();
151 byte[] objBytes = IoTRMIUtil.getObjectBytes(set);
152 System.out.println(Arrays.toString(objBytes));
153 Object obj = IoTRMIUtil.getParamObject(Set.class, null, String.class, objBytes);
155 @SuppressWarnings("unchecked")
156 Set<String> setStr = (Set<String>) obj;
157 System.out.println("Set: " + setStr.toString());*/
160 /*List<Long> list = new ArrayList<Long>();
165 byte[] objBytes = IoTRMIUtil.getObjectBytes(list);
166 System.out.println(Arrays.toString(objBytes));
167 Object obj = IoTRMIUtil.getParamObject(List.class, null, Long.class, objBytes);
169 @SuppressWarnings("unchecked")
170 List<Long> listStr = (List<Long>) obj;
171 System.out.println("List: " + listStr.toString());*/
174 Map<Long,Integer> map = new HashMap<Long,Integer>();
175 map.put(12345678l, 1234);
176 map.put(23455432l, 5678);
177 map.put(34566543l, 4321);
179 byte[] objBytes = IoTRMIUtil.getObjectBytes(map);
180 System.out.println(Arrays.toString(objBytes));
181 Object obj = IoTRMIUtil.getParamObject(Map.class, Long.class, Integer.class, objBytes);
183 map = (Map<Long,Integer>) obj;
184 System.out.println("Received map: " + map.toString());
186 //@SuppressWarnings("unchecked")
187 //List<Long> listStr = (List<Long>) obj;
188 //System.out.println("List: " + listStr.toString());