Early version of RMI system for Java part; supports primitives, one-dimensional array...
[iot2.git] / iotjava / iotrmi / Java / IoTRMICall.java
1 package iotrmi.Java;
2
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;
8 import java.util.List;
9 import java.util.Map;
10 import java.lang.reflect.Method;
11
12 import java.util.HashSet;
13 import java.util.Set;
14
15
16 /** Class IoTRMICall is a class that serves method calls on stub.
17  *  <p>
18  *  A stub will use an object of this class to send the method
19  *  information, e.g. object identifier, method identifier, and
20  *  parameters.
21  *
22  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
23  * @version     1.0
24  * @since       2016-10-04
25  */
26 public class IoTRMICall {
27
28
29         /**
30          * Class Properties
31          */
32         private IoTRMIUtil rmiUtil;
33         private IoTSocketClient rmiClient;
34
35
36         /**
37          * Constructors
38          */
39         public IoTRMICall(int _port, String _address, int _rev) throws IOException {
40
41                 rmiUtil = new IoTRMIUtil();
42                 rmiClient = new IoTSocketClient(_port, _address, _rev);
43         }
44
45
46         /**
47          * remoteCall() calls a method remotely by passing in parameters and getting a return Object
48          */
49         public Object remoteCall(String methodSign, Class<?> retType, Class<?> retGenTypeKey, 
50                         Class<?> retGenTypeVal, Class<?>[] paramCls, Object[] paramObj) {
51
52                 // Send method info
53                 byte[] methodBytes = methodToBytes(methodSign, paramCls, paramObj);
54                 try {
55                         rmiClient.sendBytes(methodBytes);
56                 } catch (IOException ex) {
57                         ex.printStackTrace();
58                         throw new Error("IoTRMICall: Error when sending bytes - rmiClient.sendBytes()");
59                 }
60                 // Receive return value and return it to caller
61                 Object retObj = null;
62                 if (retType != void.class) {
63                         byte[] retObjBytes = null;
64                         try {
65                                 retObjBytes = rmiClient.receiveBytes(retObjBytes);
66                         } catch (IOException ex) {
67                                 ex.printStackTrace();
68                                 throw new Error("IoTRMICall: Error when receiving bytes - rmiClient.receiveBytes()");
69                         }
70                         retObj = IoTRMIUtil.getParamObject(retType, retGenTypeKey, retGenTypeVal, retObjBytes);
71                 }
72                 return retObj;
73         }
74
75
76         /**
77          * methodToBytes() returns byte representation of a method
78          */
79         public byte[] methodToBytes(String methodSign, Class<?>[] paramCls, Object[] paramObj) {
80
81                 // Get method ID in bytes
82                 byte[] methodId = IoTRMIUtil.getHashCodeBytes(methodSign);
83
84                 // Get byte arrays and calculate method bytes length
85                 int numbParam = paramObj.length;
86                 int methodLen = IoTRMIUtil.METHOD_ID_LEN;       // Initialized to the length of method ID
87                 byte[][] objBytesArr = new byte[numbParam][];
88                 for (int i=0; i < numbParam; i++) {
89                         // Get byte arrays for the objects
90                         objBytesArr[i] = IoTRMIUtil.getObjectBytes(paramObj[i]);
91                         String clsName = paramCls[i].getSimpleName();
92                         int paramLen = rmiUtil.getTypeSize(clsName);
93                         if (paramLen == -1) {           // indefinite length
94                                 methodLen = methodLen + IoTRMIUtil.PARAM_LEN;
95                         }
96                         methodLen = methodLen + objBytesArr[i].length;
97                 }
98
99                 // Construct method in byte array
100                 byte[] method = new byte[methodLen];
101                 int pos = 0;
102                 System.arraycopy(methodId, 0, method, 0, methodId.length);
103                 pos = pos + IoTRMIUtil.METHOD_ID_LEN;
104                 // Second iteration for copying bytes
105                 for (int i=0; i < numbParam; i++) {
106
107                         String clsName = paramCls[i].getSimpleName();
108                         int paramLen = rmiUtil.getTypeSize(clsName);
109                         if (paramLen == -1) {           // indefinite length
110                                 paramLen = objBytesArr[i].length;
111                                 byte[] paramLenBytes = IoTRMIUtil.intToByteArray(paramLen);
112                                 System.arraycopy(paramLenBytes, 0, method, pos, IoTRMIUtil.PARAM_LEN);
113                                 pos = pos + IoTRMIUtil.PARAM_LEN;
114                         }               
115                         System.arraycopy(objBytesArr[i], 0, method, pos, paramLen);
116                         pos = pos + paramLen;
117                 }
118
119                 return method;
120         }
121
122         
123         public static void main(String[] args) throws Exception {
124
125                 String[] test = { "123", "456", "789" };
126                 byte[] b = IoTRMIUtil.getObjectBytes(test);
127
128                 Boolean[] test2 = new Boolean[] { true, false, false };
129                 byte[] b2 = IoTRMIUtil.getObjectBytes(test2);
130
131                 System.out.println(Arrays.toString(b));
132                 System.out.println(Arrays.toString(b2));
133
134                 String[] c = (String[]) IoTRMIUtil.getParamObjectArray(String[].class, b);
135                 System.out.println(Arrays.toString(c));
136
137                 Boolean[] c2 = (Boolean[]) IoTRMIUtil.getParamObjectArray(Boolean[].class, b2);
138                 System.out.println(Arrays.toString(c2));
139
140                 // Set
141                 /*Set<String> set = new HashSet<String>();
142                 set.add("1234");
143                 set.add("5678");
144
145                 byte[] objBytes = IoTRMIUtil.getObjectBytes(set);
146                 System.out.println(Arrays.toString(objBytes));
147                 Object obj = IoTRMIUtil.getParamObject(Set.class, null, String.class, objBytes);
148
149                 @SuppressWarnings("unchecked")
150                 Set<String> setStr = (Set<String>) obj;
151                 System.out.println("Set: " + setStr.toString());*/
152
153                 // List
154                 /*List<Long> list = new ArrayList<Long>();
155                 list.add(12345678l);
156                 list.add(23455432l);
157                 list.add(34566543l);
158
159                 byte[] objBytes = IoTRMIUtil.getObjectBytes(list);
160                 System.out.println(Arrays.toString(objBytes));
161                 Object obj = IoTRMIUtil.getParamObject(List.class, null, Long.class, objBytes);
162
163                 @SuppressWarnings("unchecked")
164                 List<Long> listStr = (List<Long>) obj;
165                 System.out.println("List: " + listStr.toString());*/
166
167                 // Map
168                 Map<Long,Integer> map = new HashMap<Long,Integer>();
169                 map.put(12345678l, 1234);
170                 map.put(23455432l, 5678);
171                 map.put(34566543l, 4321);
172
173                 byte[] objBytes = IoTRMIUtil.getObjectBytes(map);
174                 System.out.println(Arrays.toString(objBytes));
175                 Object obj = IoTRMIUtil.getParamObject(Map.class, Long.class, Integer.class, objBytes);
176
177                 map = (Map<Long,Integer>) obj;
178                 System.out.println("Received map: " + map.toString());
179
180                 //@SuppressWarnings("unchecked")
181                 //List<Long> listStr = (List<Long>) obj;
182                 //System.out.println("List: " + listStr.toString());
183
184         }
185 }