Combining enum, struct, and callback in one method; refactoring method body generatio...
[iot2.git] / iotjava / iotpolicy / IoTCompiler.java
index 5c3ab9226913c2a771b8cea644078b4ff9d5911d..1bd90c6d78259155aee65011d4bcdac8e00010cd 100644 (file)
@@ -742,7 +742,7 @@ public class IoTCompiler {
        /**
         * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
         */
-       private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
+       private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes, String callbackType) {
 
                print("int paramLen = ");
                writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
@@ -757,6 +757,16 @@ public class IoTCompiler {
                        String simpleType = getGenericType(paramType);
                        if (isStructClass(simpleType)) {
                                writeStructMembersJavaStub(simpleType, paramType, param);
+                       } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               println("paramCls[pos] = int.class;");
+                               print("paramObj[pos++] = ");
+                               if (isArray(methParams.get(i)))
+                                       print(getSimpleIdentifier(methParams.get(i)) + ".length");
+                               else if (isList(methPrmTypes.get(i)))
+                                       print(getSimpleIdentifier(methParams.get(i)) + ".size()");
+                               else
+                                       print("new Integer(1)");
+                               println(";");
                        } else {
                                String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
                                println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
@@ -859,6 +869,81 @@ public class IoTCompiler {
         * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
         */
        private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
+                       List<String> methPrmTypes, String method, String callbackType) {
+
+               checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
+               println("int methodId = " + intDecl.getMethodNumId(method) + ";");
+               String retType = intDecl.getMethodType(method);
+               println("Class<?> retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;");
+               checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes);
+               // Generate array of parameter types
+               if (isStructPresent(methParams, methPrmTypes)) {
+                       writeStructParamClassJavaStub(methParams, methPrmTypes, callbackType);
+               } else {
+                       print("Class<?>[] paramCls = new Class<?>[] { ");
+                       for (int i = 0; i < methParams.size(); i++) {
+                               String prmType = methPrmTypes.get(i);
+                               if (checkCallbackType(prmType, callbackType)) { // Check if this has callback object
+                                       print("int.class");
+                               } else { // Generate normal classes if it's not a callback object
+                                       String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+                                       print(getSimpleType(getEnumType(paramType)) + ".class");
+                               }
+                               // Check if this is the last element (don't print a comma)
+                               if (i != methParams.size() - 1) {
+                                       print(", ");
+                               }
+                       }
+                       println(" };");
+                       // Generate array of parameter objects
+                       print("Object[] paramObj = new Object[] { ");
+                       for (int i = 0; i < methParams.size(); i++) {
+                               String paramType = methPrmTypes.get(i);
+                               if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                                       //if (isArray(methPrmTypes.get(i), methParams.get(i)))
+                                       if (isArray(methParams.get(i)))
+                                               print(getSimpleIdentifier(methParams.get(i)) + ".length");
+                                       else if (isList(methPrmTypes.get(i)))
+                                               print(getSimpleIdentifier(methParams.get(i)) + ".size()");
+                                       else
+                                               print("new Integer(1)");
+                               } else
+                                       print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
+                               // Check if this is the last element (don't print a comma)
+                               if (i != methParams.size() - 1) {
+                                       print(", ");
+                               }
+                       }
+                       println(" };");
+               }
+               // Check if this is "void"
+               if (retType.equals("void")) {
+                       println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+               } else { // We do have a return value
+                       // Generate array of parameter types
+                       if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
+                               writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
+                       } else {
+                               // This is an enum type
+                               if (getParamCategory(getGenericType(getSimpleArrayType(retType))) == ParamCategory.ENUM) {
+                                       println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+                                       checkAndWriteEnumRetTypeJavaStub(retType);
+                               } else if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
+                               // Check if the return value NONPRIMITIVES
+                                       String retGenValType = getGenericType(retType);
+                                       println("Class<?> retGenValType = " + retGenValType + ".class;");
+                                       println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
+                                       println("return (" + retType + ")retObj;");
+                               } else {
+                                       println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+                                       println("return (" + retType + ")retObj;");
+                               }
+                       }
+               }
+       }
+
+
+       /*private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
                        List<String> methPrmTypes, String method) {
 
                checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
@@ -915,7 +1000,7 @@ public class IoTCompiler {
                                }
                        }
                }
-       }
+       }*/
 
 
        /**
@@ -936,7 +1021,10 @@ public class IoTCompiler {
        private boolean checkCallbackType(String paramType, String callbackType) {
 
                String prmType = returnGenericCallbackType(paramType);
-               return callbackType.equals(prmType);
+               if (callbackType == null)       // If there is no callbackType it means not a callback method
+                       return false;
+               else
+                       return callbackType.equals(prmType);
        }
 
 
@@ -968,6 +1056,34 @@ public class IoTCompiler {
                println("ex.printStackTrace();");
                println("throw new Error(\"Exception when generating skeleton objects!\");");
                println("}\n");
+       }
+
+
+/*     private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
+                       List<String> methPrmTypes, String method, String callbackType) {
+
+               println("try {");
+               // Check if this is single object, array, or list of objects
+               for (int i = 0; i < methParams.size(); i++) {
+                       String paramType = methPrmTypes.get(i);
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               String param = methParams.get(i);
+                               if (isArrayOrList(paramType, param)) {  // Generate loop
+                                       println("for (" + getGenericType(paramType) + " cb : " + getSimpleIdentifier(param) + ") {");
+                                       println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
+                               } else
+                                       println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(" +
+                                               getSimpleIdentifier(param) + ", objIdCnt++);");
+                               println("listCallbackObj.add(skel" + i + ");");
+                               if (isArrayOrList(paramType, param))
+                                       println("}");
+                       }
+               }
+               print("}");
+               println(" catch (Exception ex) {");
+               println("ex.printStackTrace();");
+               println("throw new Error(\"Exception when generating skeleton objects!\");");
+               println("}\n");
                println("int methodId = " + intDecl.getMethodNumId(method) + ";");
                String retType = intDecl.getMethodType(method);
                println("Class<?> retType = " + getSimpleType(getEnumType(retType)) + ".class;");
@@ -1018,7 +1134,7 @@ public class IoTCompiler {
                                println("return (" + retType + ")retObj;");
                        }
                }
-       }
+       }*/
 
 
        /**
@@ -1054,8 +1170,8 @@ public class IoTCompiler {
                        // Now, write the body of stub!
                        if (isCallbackMethod)
                                writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
-                       else
-                               writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method);
+                       //else
+                       writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
                        println("}\n");
                        // Write the init callback helper method
                        if (isCallbackMethod && !isDefined) {
@@ -1356,9 +1472,12 @@ public class IoTCompiler {
         * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
         */
        private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes, 
