Adding early version of IoT RMI system; for now: 1) Connects Java to Java; 2) Transla...
[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
13 /** Class IoTRMICall is a class that serves method calls on stub.
14  *  <p>
15  *  A stub will use an object of this class to send the method
16  *  information, e.g. object identifier, method identifier, and
17  *  parameters.
18  *
19  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
20  * @version     1.0
21  * @since       2016-10-04
22  */
23 public class IoTRMICall {
24
25         /**
26          * Class Properties
27          */
28         private IoTRMIUtil rmiUtil;
29         private IoTSocketClient rmiClient;
30
31
32         /**
33          * Constructors
34          */
35         public IoTRMICall(int _port, String _address, int _rev) throws IOException {
36
37                 rmiUtil = new IoTRMIUtil();
38                 rmiClient = new IoTSocketClient(_port, _address, _rev);
39         }
40
41
42         /**
43          * remoteCall() calls a method remotely by passing in parameters and getting a return Object
44          */
45         public Object remoteCall(String methodSign, String retType, Class<?>[] paramCls, Object[] paramObj) throws IOException {
46
47                 // Send method info
48                 byte[] methodBytes = methodToBytes(methodSign, paramCls, paramObj);
49                 rmiClient.sendBytes(methodBytes);
50                 // Receive return value and return it to caller
51                 byte[] retObjBytes = null;
52                 retObjBytes = rmiClient.receiveBytes(retObjBytes);
53                 Object retObj = IoTRMIUtil.getParamObject(retType, retObjBytes);
54                 return retObj;
55         }
56
57
58         /**
59          * methodToBytes() returns byte representation of a method
60          */
61         public byte[] methodToBytes(String methodSign, Class<?>[] paramCls, Object[] paramObj) {
62
63                 // Get method ID in bytes
64                 byte[] methodId = IoTRMIUtil.getHashCodeBytes(methodSign);
65
66                 // Get byte arrays and calculate method bytes length
67                 int numbParam = paramObj.length;
68                 int methodLen = IoTRMIUtil.METHOD_ID_LEN;       // Initialized to the length of method ID
69                 byte[][] objBytesArr = new byte[numbParam][];
70                 for (int i=0; i < numbParam; i++) {
71                         // Get byte arrays for the objects
72                         objBytesArr[i] = IoTRMIUtil.getObjectBytes(paramObj[i]);
73                         String clsName = paramCls[i].getSimpleName();
74                         int paramLen = rmiUtil.getTypeSize(clsName);
75                         if (paramLen == -1) {           // indefinite length
76                                 methodLen = methodLen + IoTRMIUtil.PARAM_LEN;
77                         }
78                         methodLen = methodLen + objBytesArr[i].length;
79                 }
80
81                 // Construct method in byte array
82                 byte[] method = new byte[methodLen];
83                 int pos = 0;
84                 System.arraycopy(methodId, 0, method, 0, methodId.length);
85                 pos = pos + IoTRMIUtil.METHOD_ID_LEN;
86                 // Second iteration for copying bytes
87                 for (int i=0; i < numbParam; i++) {
88
89                         String clsName = paramCls[i].getSimpleName();
90                         int paramLen = rmiUtil.getTypeSize(clsName);
91                         if (paramLen == -1) {           // indefinite length
92                                 paramLen = objBytesArr[i].length;
93                                 byte[] paramLenBytes = IoTRMIUtil.intToByteArray(paramLen);
94                                 System.arraycopy(paramLenBytes, 0, method, pos, IoTRMIUtil.PARAM_LEN);
95                                 pos = pos + IoTRMIUtil.PARAM_LEN;
96                         }               
97                         System.arraycopy(objBytesArr[i], 0, method, pos, paramLen);
98                         pos = pos + paramLen;
99                 }
100
101                 return method;
102         }
103
104         
105         public static void main(String[] args) throws Exception {
106
107                 int port = 5010;
108                 String address = "localhost";
109                 int rev = 0;
110                 IoTRMICall rmiCall = new IoTRMICall(port, address, rev);
111                 String sign = "intsetACAndGetA(string,int)";
112                 String retType = "int";
113                 System.out.println("Calling function: " + sign);
114                 Object retObj = rmiCall.remoteCall(sign, retType, new Class<?>[] { String.class, int.class }, 
115                         new Object[] { "Test param", 1234567 });
116                 System.out.println("Returned object: " + retObj);
117
118                 System.out.println();
119         }
120 }