Adding support to returning struct/list of struct objects
[iot2.git] / iotjava / iotrmi / Java / sample / TestClass_Stub.java
1 package iotrmi.Java.sample;
2
3 import java.io.IOException;
4 import iotrmi.Java.IoTRMICall;
5 import iotruntime.master.CommunicationHandler;
6
7 import java.util.Arrays;
8 import java.util.List;
9 import java.util.ArrayList;
10
11 import iotrmi.Java.IoTRMIObject;
12
13 public class TestClass_Stub implements TestClassInterface {
14
15         /**
16          * Class Properties
17          */
18         private IoTRMICall rmiCall;
19         private String address;
20         private int[] ports;
21         private List<CallBackInterface> listCBObj;
22         private IoTRMIObject rmiObj;
23
24         /**
25          * Class Constants
26          */
27         private final static int NUM_CB_OBJ = 1;
28         private int objectId = 0;       // Default value is 0
29         private static int objIdCnt = 0; // Counter for callback object Ids
30
31         /**
32          * Constructors
33          */
34         public TestClass_Stub(int _port, String _address, int _rev, int[] _ports) throws Exception {
35
36                 address = _address;
37                 ports = _ports;
38                 rmiCall = new IoTRMICall(_port, _address, _rev);
39                 listCBObj = new ArrayList<CallBackInterface>();
40                 ___initCallBack();
41         }
42
43
44         /**
45          * Instantiation of callback objects
46          */
47         public static int numCallbackObjects() {
48
49                 return NUM_CB_OBJ;      // Generated by the IoTCompiler
50         }
51
52
53         // Initialize callback
54         public void ___initCallBack() {
55
56                 Thread thread = new Thread() {
57                         public void run() {
58                         try{
59                                         System.out.println("Created server with port: " + ports[0]);
60                                         rmiObj = new IoTRMIObject(ports[0]);
61                                         Object retObj = null;
62                                         while (true) {
63                                                 byte[] method = rmiObj.getMethodBytes();
64                                                 int objId = IoTRMIObject.getObjectId(method);
65                                                 CallBack_CBSkeleton skel = (CallBack_CBSkeleton) listCBObj.get(objId);
66                                                 if (skel != null) {
67                                                         //rmiObj.setMethodBytes(method);
68                                                         skel.invokeMethod(rmiObj);
69                                                 }
70                                         }
71                                 } catch (Exception ex){
72                                         ex.printStackTrace();
73                                         throw new Error("Error instantiating class CallBack_Skeleton!");
74                         }
75                     }
76                 };
77                 thread.start();
78
79                 //String sign = "registercallback";     // can be any string
80                 int methodId = 9;
81                 Class<?> retType = void.class;
82                 // port, address, rev
83                 Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };
84                 Object[] paramObj = new Object[] { ports[0], address, 0 };
85                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
86         }
87
88
89         // Single callback handling
90         public void registerCallback(CallBackInterface _cb) {
91
92                 /*Thread thread = new Thread() {
93                         public void run() {
94                     try{
95                                         CallBack_Skeleton cbskel = new CallBack_Skeleton(_cb, ports[0]);
96                                 } catch (Exception ex){
97                                         ex.printStackTrace();
98                                         throw new Error("Error instantiating class CallBack_Skeleton!");
99                     }
100                 }
101             };
102                 thread.start();
103
104                 String sign = "voidregisterCallBack(CallBackInterface)";
105                 Class<?> retType = void.class;
106                 // port, address, and rev
107                 Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };
108                 Object[] paramObj = new Object[] { ports[0], address, 0 };
109                 rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj);*/
110         }
111
112
113         public void registerCallback(CallBackInterface[] _cb) {
114
115                 try {
116                         //for (int objId = 0; objId < _cb.length; objId++) {
117                         for (CallBackInterface cb : _cb) {
118                                 CallBack_CBSkeleton skel = new CallBack_CBSkeleton(cb, objIdCnt++);
119                                 listCBObj.add(skel);
120                         }
121                 } catch (Exception ex){
122                         ex.printStackTrace();
123                         throw new Error("Class not found / instantiation / illegal access / IO error!");
124                 }
125
126                 //String sign = "voidregisterCallBack(CallBackInterface[])";
127                 int methodId = 8;
128                 Class<?> retType = void.class;
129                 // port, address, rev, and number of objects
130                 Class<?>[] paramCls = new Class<?>[] { int.class };
131                 Object[] paramObj = new Object[] { _cb.length };
132                 //rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj);
133                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
134         }
135
136
137         public void setA(int _int) {
138
139                 //String sign = "voidsetA(int)";
140                 int methodId = 0;
141                 Class<?> retType = void.class;
142                 Class<?>[] paramCls = new Class<?>[] { int.class };
143                 Object[] paramObj = new Object[] { _int };
144                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
145         }
146
147
148         public void setB(float _float) {
149
150                 int methodId = 1;
151                 Class<?> retType = void.class;
152                 Class<?>[] paramCls = new Class<?>[] { float.class };
153                 Object[] paramObj = new Object[] { _float };
154                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
155         }
156
157
158         public void setC(String _string) {
159
160                 int methodId = 2;
161                 Class<?> retType = void.class;
162                 Class<?>[] paramCls = new Class<?>[] { String.class };
163                 Object[] paramObj = new Object[] { _string };
164                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
165         }
166
167
168         // Getters
169         public String sumArray(String[] newA) {
170
171                 int methodId = 3;
172                 Class<?> retType = String.class;
173                 Class<?>[] paramCls = new Class<?>[] { String[].class };
174                 Object[] paramObj = new Object[] { newA };
175                 Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
176                 return (String)retObj;
177         }
178
179
180         public int setAndGetA(int newA) {
181                 int methodId = 4;
182                 Class<?> retType = int.class;
183                 Class<?>[] paramCls = new Class<?>[] { int.class };
184                 Object[] paramObj = new Object[] { newA };
185                 Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
186                 return (int)retObj;
187         }
188
189
190         public int setACAndGetA(String newC, int newA) {
191
192                 int methodId = 5;
193                 Class<?> retType = int.class;
194                 Class<?>[] paramCls = new Class<?>[] { String.class, int.class };
195                 Object[] paramObj = new Object[] { newC, newA };
196                 Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
197                 return (int)retObj;
198         }
199
200
201         public int callBack() {
202
203                 int methodId = 6;
204                 Class<?> retType = int.class;
205                 Class<?>[] paramCls = new Class<?>[] { };
206                 Object[] paramObj = new Object[] { };
207                 Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
208                 return (int)retObj;
209
210         }
211
212
213         public StructJ[] handleStruct(StructJ[] data) {
214
215                 int methodId = 11;
216                 Class<?> retType = void.class;
217                 Class<?>[] paramCls = new Class<?>[] { int.class };
218                 Object[] paramObj = new Object[] { data.length };
219                 rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
220
221                 int methodId2 = 10;
222                 Class<?> retType2 = int.class;  // return type is integer if it is a struct!!!
223                 // Calculate the size of the array
224                 Class<?>[] paramCls2 = new Class<?>[3*data.length];
225                 Object[] paramObj2 = new Object[3*data.length];
226                 // Handle with for loop
227                 int pos = 0;
228                 for(int i = 0; i < data.length; i++) {
229                         paramCls2[pos] = String.class;
230                         paramObj2[pos++] = data[i].name;
231                         paramCls2[pos] = float.class;
232                         paramObj2[pos++] = data[i].value;
233                         paramCls2[pos] = int.class;
234                         paramObj2[pos++] = data[i].year;
235                 }
236                 System.out.println(Arrays.toString(paramObj2));
237                 Object retObj = rmiCall.remoteCall(objectId, methodId2, retType2, null, paramCls2, paramObj2);
238                 // RETURN STRUCT
239                 // Get the length of the struct first
240                 int structsize1 = (int) retObj;
241                 // Construct the struct
242                 Class<?>[] retCls = new Class<?>[3*structsize1];
243                 Class<?>[] retClsVal = new Class<?>[3*structsize1];
244                 pos = 0;
245                 for(int i=0; i < structsize1; i++) {
246                         retCls[pos] = String.class;
247                         retClsVal[pos++] = null;
248                         retCls[pos] = float.class;
249                         retClsVal[pos++] = null;
250                         retCls[pos] = int.class;
251                         retClsVal[pos++] = null;
252                 }
253                 Object[] retObj2 = rmiCall.getStructObjects(retCls, 
254                         retClsVal);
255                 StructJ[] dataRet = new StructJ[structsize1];
256                 for (int i=0; i < structsize1; i++) {
257                         dataRet[i] = new StructJ();
258                 }
259                 pos = 0;
260                 for(int i=0; i < structsize1; i++) {
261                         dataRet[i].name = (String) retObj2[pos++];
262                         dataRet[i].value = (float) retObj2[pos++];
263                         dataRet[i].year = (int) retObj2[pos++];
264                 }
265
266                 return dataRet;
267         }
268
269
270         public EnumJ[] handleEnum(EnumJ[] en) {
271
272                 int methodId = 12;
273                 Class<?> retType = int[].class;
274                 // Handle with for loop
275                 int paramInt[] = new int[en.length];
276                 for(int i = 0; i < en.length; i++) {
277                         paramInt[i] = en[i].ordinal();
278                 }
279
280                 Class<?>[] paramCls = new Class<?>[] { int[].class };
281                 Object[] paramObj = new Object[] { paramInt };
282
283                 // if no return value just
284                 // rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
285                 // This is with return value:
286                 Object retObj = 
287                         rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
288                 int[] retEnumInt = (int[]) retObj;
289                 int enumsize1 = retEnumInt.length;
290                 // Encoder/decoder
291                 EnumJ[] enumJ = EnumJ.values();
292                 EnumJ[] enRetVal = new EnumJ[enumsize1];
293                 for(int i = 0; i < enumsize1; i++) {
294                         enRetVal[i] = enumJ[retEnumInt[i]];
295                 }
296                 return enRetVal;
297         }
298
299
300         public static void main(String[] args) throws Exception {
301
302                 CommunicationHandler comHan = new CommunicationHandler(true);
303                 int numOfPorts = TestClass_Stub.numCallbackObjects();
304                 int[] ports = comHan.getCallbackPorts(numOfPorts);
305
306                 int port = 5010;
307                 String address = "localhost";
308                 int rev = 0;
309
310                 System.out.println("Allocated ports: " + Arrays.toString(ports));
311
312                 TestClass_Stub tcstub = new TestClass_Stub(port, address, rev, ports);
313                 System.out.println("Return value: " + tcstub.setAndGetA(123));
314                 System.out.println("Return value: " + tcstub.setACAndGetA("string", 123));
315                 System.out.println("Return value: " + tcstub.sumArray(new String[] { "123", "456", "987" }));
316
317                 /*CallBackInterface cb1 = new CallBack(23);
318                 CallBackInterface cb2 = new CallBack(33);
319                 CallBackInterface cb3 = new CallBack(43);
320                 CallBackInterface[] cb = { cb1, cb2, cb3 };
321                 tcstub.registerCallback(cb);
322                 System.out.println("Return value from callback: " + tcstub.callBack());
323                 CallBackInterface cb4 = new CallBack(10);
324                 CallBackInterface cb5 = new CallBack(11);
325                 CallBackInterface cb6 = new CallBack(12);
326                 CallBackInterface[] cbt = { cb4, cb5, cb6 };
327                 tcstub.registerCallback(cbt);
328                 System.out.println("Return value from callback: " + tcstub.callBack());*/
329
330                 StructJ[] data = new StructJ[2];
331                 for (int i=0; i<2; i++) {
332                         data[i] = new StructJ();
333                 }
334                 data[0].name = "Rahmadi";
335                 data[0].value = 0.123f;
336                 data[0].year = 2016;
337                 //data[1].name = "Trimananda";
338                 //data[1].value = 0.223f;
339                 //data[1].year = 2017;
340
341                 for (StructJ str : data) {
342                         System.out.println("Name: " + str.name);
343                         System.out.println("Value: " + str.value);
344                         System.out.println("Year: " + str.year);
345                 }
346                 StructJ[] strj = tcstub.handleStruct(data);
347                 for (StructJ str : strj) {
348                         System.out.println("Name: " + str.name);
349                         System.out.println("Value: " + str.value);
350                         System.out.println("Year: " + str.year);
351                 }
352
353
354                 EnumJ[] en = { EnumJ.APPLE, EnumJ.ORANGE, EnumJ.APPLE, EnumJ.GRAPE };
355                 EnumJ[] res = tcstub.handleEnum(en);
356                 System.out.println("Enum members: " + Arrays.toString(res));
357         }
358 }
359
360