Adding struct support for Java in compiler
[iot2.git] / iotjava / iotrmi / Java / sample / TestClass_Stub.java
index 39411a75f64f8bc4927f7e11291923d203916231..2a45396eed3b0303b670031248be1438116031a0 100644 (file)
@@ -5,6 +5,10 @@ import iotrmi.Java.IoTRMICall;
 import iotruntime.master.CommunicationHandler;
 
 import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+
+import iotrmi.Java.IoTRMIObject;
 
 public class TestClass_Stub implements TestClassInterface {
 
@@ -12,22 +16,40 @@ public class TestClass_Stub implements TestClassInterface {
         * Class Properties
         */
        private IoTRMICall rmiCall;
+       private IoTRMIObject rmiObj;
        private String address;
        private int[] ports;
 
        /**
         * Class Constants
         */
+       private int objectId = 0;       // Default value is 0
+       // This is permission system for callback objects
+       private static Integer[] object0Permission = { 0, 1 };  // object0 is the callback object
+       private List<Integer> set0Allowed;
+
+       /**
+        * Properties and constants for Callbacks!
+        */
+       private List<CallBackInterface> listCBObj;
        private final static int NUM_CB_OBJ = 1;
+       private static int objIdCnt = 0; // Counter for callback object Ids
+
 
        /**
         * Constructors
         */
-       public TestClass_Stub(int _port, String _address, int _rev, int[] _ports) throws IOException {
+       public TestClass_Stub(int _port, String _address, int _rev, int[] _ports) throws Exception {
 
                address = _address;
                ports = _ports;
                rmiCall = new IoTRMICall(_port, _address, _rev);
+
+               set0Allowed = Arrays.asList(object0Permission);
+
+               // Only for callbacks!!!
+               listCBObj = new ArrayList<CallBackInterface>();
+               ___initCallBack();
        }
 
 
@@ -40,16 +62,54 @@ public class TestClass_Stub implements TestClassInterface {
        }
 
 
-       public void registerCallback(CallBackInterface _cb) {
-
-               //int port = 5011;      // Send this info to the other end to start the stub
-               //String address = "localhost";
+       // Initialize callback
+       public void ___initCallBack() {
 
                Thread thread = new Thread() {
                        public void run() {
+                       try{
+                                       System.out.println("Created server with port: " + ports[0]);
+                                       rmiObj = new IoTRMIObject(ports[0]);
+                                       Object retObj = null;
+                                       while (true) {
+                                               byte[] method = rmiObj.getMethodBytes();
+                                               // Permission checking
+                                               int methId = IoTRMIObject.getMethodId(method);
+                                               if (!set0Allowed.contains(methId))
+                                                       throw new Error("CallBack_CBSkeleton: This object is not allowed to access method " + methId);
+
+                                               int objId = IoTRMIObject.getObjectId(method);
+                                               CallBack_CBSkeleton skel = (CallBack_CBSkeleton) listCBObj.get(objId);
+                                               if (skel != null) {
+                                                       //rmiObj.setMethodBytes(method);
+                                                       skel.invokeMethod(rmiObj);
+                                               }
+                                       }
+                               } catch (Exception ex){
+                                       ex.printStackTrace();
+                                       throw new Error("Error instantiating class CallBack_Skeleton!");
+                       }
+                   }
+               };
+               thread.start();
+
+               //String sign = "registercallback";     // can be any string
+               int methodId = 9;
+               Class<?> retType = void.class;
+               // port, address, rev
+               Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };
+               Object[] paramObj = new Object[] { ports[0], address, 0 };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+
+       // Single callback handling
+       public void registerCallback(CallBackInterface _cb) {
+
+               /*Thread thread = new Thread() {
+                       public void run() {
                    try{
                                        CallBack_Skeleton cbskel = new CallBack_Skeleton(_cb, ports[0]);
-                                       cbskel.waitRequestInvokeMethod();
                                } catch (Exception ex){
                                        ex.printStackTrace();
                                        throw new Error("Error instantiating class CallBack_Skeleton!");
@@ -63,105 +123,255 @@ public class TestClass_Stub implements TestClassInterface {
                // port, address, and rev
                Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };
                Object[] paramObj = new Object[] { ports[0], address, 0 };
-               rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj);*/
+       }
+
+
+       public void registerCallback(CallBackInterface[] _cb) {
+
+               try {
+                       //for (int objId = 0; objId < _cb.length; objId++) {
+                       for (CallBackInterface cb : _cb) {
+                               CallBack_CBSkeleton skel = new CallBack_CBSkeleton(cb, objIdCnt++);
+                               listCBObj.add(skel);
+                       }
+               } catch (Exception ex){
+                       ex.printStackTrace();
+                       throw new Error("Class not found / instantiation / illegal access / IO error!");
+               }
+
+               //String sign = "voidregisterCallBack(CallBackInterface[])";
+               int methodId = 8;
+               Class<?> retType = void.class;
+               // port, address, rev, and number of objects
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { _cb.length };
+               //rmiCall.remoteCall(objectId, sign, retType, null, null, paramCls, paramObj);
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
        }
 
 
        public void setA(int _int) {
 
-               String sign = "voidsetA(int)";
+               //String sign = "voidsetA(int)";
+               int methodId = 0;
                Class<?> retType = void.class;
                Class<?>[] paramCls = new Class<?>[] { int.class };
                Object[] paramObj = new Object[] { _int };
-               rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
        }
 
 
        public void setB(float _float) {
 
-               String sign = "voidsetB(float)";
+               int methodId = 1;
                Class<?> retType = void.class;
                Class<?>[] paramCls = new Class<?>[] { float.class };
                Object[] paramObj = new Object[] { _float };
-               rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
        }
 
 
        public void setC(String _string) {
 
-               String sign = "voidsetC(string)";
+               int methodId = 2;
                Class<?> retType = void.class;
                Class<?>[] paramCls = new Class<?>[] { String.class };
                Object[] paramObj = new Object[] { _string };
-               rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
        }
 
 
        // Getters
        public String sumArray(String[] newA) {
 
-               String sign = "sumArray(string[])";
+               int methodId = 3;
                Class<?> retType = String.class;
                Class<?>[] paramCls = new Class<?>[] { String[].class };
                Object[] paramObj = new Object[] { newA };
-               Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
                return (String)retObj;
        }
 
 
        public int setAndGetA(int newA) {
-               String sign = "intsetAndGetA(int)";
+               int methodId = 4;
                Class<?> retType = int.class;
                Class<?>[] paramCls = new Class<?>[] { int.class };
                Object[] paramObj = new Object[] { newA };
-               Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
                return (int)retObj;
        }
 
 
        public int setACAndGetA(String newC, int newA) {
 
-               String sign = "intsetACAndGetA(string,int)";
+               int methodId = 5;
                Class<?> retType = int.class;
                Class<?>[] paramCls = new Class<?>[] { String.class, int.class };
                Object[] paramObj = new Object[] { newC, newA };
-               Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
                return (int)retObj;
        }
 
 
        public int callBack() {
 
-               String sign = "intcallBack()";
+               int methodId = 6;
                Class<?> retType = int.class;
                Class<?>[] paramCls = new Class<?>[] { };
                Object[] paramObj = new Object[] { };
-               Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
                return (int)retObj;
 
        }
 
 
+       public StructJ[] handleStruct(StructJ[] data) {
+
+               int methodId = 11;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { data.length };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+
+               int methodId2 = 10;
+               Class<?> retType2 = int.class;  // return type is integer if it is a struct!!!
+               // Calculate the size of the array
+               Class<?>[] paramCls2 = new Class<?>[3*data.length];
+               Object[] paramObj2 = new Object[3*data.length];
+               // Handle with for loop
+               int pos = 0;
+               for(int i = 0; i < data.length; i++) {
+                       paramCls2[pos] = String.class;
+                       paramObj2[pos++] = data[i].name;
+                       paramCls2[pos] = float.class;
+                       paramObj2[pos++] = data[i].value;
+                       paramCls2[pos] = int.class;
+                       paramObj2[pos++] = data[i].year;
+               }
+               //System.out.println(Arrays.toString(paramObj2));
+               Object retObj = rmiCall.remoteCall(objectId, methodId2, retType2, null, paramCls2, paramObj2);
+               // RETURN STRUCT
+               // Get the length of the struct first
+               int structsize1 = (int) retObj;
+               // Construct the struct
+               Class<?>[] retCls = new Class<?>[3*structsize1];
+               Class<?>[] retClsVal = new Class<?>[3*structsize1];
+               pos = 0;
+               for(int i=0; i < structsize1; i++) {
+                       retCls[pos] = String.class;
+                       retClsVal[pos++] = null;
+                       retCls[pos] = float.class;
+                       retClsVal[pos++] = null;
+                       retCls[pos] = int.class;
+                       retClsVal[pos++] = null;
+               }
+               Object[] retObj2 = rmiCall.getStructObjects(retCls, 
+                       retClsVal);
+               StructJ[] dataRet = new StructJ[structsize1];
+               for (int i=0; i < structsize1; i++) {
+                       dataRet[i] = new StructJ();
+               }
+               pos = 0;
+               for(int i=0; i < structsize1; i++) {
+                       dataRet[i].name = (String) retObj2[pos++];
+                       dataRet[i].value = (float) retObj2[pos++];
+                       dataRet[i].year = (int) retObj2[pos++];
+               }
+
+               return dataRet;
+       }
+
+
+       public EnumJ[] handleEnum(EnumJ[] en) {
+
+               int methodId = 12;
+               Class<?> retType = int[].class;
+               // Handle with for loop
+               int paramInt[] = new int[en.length];
+               for(int i = 0; i < en.length; i++) {
+                       paramInt[i] = en[i].ordinal();
+               }
+
+               Class<?>[] paramCls = new Class<?>[] { int[].class };
+               Object[] paramObj = new Object[] { paramInt };
+
+               // if no return value just
+               // rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               // This is with return value:
+               Object retObj = 
+                       rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               int[] retEnumInt = (int[]) retObj;
+               int enumsize1 = retEnumInt.length;
+               // Encoder/decoder
+               EnumJ[] enumJ = EnumJ.values();
+               EnumJ[] enRetVal = new EnumJ[enumsize1];
+               for(int i = 0; i < enumsize1; i++) {
+                       enRetVal[i] = enumJ[retEnumInt[i]];
+               }
+               return enRetVal;
+       }
+
+
        public static void main(String[] args) throws Exception {
 
                CommunicationHandler comHan = new CommunicationHandler(true);
                int numOfPorts = TestClass_Stub.numCallbackObjects();
                int[] ports = comHan.getCallbackPorts(numOfPorts);
 
-               System.out.println("Allocated ports: " + Arrays.toString(ports));
-
                int port = 5010;
                String address = "localhost";
                int rev = 0;
 
+               System.out.println("Allocated ports: " + Arrays.toString(ports));
+
                TestClass_Stub tcstub = new TestClass_Stub(port, address, rev, ports);
                System.out.println("Return value: " + tcstub.setAndGetA(123));
                System.out.println("Return value: " + tcstub.setACAndGetA("string", 123));
                System.out.println("Return value: " + tcstub.sumArray(new String[] { "123", "456", "987" }));
 
-               CallBack cb = new CallBack(23);
+               /*CallBackInterface cb1 = new CallBack(23);
+               CallBackInterface cb2 = new CallBack(33);
+               CallBackInterface cb3 = new CallBack(43);
+               CallBackInterface[] cb = { cb1, cb2, cb3 };
                tcstub.registerCallback(cb);
                System.out.println("Return value from callback: " + tcstub.callBack());
-               //System.out.println("Return value: " + tcstub.setAndGetA(1234));
+               CallBackInterface cb4 = new CallBack(10);
+               CallBackInterface cb5 = new CallBack(11);
+               CallBackInterface cb6 = new CallBack(12);
+               CallBackInterface[] cbt = { cb4, cb5, cb6 };
+               tcstub.registerCallback(cbt);
+               System.out.println("Return value from callback: " + tcstub.callBack());*/
+
+               StructJ[] data = new StructJ[2];
+               for (int i=0; i<2; i++) {
+                       data[i] = new StructJ();
+               }
+               data[0].name = "Rahmadi";
+               data[0].value = 0.123f;
+               data[0].year = 2016;
+               //data[1].name = "Trimananda";
+               //data[1].value = 0.223f;
+               //data[1].year = 2017;
+
+               for (StructJ str : data) {
+                       System.out.println("Name: " + str.name);
+                       System.out.println("Value: " + str.value);
+                       System.out.println("Year: " + str.year);
+               }
+               StructJ[] strj = tcstub.handleStruct(data);
+               for (StructJ str : strj) {
+                       System.out.println("Name: " + str.name);
+                       System.out.println("Value: " + str.value);
+                       System.out.println("Year: " + str.year);
+               }
+
+
+               EnumJ[] en = { EnumJ.APPLE, EnumJ.ORANGE, EnumJ.APPLE, EnumJ.GRAPE };
+               EnumJ[] res = tcstub.handleEnum(en);
+               System.out.println("Enum members: " + Arrays.toString(res));
        }
 }
+
+