-                       String callbackType) {
+                       String callbackType, boolean isStructMethod) {
 
                Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
+               String offsetPfx = "";
+               if (isStructMethod)
+                       offsetPfx = "offset";
                // Iterate over callback objects
                for (int i = 0; i < methParams.size(); i++) {
                        String paramType = methPrmTypes.get(i);
@@ -1368,10 +1487,10 @@ public class IoTCompiler {
                                String exchParamType = checkAndGetParamClass(getGenericType(paramType));
                                // Print array if this is array or list if this is a list of callback objects
                                if (isArray(param)) {
-                                       println("int numStubs" + i + " = (int) paramObj[" + i + "];");
+                                       println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];");
                                        println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
                                } else if (isList(paramType)) {
-                                       println("int numStubs" + i + " = (int) paramObj[" + i + "];");
+                                       println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];");
                                        println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
                                } else {
                                        println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
@@ -1674,7 +1793,7 @@ public class IoTCompiler {
                checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
                Map<Integer,String> mapStubParam = null;
                if (isCallbackMethod) {
-                       mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
+                       mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType, isStructMethod);
                }
                // Check if this is "void"
                String retType = intDecl.getMethodType(method);
@@ -2605,8 +2724,8 @@ public class IoTCompiler {
                        println(") { ");
                        if (isCallbackMethod)
                                writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
-                       else
-                               writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackClasses);
+                       //else
+                       writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType, isCallbackMethod);
                        println("}\n");
                        // Write the init callback helper method
                        if (isCallbackMethod && !isDefined) {
@@ -2624,6 +2743,37 @@ public class IoTCompiler {
        private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
                        List<String> methPrmTypes, String method, String callbackType) {
 
+               // Check if this is single object, array, or list of objects
+               boolean isArrayOrList = false;
+               String callbackParam = null;
+               for (int i = 0; i < methParams.size(); i++) {
+
+                       String paramType = methPrmTypes.get(i);
+                       if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               String param = methParams.get(i);
+                               if (isArrayOrList(paramType, param)) {  // Generate loop
+                                       println("for (" + getGenericType(paramType) + "* cb : " + getSimpleIdentifier(param) + ") {");
+                                       println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
+                                       isArrayOrList = true;
+                                       callbackParam = getSimpleIdentifier(param);
+                               } else
+                                       println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(" +
+                                               getSimpleIdentifier(param) + ", objIdCnt++);");
+                               println("vecCallbackObj.push_back(skel" + i + ");");
+                               if (isArrayOrList)
+                                       println("}");
+                       }
+               }
+               print("int ___paramCB = ");
+               if (isArrayOrList)
+                       println(callbackParam + ".size();");
+               else
+                       println("1;");
+       }
+
+/*     private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
+                       List<String> methPrmTypes, String method, String callbackType) {
+
                // Check if this is single object, array, or list of objects
                boolean isArrayOrList = false;
                String callbackParam = null;
@@ -2695,7 +2845,7 @@ public class IoTCompiler {
                        println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
                        println("return retVal;");
                }
-       }
+       }*/
 
 
        /**
@@ -2850,7 +3000,7 @@ public class IoTCompiler {
        /**
         * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
         */
-       private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
+       private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes, String callbackType) {
 
                print("int numParam = ");
                writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
@@ -2865,6 +3015,9 @@ public class IoTCompiler {
                        String simpleType = getGenericType(paramType);
                        if (isStructClass(simpleType)) {
                                writeStructMembersCplusStub(simpleType, paramType, param);
+                       } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+                               println("paramCls[pos] = \"int\";");
+                               println("paramObj[pos++] = &___paramCB;");
                        } else {
                                String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
                                println("paramCls[pos] = \"" + prmTypeC + "\";");
@@ -2968,7 +3121,7 @@ public class IoTCompiler {
         * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
         */
        private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
-                       List<String> methPrmTypes, String method, Set<String> callbackClasses) {
+                       List<String> methPrmTypes, String method, String callbackType, boolean isCallbackMethod) {
 
                checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
                println("int methodId = " + intDecl.getMethodNumId(method) + ";");
@@ -2977,13 +3130,13 @@ public class IoTCompiler {
                checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
                // Generate array of parameter types
                if (isStructPresent(methParams, methPrmTypes)) {
-                       writeStructParamClassCplusStub(methParams, methPrmTypes);
+                       writeStructParamClassCplusStub(methParams, methPrmTypes, callbackType);
                } else {
                        println("int numParam = " + methParams.size() + ";");
                        print("string paramCls[] = { ");
                        for (int i = 0; i < methParams.size(); i++) {
                                String paramType = returnGenericCallbackType(methPrmTypes.get(i));
-                               if (callbackClasses.contains(paramType)) {
+                               if (checkCallbackType(paramType, callbackType)) {
                                        print("\"int\"");
                                } else {
                                        String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
@@ -2998,7 +3151,11 @@ public class IoTCompiler {
                        // Generate array of parameter objects
                        print("void* paramObj[] = { ");
                        for (int i = 0; i < methParams.size(); i++) {
-                               print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
+                               String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+                               if (checkCallbackType(paramType, callbackType)) // Check if this has callback object
+                                       print("&___paramCB");
+                               else
+                                       print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
                                // Check if this is the last element (don't print a comma)
                                if (i != methParams.size() - 1) {
                                        print(", ");
@@ -3696,7 +3853,7 @@ public class IoTCompiler {
 
 
        /**
-        * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
+        * HELPER: writeMethodInputParameters() writes the parameter variables for C++ skeleton
         */
        private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes, 
                        Set<String> callbackClasses, String methodId) {
@@ -3982,8 +4139,8 @@ public class IoTCompiler {
                                String prmType = returnGenericCallbackType(methPrmTypes.get(i));
                                if (callbackClasses.contains(prmType)) {
                                        isCallbackMethod = true;
-                                       callbackType = paramType;
-                                       writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
+                                       callbackType = prmType;
+                                       println("int numStubs" + i + " = 0;");
                                        println("paramCls[pos] = \"int\";");
                                        println("paramObj[pos++] = &numStubs" + i + ";");
                                } else {        // Generate normal classes if it's not a callback object