X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=iotjava%2Fiotpolicy%2FIoTCompiler.java;h=857199833799691896a5153f3e01c368d18319ec;hb=2fad50e1aa24179079a3b04904b7fd945e642d46;hp=e8abdfa8c54e313d296791cb67d78ec7f20efbb1;hpb=8946012fd7b634404bffa2d3977c309f4e31bcb7;p=iot2.git diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index e8abdfa..8571998 100644 --- a/iotjava/iotpolicy/IoTCompiler.java +++ b/iotjava/iotpolicy/IoTCompiler.java @@ -59,6 +59,7 @@ public class IoTCompiler { private String dir; private String subdir; + /** * Class constants */ @@ -73,6 +74,7 @@ public class IoTCompiler { USERDEFINED // Assumed as driver classes } + /** * Class constructors */ @@ -104,7 +106,6 @@ public class IoTCompiler { * data structures. * Additionally, the data structure handles are * returned from tree-parsing for further process. - * */ public void setDataStructures(String origInt, ParseNode pnPol, ParseNode pnReq) { @@ -183,7 +184,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodJavaLocalInterface() writes the method of the interface + * HELPER: writeMethodJavaLocalInterface() writes the method of the local interface */ private void writeMethodJavaLocalInterface(Collection methods, InterfaceDecl intDecl) { @@ -326,16 +327,12 @@ public class IoTCompiler { InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); Set importClasses = getImportClasses(methods, intDecl); - printImportStatements(importClasses); + List stdImportClasses = getStandardJavaIntfaceImportClasses(); + List allImportClasses = getAllLibClasses(stdImportClasses, importClasses); + printImportStatements(allImportClasses); // Write interface header println(""); println("public interface " + intface + " {"); - // Write enum if any... - //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); - //writeEnumJava(enumDecl); - // Write struct if any... - //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); - //writeStructJava(structDecl); // Write methods writeMethodJavaLocalInterface(methods, intDecl); println("}"); @@ -364,13 +361,16 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); // Pass in set of methods and get import classes - Set importClasses = getImportClasses(intMeth.getValue(), intDecl); - printImportStatements(importClasses); + List methods = intDecl.getMethods(); + Set importClasses = getImportClasses(methods, intDecl); + List stdImportClasses = getStandardJavaIntfaceImportClasses(); + List allImportClasses = getAllLibClasses(stdImportClasses, importClasses); + printImportStatements(allImportClasses); // Write interface header println(""); println("public interface " + newIntface + " {\n"); // Write methods - writeMethodJavaInterface(intMeth.getValue(), intDecl); + writeMethodJavaInterface(methods, intDecl); println("}"); pw.close(); System.out.println("IoTCompiler: Generated interface " + newIntface + ".java..."); @@ -387,7 +387,7 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("private final static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface); Set methodIds = intMeth.getValue(); @@ -446,7 +446,7 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);"); } } @@ -482,7 +482,7 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("if (!set" + newObjectId + "Allowed.contains(methodId)) {"); println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);"); println("}"); @@ -491,7 +491,7 @@ public class IoTCompiler { /** - * HELPER: writeConstructorJavaStub() writes the constructor of the stub class + * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub */ private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) { @@ -508,11 +508,13 @@ public class IoTCompiler { println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);"); println("if (skel != null) {"); println("skel.invokeMethod(rmiObj);"); - println("} else {"); + print("}"); + println(" else {"); println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");"); println("}"); println("}"); - println("} catch (Exception ex) {"); + print("}"); + println(" catch (Exception ex) {"); println("ex.printStackTrace();"); println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");"); println("}"); @@ -649,7 +651,7 @@ public class IoTCompiler { /** - * HELPER: writeLengthStructParamClassJavaStub() writes lengths of params + * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters */ private void writeLengthStructParamClassJavaStub(List methParams, List methPrmTypes) { @@ -743,7 +745,7 @@ public class IoTCompiler { /** - * HELPER: writeStructRetMembersJavaStub() writes parameters of struct + * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement */ private void writeStructRetMembersJavaStub(String simpleType, String retType) { @@ -752,7 +754,7 @@ public class IoTCompiler { List memTypes = structDecl.getMemberTypes(simpleType); List members = structDecl.getMembers(simpleType); if (isArrayOrList(retType, retType)) { // An array or list - println("for(int i = 0; i < retLen.length; i++) {"); + println("for(int i = 0; i < retLen; i++) {"); } if (isArray(retType)) { // An array for (int i = 0; i < members.size(); i++) { @@ -782,7 +784,7 @@ public class IoTCompiler { /** - * HELPER: writeStructReturnJavaStub() writes parameters if struct is present + * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement */ private void writeStructReturnJavaStub(String simpleType, String retType) { @@ -922,7 +924,6 @@ public class IoTCompiler { 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); @@ -937,7 +938,8 @@ public class IoTCompiler { println("}"); } } - println("} catch (Exception ex) {"); + print("}"); + println(" catch (Exception ex) {"); println("ex.printStackTrace();"); println("throw new Error(\"Exception when generating skeleton objects!\");"); println("}\n"); @@ -995,7 +997,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodJavaStub() writes the method of the stub class + * HELPER: writeMethodJavaStub() writes the methods of the stub class */ private void writeMethodJavaStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { @@ -1289,7 +1291,8 @@ public class IoTCompiler { /** * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part */ - private Map writeCallbackJavaStubGeneration(List methParams, List methPrmTypes, String callbackType) { + private Map writeCallbackJavaStubGeneration(List methParams, List methPrmTypes, + String callbackType) { Map mapStubParam = new HashMap(); // Iterate over callback objects @@ -1425,9 +1428,9 @@ public class IoTCompiler { /** - * HELPER: writeLengthStructParamClassJavaSkeleton() writes lengths of params + * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params */ - private void writeLengthStructParamClassJavaSkeleton(List methParams, List methPrmTypes, + private void writeLengthStructParamClassSkeleton(List methParams, List methPrmTypes, String method, InterfaceDecl intDecl) { // Iterate and find struct declarations - count number of params @@ -1450,7 +1453,7 @@ public class IoTCompiler { /** - * HELPER: writeStructMembersJavaSkeleton() writes parameters of struct + * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct */ private void writeStructMembersJavaSkeleton(String simpleType, String paramType, String param, String method, InterfaceDecl intDecl, int iVar) { @@ -1483,9 +1486,8 @@ public class IoTCompiler { } - /** - * HELPER: writeStructMembersInitJavaSkeleton() writes parameters of struct + * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct */ private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List methParams, List methPrmTypes, String method) { @@ -1504,7 +1506,7 @@ public class IoTCompiler { println("paramStruct" + i + "[i] = new " + simpleType + "();"); println("}"); } else if (isList(paramType)) { // A list - println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();"); + println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();"); } else println(simpleType + " paramStruct" + i + " = new " + simpleType + "();"); println("int objPos = 0;"); @@ -1547,7 +1549,7 @@ public class IoTCompiler { /** - * HELPER: writeStructReturnJavaSkeleton() writes parameters if struct is present + * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement */ private void writeStructReturnJavaSkeleton(String simpleType, String retType) { @@ -1592,46 +1594,12 @@ public class IoTCompiler { /** - * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton + * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton */ - private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method, Set callbackClasses) { + private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, boolean isCallbackMethod, String callbackType, + boolean isStructMethod) { - // Generate array of parameter objects - boolean isCallbackMethod = false; - String callbackType = null; - print("int paramLen = "); - writeLengthStructParamClassJavaSkeleton(methParams, methPrmTypes, method, intDecl); - println(";"); - println("Class[] paramCls = new Class[paramLen];"); - println("Class[] paramClsGen = new Class[paramLen];"); - // Iterate again over the parameters - for (int i = 0; i < methParams.size(); i++) { - String paramType = methPrmTypes.get(i); - String param = methParams.get(i); - String simpleType = getGenericType(paramType); - if (isStructClass(simpleType)) { - writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i); - } else { - String prmType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(prmType)) { - isCallbackMethod = true; - callbackType = prmType; - print("int.class"); - } else { // Generate normal classes if it's not a callback object - String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;"); - print("paramClsGen[pos++] = "); - String prmTypeOth = methPrmTypes.get(i); - if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES) - println(getTypeOfGeneric(prmType)[0] + ".class;"); - else - println("null;"); - } - } - } - println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);"); - writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method); checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes); Map mapStubParam = null; if (isCallbackMethod) @@ -1657,7 +1625,10 @@ public class IoTCompiler { print("paramStruct" + i); } else { String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print("(" + prmType + ") paramObj[offset" + i + "]"); + if (isStructMethod) + print("(" + prmType + ") paramObj[offset" + i + "]"); + else + print("(" + prmType + ") paramObj[" + i + "]"); } if (i != methParams.size() - 1) print(", "); @@ -1674,11 +1645,59 @@ public class IoTCompiler { println("rmiObj.sendReturnObj(retObj);"); } if (isCallbackMethod) { // Catch exception if this is callback - println("} catch(Exception ex) {"); + print("}"); + println(" catch(Exception ex) {"); println("ex.printStackTrace();"); println("throw new Error(\"Exception from callback object instantiation!\");"); println("}"); - } + } + } + + + /** + * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton + */ + private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, Set callbackClasses) { + + // Generate array of parameter objects + boolean isCallbackMethod = false; + String callbackType = null; + print("int paramLen = "); + writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl); + println(";"); + println("Class[] paramCls = new Class[paramLen];"); + println("Class[] paramClsGen = new Class[paramLen];"); + // Iterate again over the parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i); + } else { + String prmType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(prmType)) { + isCallbackMethod = true; + callbackType = prmType; + println("paramCls[pos] = int.class;"); + println("paramClsGen[pos++] = null;"); + } else { // Generate normal classes if it's not a callback object + String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;"); + print("paramClsGen[pos++] = "); + String prmTypeOth = methPrmTypes.get(i); + if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES) + println(getTypeOfGeneric(prmType)[0] + ".class;"); + else + println("null;"); + } + } + } + println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);"); + writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method); + // Write the return value part + writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true); } @@ -1719,51 +1738,8 @@ public class IoTCompiler { print(", "); } println(" });"); - checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes); - Map mapStubParam = null; - if (isCallbackMethod) - mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - if (retType.equals("void")) { - print(intDecl.getMethodId(method) + "("); - } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type - checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method)); - } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type - print(retType + " retStruct = " + intDecl.getMethodId(method) + "("); - } else { // We do have a return value - print("Object retObj = " + intDecl.getMethodId(method) + "("); - } - for (int i = 0; i < methParams.size(); i++) { - - if (isCallbackMethod) { - print(mapStubParam.get(i)); // Get the callback parameter - } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class - print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i)); - } else { - String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print("(" + prmType + ") paramObj[" + i + "]"); - } - if (i != methParams.size() - 1) - print(", "); - } - println(");"); - if (!retType.equals("void")) { - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type - checkAndWriteEnumRetConvJavaSkeleton(retType); - println("rmiObj.sendReturnObj(retObj);"); - } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type - writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); - println("rmiObj.sendReturnObj(retCls, retObj);"); - } else - println("rmiObj.sendReturnObj(retObj);"); - } - if (isCallbackMethod) { // Catch exception if this is callback - println("} catch(Exception ex) {"); - println("ex.printStackTrace();"); - println("throw new Error(\"Exception from callback object instantiation!\");"); - println("}"); - } + // Write the return value part + writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false); } @@ -1800,7 +1776,6 @@ public class IoTCompiler { int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } - // TODO: Need to create comma separation } // Check if this is "void" if (retType.equals("void")) @@ -1834,7 +1809,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of the struct in skeleton class + * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class */ private void writeMethodHelperStructSetupJavaSkeleton(Collection methods, InterfaceDecl intDecl) { @@ -1865,9 +1840,40 @@ public class IoTCompiler { /** - * HELPER: writeCountVarStructJavaSkeleton() writes counter variable of struct for skeleton + * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class + */ + private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection methods, + InterfaceDecl intDecl) { + + // Use this set to handle two same methodIds + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + // Check for params with structs + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("public int ___"); + String helperMethod = methodNumId + "struct" + i; + println(helperMethod + "(IoTRMIObject rmiObj) {"); + // Now, write the helper body of skeleton! + println("Object[] paramObj = rmiObj.getMethodParams(new Class[] { int.class }, new Class[] { null });"); + println("return (int) paramObj[0];"); + println("}\n"); + } + } + } + } + + + /** + * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton */ - private void writeCountVarStructJavaSkeleton(Collection methods, InterfaceDecl intDecl) { + private void writeCountVarStructSkeleton(Collection methods, InterfaceDecl intDecl) { // Use this set to handle two same methodIds for (String method : methods) { @@ -1889,12 +1895,13 @@ public class IoTCompiler { /** - * HELPER: writeInputCountVarStructJavaSkeleton() writes counter variable of struct for skeleton + * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton */ - private void writeInputCountVarStructJavaSkeleton(String method, InterfaceDecl intDecl) { + private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); + boolean structExist = false; // Check for params with structs for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); @@ -1902,6 +1909,7 @@ public class IoTCompiler { String simpleType = getSimpleType(paramType); boolean begin = true; if (isStructClass(simpleType)) { + structExist = true; if (!begin) { print(", "); begin = false; } @@ -1909,13 +1917,14 @@ public class IoTCompiler { print("struct" + methodNumId + "Size" + i); } } + return structExist; } /** - * HELPER: writeMethodCallStructJavaSkeleton() writes method call for wait invoke in skeleton + * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton */ - private void writeMethodCallStructJavaSkeleton(Collection methods, InterfaceDecl intDecl) { + private void writeMethodCallStructSkeleton(Collection methods, InterfaceDecl intDecl) { // Use this set to handle two same methodIds for (String method : methods) { @@ -1941,6 +1950,35 @@ public class IoTCompiler { } + /** + * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton + */ + private void writeMethodCallStructCallbackSkeleton(Collection methods, InterfaceDecl intDecl) { + + // Use this set to handle two same methodIds + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + // Check for params with structs + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("case "); + String helperMethod = methodNumId + "struct" + i; + String tempVar = "struct" + methodNumId + "Size" + i; + print(intDecl.getHelperMethodNumId(helperMethod) + ": "); + print(tempVar + " = ___"); + println(helperMethod + "(rmiObj); break;"); + } + } + } + } + + /** * HELPER: writeJavaMethodPermission() writes permission checks in skeleton */ @@ -1950,15 +1988,15 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("if (_objectId == object" + newObjectId + "Id) {"); println("if (!set" + newObjectId + "Allowed.contains(methodId)) {"); println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);"); println("}"); + println("}"); println("else {"); println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");"); println("}"); - println("}"); } } @@ -1972,7 +2010,7 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("private void ___waitRequestInvokeMethod() throws IOException {"); // Write variables here if we have callbacks or enums or structs - writeCountVarStructJavaSkeleton(methods, intDecl); + writeCountVarStructSkeleton(methods, intDecl); println("while (true) {"); println("rmiObj.getMethodBytes();"); println("int _objectId = rmiObj.getObjectId();"); @@ -1991,7 +2029,7 @@ public class IoTCompiler { else uniqueMethodIds.add(methodId); print(helperMethod + "("); - writeInputCountVarStructJavaSkeleton(method, intDecl); + writeInputCountVarStructSkeleton(method, intDecl); println("); break;"); } String method = "___initCallBack()"; @@ -2000,7 +2038,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(); break;"); } - writeMethodCallStructJavaSkeleton(methods, intDecl); + writeMethodCallStructSkeleton(methods, intDecl); println("default: "); println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");"); println("}"); @@ -2092,28 +2130,62 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - String methodId = intDecl.getMethodId(method); - print("public void ___"); - String helperMethod = methodId; - if (uniqueMethodIds.contains(methodId)) - helperMethod = helperMethod + intDecl.getMethodNumId(method); - else - uniqueMethodIds.add(methodId); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - if (retType.equals("void")) - println(helperMethod + "(IoTRMIObject rmiObj) {"); - else - println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {"); - // Now, write the helper body of skeleton! - writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses); - println("}\n"); + if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently + String methodId = intDecl.getMethodId(method); + print("public void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + String retType = intDecl.getMethodType(method); + print(helperMethod + "("); + boolean begin = true; + for (int i = 0; i < methParams.size(); i++) { // Print size variables + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + if (!begin) { // Generate comma for not the beginning variable + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("int struct" + methodNumId + "Size" + i); + } + } + // Check if this is "void" + if (retType.equals("void")) + println(", IoTRMIObject rmiObj) {"); + else + println(", IoTRMIObject rmiObj) throws IOException {"); + writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses); + println("}\n"); + } else { + String methodId = intDecl.getMethodId(method); + print("public void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + if (retType.equals("void")) + println(helperMethod + "(IoTRMIObject rmiObj) {"); + else + println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses); + println("}\n"); + } } + // Write method helper for structs + writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl); } /** - * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the main loop of the skeleton class + * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the request invoke method of the callback skeleton class */ private void writeJavaCallbackWaitRequestInvokeMethod(Collection methods, InterfaceDecl intDecl, boolean callbackExist) { @@ -2121,6 +2193,8 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {"); // Write variables here if we have callbacks or enums or structs + writeCountVarStructSkeleton(methods, intDecl); + // Write variables here if we have callbacks or enums or structs println("int methodId = rmiObj.getMethodId();"); // TODO: code the permission check here! println("switch (methodId) {"); @@ -2134,7 +2208,11 @@ public class IoTCompiler { helperMethod = helperMethod + methodNumId; else uniqueMethodIds.add(methodId); - println(helperMethod + "(rmiObj); break;"); + print(helperMethod + "("); + if (writeInputCountVarStructSkeleton(method, intDecl)) + println(", rmiObj); break;"); + else + println("rmiObj); break;"); } String method = "___initCallBack()"; // Print case -9999 (callback handler) if callback exists @@ -2142,6 +2220,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(rmiObj); break;"); } + writeMethodCallStructCallbackSkeleton(methods, intDecl); println("default: "); println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");"); println("}"); @@ -2193,7 +2272,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodCplusLocalInterface() writes the method of the interface + * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface */ private void writeMethodCplusLocalInterface(Collection methods, InterfaceDecl intDecl) { @@ -2358,11 +2437,6 @@ public class IoTCompiler { Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); printIncludeStatements(includeClasses); println(""); println("using namespace std;\n"); - // Write enum if any... - //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); - //writeEnumCplus(enumDecl); - // Write struct if any... - //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); //writeStructCplus(structDecl); println("class " + intface); println("{"); println("public:"); @@ -2421,7 +2495,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodCplusStub() writes the method of the stub + * HELPER: writeMethodCplusStub() writes the methods of the stub */ private void writeMethodCplusStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { @@ -2429,6 +2503,9 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); + + //System.out.println("\n\nMethod return type: " + checkAndGetCplusType(intDecl.getMethodType(method)) + "\n\n"); + print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " + intDecl.getMethodId(method) + "("); boolean isCallbackMethod = false; @@ -2495,8 +2572,9 @@ public class IoTCompiler { println("int numParam = " + methParams.size() + ";"); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - String retTypeC = checkAndGetCplusType(retType); - println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";"); + //String retTypeC = checkAndGetCplusType(retType); + //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";"); + println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";"); // Generate array of parameter types print("string paramCls[] = { "); for (int i = 0; i < methParams.size(); i++) { @@ -2504,8 +2582,10 @@ public class IoTCompiler { if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object print("\"int\""); } else { // Generate normal classes if it's not a callback object - String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); + //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + //String prmType = getSimpleType(getEnumType(paramTypeC)); + String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + String prmType = getEnumType(paramTypeC); print("\"" + prmType + "\""); } if (i != methParams.size() - 1) // Check if this is the last element @@ -2602,54 +2682,286 @@ public class IoTCompiler { /** - * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class + * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup */ - private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method) { - - println("int numParam = " + methParams.size() + ";"); - println("int methodId = " + intDecl.getMethodNumId(method) + ";"); - String retType = intDecl.getMethodType(method); - String retTypeC = checkAndGetCplusType(retType); - println("string retType = \"" + checkAndGetCplusArrayType(getEnumType(retTypeC)) + "\";"); - // Generate array of parameter types - print("string paramCls[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - print("\"" + getEnumType(paramType) + "\""); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + private void checkAndWriteStructSetupCplusStub(List methParams, List methPrmTypes, + InterfaceDecl intDecl, String method) { + + // Iterate and find struct declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + // Check if this is enum type + println("int numParam" + i + " = 1;"); + int methodNumId = intDecl.getMethodNumId(method); + String helperMethod = methodNumId + "struct" + i; + println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";"); + println("string retTypeStruct" + i + " = \"void\";"); + println("string paramClsStruct" + i + "[] = { \"int\" };"); + print("int structLen" + i + " = "); + if (isArrayOrList(param, paramType)) { // An array + println(getSimpleArrayType(param) + ".size();"); + } else { // Just one element + println("1;"); + } + println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };"); + println("void* retStructLen" + i + " = NULL;"); + println("rmiCall->remoteCall(objectId, methodIdStruct" + i + + ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i + + ", numParam" + i + ", retStructLen" + i + ");\n"); } } - println(" };"); - checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); - // Generate array of parameter objects - print("void* paramObj[] = { "); + } + + + /** + * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params + */ + private void writeLengthStructParamClassCplusStub(List methParams, List methPrmTypes) { + + // Iterate and find struct declarations - count number of params for (int i = 0; i < methParams.size(); i++) { - print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); - // Check if this is the last element (don't print a comma) + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + int members = getNumOfMembers(simpleType); + if (isArrayOrList(param, paramType)) { // An array + String structLen = param + ".size()"; + print(members + "*" + structLen); + } else + print(Integer.toString(members)); + } else + print("1"); if (i != methParams.size() - 1) { - print(", "); + print("+"); } } - println(" };"); + } + + + /** + * HELPER: writeStructMembersCplusStub() writes member parameters of struct + */ + private void writeStructMembersCplusStub(String simpleType, String paramType, String param) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + param + ".size(); i++) {"); + } + if (isArrayOrList(param, paramType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &" + param + "[i]."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &" + param + "."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + } + } + + + /** + * HELPER: writeStructParamClassCplusStub() writes member parameters of struct + */ + private void writeStructParamClassCplusStub(List methParams, List methPrmTypes) { + + print("int numParam = "); + writeLengthStructParamClassCplusStub(methParams, methPrmTypes); + println(";"); + println("void* paramObj[numParam];"); + println("string paramCls[numParam];"); + println("int pos = 0;"); + // Iterate again over the parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + writeStructMembersCplusStub(simpleType, paramType, param); + } else { + String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &"); + print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement + */ + private void writeStructRetMembersCplusStub(String simpleType, String retType) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + } + if (isArrayOrList(retType, retType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + print("structRet[i]." + getSimpleIdentifier(members.get(i))); + println(" = retParam" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + print("structRet." + getSimpleIdentifier(members.get(i))); + println(" = retParam" + i + ";"); + } + } + println("return structRet;"); + } + + + /** + * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement + */ + private void writeStructReturnCplusStub(String simpleType, String retType) { + + // Minimum retLen is 1 if this is a single struct object + println("int retLen = 0;"); + println("void* retLenObj = { &retLen };"); + // Handle the returned struct!!! + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);"); + int numMem = getNumOfMembers(simpleType); + println("int numRet = " + numMem + "*retLen;"); + println("string retCls[numRet];"); + println("void* retObj[numRet];"); + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + // Set up variables + if (isArrayOrList(retType, retType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];"); + } + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";"); + } + } + println("int retPos = 0;"); + // Get the struct declaration for this struct and generate initialization code + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("retObj[retPos++] = &retParam" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("retObj[retPos++] = &retParam" + i + ";"); + } + } + println("rmiCall->getStructObjects(retCls, numRet, retObj);"); + if (isArrayOrList(retType, retType)) { // An array or list + println("vector<" + simpleType + "> structRet(retLen);"); + } else + println(simpleType + " structRet;"); + writeStructRetMembersCplusStub(simpleType, retType); + } + + + /** + * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class + */ + private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method) { + + checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method); + println("int methodId = " + intDecl.getMethodNumId(method) + ";"); + String retType = intDecl.getMethodType(method); + //String retTypeC = checkAndGetCplusType(retType); + //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";"); + println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";"); + // Generate array of parameter types + if (isStructPresent(methParams, methPrmTypes)) { + writeStructParamClassCplusStub(methParams, methPrmTypes); + } else { + println("int numParam = " + methParams.size() + ";"); + print("string paramCls[] = { "); + for (int i = 0; i < methParams.size(); i++) { + //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + //String prmType = getSimpleType(getEnumType(paramTypeC)); + String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + String prmType = getEnumType(paramTypeC); + print("\"" + prmType + "\""); + // Check if this is the last element (don't print a comma) + if (i != methParams.size() - 1) { + print(", "); + } + } + println(" };"); + checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); + // 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)); + // 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("void* retObj = NULL;"); println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); } else { // We do have a return value - if (getParamCategory(retType) == ParamCategory.ENUM) { - checkAndWriteEnumRetTypeCplusStub(retType); + // Generate array of parameter types + if (isStructClass(getGenericType(getSimpleArrayType(retType)))) { + writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType); } else { - if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - println(checkAndGetCplusType(retType) + " retVal;"); - else - println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); - println("void* retObj = &retVal;"); - println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); - println("return retVal;"); + // Check if the return value NONPRIMITIVES + if (getParamCategory(retType) == ParamCategory.ENUM) { + checkAndWriteEnumRetTypeCplusStub(retType); + } else { + //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + if (isArrayOrList(retType,retType)) + println(checkAndGetCplusType(retType) + " retVal;"); + else { + println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); + } + println("void* retObj = &retVal;"); + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); + println("return retVal;"); + } } } } @@ -2663,8 +2975,8 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); - println("const static int object" + newObjectId + "Id = " + newObjectId + ";"); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface); println("const static set set" + newObjectId + "Allowed;"); } } @@ -2709,7 +3021,6 @@ public class IoTCompiler { println("ports = _ports;"); println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);"); if (callbackExist) { - println("objIdCnt = 0;"); Iterator it = callbackClasses.iterator(); String callbackType = (String) it.next(); println("thread th1 (&" + newStubClass + "::___initCallBack, this);"); @@ -2758,7 +3069,7 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {"); println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;"); println("exit(-1);"); @@ -2783,7 +3094,8 @@ public class IoTCompiler { println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface + "_CallbackSkeleton*> (vecCallbackObj.at(objId));"); println("skel->invokeMethod(rmiObj);"); - println("} else {"); + print("}"); + println(" else {"); println("cerr << \"Illegal object Id: \" << to_string(objId);"); // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding) println("exit(-1);"); @@ -2794,7 +3106,7 @@ public class IoTCompiler { /** - * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization of callback + * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback */ private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) { @@ -2856,6 +3168,7 @@ public class IoTCompiler { print("}"); println(";"); if (callbackExist) writePermissionInitializationCplus(intface, newStubClass, intDecl); + writeObjectIdCountInitializationCplus(newStubClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp..."); @@ -2871,7 +3184,7 @@ public class IoTCompiler { println("IoTRMICall *rmiCall;"); // Get the object Id - println("static int objectId;"); + println("int objectId;"); if (callbackExist) { // We assume that each class only has one callback interface for now Iterator it = callbackClasses.iterator(); @@ -2951,6 +3264,7 @@ public class IoTCompiler { println("};"); if (callbackExist) writePermissionInitializationCplus(intface, newStubClass, intDecl); + writeObjectIdCountInitializationCplus(newStubClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp..."); @@ -2982,6 +3296,16 @@ public class IoTCompiler { } + /** + * HELPER: writeObjectIdCountInitializationCplus() writes the initialization of objIdCnt variable + */ + private void writeObjectIdCountInitializationCplus(String newSkelClass, boolean callbackExist) { + + if (callbackExist) + println("int " + newSkelClass + "::objIdCnt = 0;"); + } + + /** * HELPER: writePermissionInitializationCplus() writes the initialization of permission set */ @@ -2991,7 +3315,7 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); print("const set " + newSkelClass + "::set" + newObjectId + "Allowed {"); Set methodIds = intMeth.getValue(); int i = 0; @@ -3018,11 +3342,6 @@ public class IoTCompiler { println("bool _bResult = false;"); println("mainObj = _mainObj;"); println("rmiObj = new IoTRMIObject(_port, &_bResult);"); - // Callback - if (callbackExist) { - println("objIdCnt = 0;"); - } - //println("set0Allowed = Arrays.asList(object0Permission);"); println("___waitRequestInvokeMethod();"); println("}\n"); } @@ -3092,7 +3411,9 @@ public class IoTCompiler { println("int param1 = 0;"); println("string param2 = \"\";"); println("int param3 = 0;"); + println("string paramCls[] = { \"int\", \"string\", \"int\" };"); println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };"); + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); println("bool bResult = false;"); println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);"); println("}\n"); @@ -3243,137 +3564,449 @@ public class IoTCompiler { /** - * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class + * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton + */ + private void writeMethodInputParameters(List methParams, List methPrmTypes, + Set callbackClasses, String methodId) { + + print(methodId + "("); + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) + print("stub" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("paramEnum" + i); + else if (isStructClass(getSimpleType(paramType))) // Struct type + print("paramStruct" + i); + else + print(getSimpleIdentifier(methParams.get(i))); + if (i != methParams.size() - 1) { + print(", "); + } + } + println(");"); + } + + + /** + * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton + */ + private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, boolean isCallbackMethod, String callbackType, + String methodId, Set callbackClasses) { + + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + if (isCallbackMethod) + writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType); + checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes); + writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + // Check if this is "void" + if (retType.equals("void")) { + writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId); + } else { // We do have a return value + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + print(checkAndGetCplusType(retType) + " retEnum = "); + else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + print(checkAndGetCplusType(retType) + " retStruct = "); + else + print(checkAndGetCplusType(retType) + " retVal = "); + writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId); + checkAndWriteEnumRetTypeCplusSkeleton(retType); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + println("void* retObj = &retEnumInt;"); + else + if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("void* retObj = &retVal;"); + String retTypeC = checkAndGetCplusType(retType); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);"); + else + println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");"); + } + } + + + /** + * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class + */ + private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, String methodId, Set callbackClasses) { + + // Generate array of parameter types + boolean isCallbackMethod = false; + String callbackType = null; + print("string paramCls[] = { "); + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) { + isCallbackMethod = true; + callbackType = paramType; + print("\"int\""); + } else { // Generate normal classes if it's not a callback object + //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + //String prmType = getSimpleType(getEnumType(paramTypeC)); + String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + String prmType = getEnumType(paramTypeC); + print("\"" + prmType + "\""); + } + if (i != methParams.size() - 1) { + print(", "); + } + } + println(" };"); + println("int numParam = " + methParams.size() + ";"); + if (isCallbackMethod) + writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType); + // Generate parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (!callbackClasses.contains(paramType)) { + String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); + if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i)); + println(methParamComplete + ";"); + } + } + } + // Generate array of parameter objects + print("void* paramObj[] = { "); + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) + print("&numStubs" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("¶mEnumInt" + i); + else + print("&" + getSimpleIdentifier(methParams.get(i))); + if (i != methParams.size() - 1) { + print(", "); + } + } + println(" };"); + // Write the return value part + writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, + callbackType, methodId, callbackClasses); + } + + + /** + * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct + */ + private void writeStructMembersCplusSkeleton(String simpleType, String paramType, + String param, String method, InterfaceDecl intDecl, int iVar) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + int methodNumId = intDecl.getMethodNumId(method); + String counter = "struct" + methodNumId + "Size" + iVar; + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + counter + "; i++) {"); + } + // Set up variables + if (isArrayOrList(param, paramType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " param" + i + "[" + counter + "];"); + } + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " param" + i + ";"); + } + } + println("int pos = 0;"); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("paramObj[pos++] = ¶m" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("paramObj[pos++] = ¶m" + i + ";"); + } + } + } + + + /** + * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct + */ + private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method) { + + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + String counter = "struct" + methodNumId + "Size" + i; + // Declaration + if (isArrayOrList(param, paramType)) { // An array or list + println("vector<" + simpleType + "> paramStruct" + i + ";"); + } else + println(simpleType + " paramStruct" + i + ";"); + // Initialize members + StructDecl structDecl = getStructDecl(simpleType); + List members = structDecl.getMembers(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + counter + "; i++) {"); + for (int j = 0; j < members.size(); j++) { + print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j))); + println(" = param" + j + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int j = 0; j < members.size(); j++) { + print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j))); + println(" = param" + j + ";"); + } + } + } + } + } + + + /** + * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement + */ + private void writeStructReturnCplusSkeleton(String simpleType, String retType) { + + // Minimum retLen is 1 if this is a single struct object + if (isArrayOrList(retType, retType)) + println("int retLen = retStruct.size();"); + else // Just single struct object + println("int retLen = 1;"); + println("void* retLenObj = &retLen;"); + println("rmiObj->sendReturnObj(retLenObj, \"int\");"); + int numMem = getNumOfMembers(simpleType); + println("int numRetObj = " + numMem + "*retLen;"); + println("string retCls[numRetObj];"); + println("void* retObj[numRetObj];"); + println("int retPos = 0;"); + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String paramTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("retObj[retPos++] = &retStruct[i]."); + print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i)); + println(";"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String paramTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("retObj[retPos++] = &retStruct."); + print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton + */ + private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, String methodId, Set callbackClasses) { + + // Generate array of parameter objects + boolean isCallbackMethod = false; + String callbackType = null; + print("int numParam = "); + writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl); + println(";"); + println("string paramCls[numParam];"); + println("void* paramObj[numParam];"); + // Iterate again over the parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i); + } else { + String prmType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(prmType)) { + isCallbackMethod = true; + callbackType = paramType; + writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType); + println("paramCls[pos] = \"int\";"); + println("paramObj[pos++] = &numStubs" + i + ";"); + } else { // Generate normal classes if it's not a callback object + String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); + String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); + if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i)); + println(methParamComplete + ";"); + } + println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";"); + if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + println("paramObj[pos++] = ¶mEnumInt" + i); + else + println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";"); + } + } + } + // Write the return value part + writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, + callbackType, methodId, callbackClasses); + } + + + /** + * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class + */ + private void writeMethodHelperCplusSkeleton(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { + + // Use this set to handle two same methodIds + Set uniqueMethodIds = new HashSet(); + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + String retType = intDecl.getMethodType(method); + print(helperMethod + "("); + boolean begin = true; + for (int i = 0; i < methParams.size(); i++) { // Print size variables + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + if (!begin) { // Generate comma for not the beginning variable + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("int struct" + methodNumId + "Size" + i); + } + } + println(") {"); + writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } else { + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + println(helperMethod + "() {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } + } + // Write method helper for structs + writeMethodHelperStructSetupCplusSkeleton(methods, intDecl); + } + + + /** + * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class */ - private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method, String methodId, Set callbackClasses) { + private void writeMethodHelperStructSetupCplusSkeleton(Collection methods, + InterfaceDecl intDecl) { - // Generate array of parameter types - boolean isCallbackMethod = false; - String callbackType = null; - print("string paramCls[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) { - isCallbackMethod = true; - callbackType = paramType; - print("\"int\""); - } else { // Generate normal classes if it's not a callback object - String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - print("\"" + getEnumType(prmType) + "\""); - } - if (i != methParams.size() - 1) { - print(", "); - } - } - println(" };"); - println("int numParam = " + methParams.size() + ";"); - if (isCallbackMethod) - writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType); - // Generate parameters - for (int i = 0; i < methParams.size(); i++) { - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (!callbackClasses.contains(paramType)) { - String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); - if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type - println("vector paramEnumInt" + i + ";"); - } else { - String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i)); - println(methParamComplete + ";"); - } - } - } - // Generate array of parameter objects - print("void* paramObj[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) - print("&numStubs" + i); - else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type - print("¶mEnumInt" + i); - else - print("&" + getSimpleIdentifier(methParams.get(i))); - if (i != methParams.size() - 1) { - print(", "); - } - } - println(" };"); - println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); - if (isCallbackMethod) - writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType); - checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes); - String retType = intDecl.getMethodType(method); - // Check if this is "void" - if (retType.equals("void")) { - print(methodId + "("); - for (int i = 0; i < methParams.size(); i++) { - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) - print("stub" + i); - else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type - print("paramEnum" + i); - else - print(getSimpleIdentifier(methParams.get(i))); - if (i != methParams.size() - 1) { - print(", "); - } - } - println(");"); - } else { // We do have a return value - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type - print(checkAndGetCplusType(retType) + " retEnum = "); - else - print(checkAndGetCplusType(retType) + " retVal = "); - print(methodId + "("); + // Use this set to handle two same methodIds + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + // Check for params with structs for (int i = 0; i < methParams.size(); i++) { - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) - print("stub" + i); - else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type - print("paramEnum" + i); - else - print(getSimpleIdentifier(methParams.get(i))); - if (i != methParams.size() - 1) { - print(", "); + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("int ___"); + String helperMethod = methodNumId + "struct" + i; + println(helperMethod + "() {"); + // Now, write the helper body of skeleton! + println("string paramCls[] = { \"int\" };"); + println("int numParam = 1;"); + println("int param0 = 0;"); + println("void* paramObj[] = { ¶m0 };"); + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + println("return param0;"); + println("}\n"); } } - println(");"); - checkAndWriteEnumRetTypeCplusSkeleton(retType); - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type - println("void* retObj = &retEnumInt;"); - else - println("void* retObj = &retVal;"); - String retTypeC = checkAndGetCplusType(retType); - println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");"); } } /** - * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class + * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class */ - private void writeMethodHelperCplusSkeleton(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { + private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection methods, + InterfaceDecl intDecl) { // Use this set to handle two same methodIds - Set uniqueMethodIds = new HashSet(); for (String method : methods) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - String methodId = intDecl.getMethodId(method); - print("void ___"); - String helperMethod = methodId; - if (uniqueMethodIds.contains(methodId)) - helperMethod = helperMethod + intDecl.getMethodNumId(method); - else - uniqueMethodIds.add(methodId); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - println(helperMethod + "() {"); - // Now, write the helper body of skeleton! - writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); - println("}\n"); + // Check for params with structs + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("int ___"); + String helperMethod = methodNumId + "struct" + i; + println(helperMethod + "(IoTRMIObject* rmiObj) {"); + // Now, write the helper body of skeleton! + println("string paramCls[] = { \"int\" };"); + println("int numParam = 1;"); + println("int param0 = 0;"); + println("void* paramObj[] = { ¶m0 };"); + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + println("return param0;"); + println("}\n"); + } + } } } @@ -3387,17 +4020,17 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); + int newObjectId = getNewIntfaceObjectId(newIntface); println("if (_objectId == object" + newObjectId + "Id) {"); println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {"); println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;"); println("exit(-1);"); println("}"); + println("}"); println("else {"); println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;"); println("exit(-1);"); println("}"); - println("}"); } } @@ -3411,6 +4044,7 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("void ___waitRequestInvokeMethod() {"); // Write variables here if we have callbacks or enums or structs + writeCountVarStructSkeleton(methods, intDecl); println("while (true) {"); println("rmiObj->getMethodBytes();"); println("int _objectId = rmiObj->getObjectId();"); @@ -3428,7 +4062,9 @@ public class IoTCompiler { helperMethod = helperMethod + methodNumId; else uniqueMethodIds.add(methodId); - println(helperMethod + "(); break;"); + print(helperMethod + "("); + writeInputCountVarStructSkeleton(method, intDecl); + println("); break;"); } String method = "___initCallBack()"; // Print case -9999 (callback handler) if callback exists @@ -3436,6 +4072,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(); break;"); } + writeMethodCallStructSkeleton(methods, intDecl); println("default: "); println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;"); println("throw exception();"); @@ -3492,6 +4129,7 @@ public class IoTCompiler { writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface); println("};"); writePermissionInitializationCplus(intface, newSkelClass, intDecl); + writeObjectIdCountInitializationCplus(newSkelClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp..."); @@ -3506,7 +4144,7 @@ public class IoTCompiler { println(intface + " *mainObj;"); // Keep track of object Ids of all stubs registered to this interface - println("static int objectId;"); + println("int objectId;"); // Callback if (callbackExist) { Iterator it = callbackClasses.iterator(); @@ -3529,10 +4167,6 @@ public class IoTCompiler { println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {"); println("mainObj = _mainObj;"); println("objectId = _objectId;"); - // Callback - if (callbackExist) { - println("objIdCnt = 0;"); - } println("}\n"); } @@ -3564,7 +4198,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of the callback skeleton class + * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of callback skeleton class */ private void writeMethodHelperCplusCallbackSkeleton(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { @@ -3575,25 +4209,55 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - String methodId = intDecl.getMethodId(method); - print("void ___"); - String helperMethod = methodId; - if (uniqueMethodIds.contains(methodId)) - helperMethod = helperMethod + intDecl.getMethodNumId(method); - else - uniqueMethodIds.add(methodId); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - println(helperMethod + "(IoTRMIObject* rmiObj) {"); - // Now, write the helper body of skeleton! - writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); - println("}\n"); + if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + String retType = intDecl.getMethodType(method); + print(helperMethod + "("); + boolean begin = true; + for (int i = 0; i < methParams.size(); i++) { // Print size variables + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + if (!begin) { // Generate comma for not the beginning variable + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("int struct" + methodNumId + "Size" + i); + } + } + println(", IoTRMIObject* rmiObj) {"); + writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } else { + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + println(helperMethod + "(IoTRMIObject* rmiObj) {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } } + // Write method helper for structs + writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl); } /** - * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the main loop of the skeleton class + * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the request invoke method of the skeleton callback class */ private void writeCplusCallbackWaitRequestInvokeMethod(Collection methods, InterfaceDecl intDecl, boolean callbackExist) { @@ -3602,6 +4266,8 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("void invokeMethod(IoTRMIObject* rmiObj) {"); // Write variables here if we have callbacks or enums or structs + writeCountVarStructSkeleton(methods, intDecl); + // Write variables here if we have callbacks or enums or structs println("int methodId = rmiObj->getMethodId();"); // TODO: code the permission check here! println("switch (methodId) {"); @@ -3615,7 +4281,11 @@ public class IoTCompiler { helperMethod = helperMethod + methodNumId; else uniqueMethodIds.add(methodId); - println(helperMethod + "(rmiObj); break;"); + print(helperMethod + "("); + if (writeInputCountVarStructSkeleton(method, intDecl)) + println(", rmiObj); break;"); + else + println("rmiObj); break;"); } String method = "___initCallBack()"; // Print case -9999 (callback handler) if callback exists @@ -3623,6 +4293,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(rmiObj); break;"); } + writeMethodCallStructCallbackSkeleton(methods, intDecl); println("default: "); println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;"); println("throw exception();"); @@ -3631,7 +4302,6 @@ public class IoTCompiler { } - /** * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++ */ @@ -3678,6 +4348,7 @@ public class IoTCompiler { // Write waitRequestInvokeMethod() - main loop writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist); println("};"); + writeObjectIdCountInitializationCplus(newSkelClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp..."); @@ -3715,35 +4386,6 @@ public class IoTCompiler { } - /** - * generateReturnStmt() generate return statement based on methType - */ - public String generateReturnStmt(String methType) { - - // Generate dummy returns for now - if (methType.equals("short")|| - methType.equals("int") || - methType.equals("long") || - methType.equals("float")|| - methType.equals("double")) { - - return "1"; - } else if ( methType.equals("String")) { - - return "\"a\""; - } else if ( methType.equals("char") || - methType.equals("byte")) { - - return "\'a\'"; - } else if ( methType.equals("boolean")) { - - return "true"; - } else { - return "null"; - } - } - - /** * setDirectory() sets a new directory for stub files */ @@ -3789,7 +4431,7 @@ public class IoTCompiler { pn = (ParseNode) parse.parse().value; } catch (Exception e) { e.printStackTrace(); - throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file); + throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file + "\n"); } return pn; @@ -3797,7 +4439,7 @@ public class IoTCompiler { /**================ - * Helper functions + * Basic helper functions **================ */ boolean newline=true; @@ -3826,6 +4468,9 @@ public class IoTCompiler { } + /** + * A collection of methods with print-to-file functionality + */ private void println(String str) { if (newline) { int tab = tablevel; @@ -3896,7 +4541,22 @@ public class IoTCompiler { } - // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, or USERDEFINED + // Check and find object Id for new interface in mapNewIntfaceObjId (callbacks) + // Throw an error if the new interface is not found! + // Basically the compiler needs to parse the policy (and requires) files for callback class first + private int getNewIntfaceObjectId(String newIntface) { + + if (!mapNewIntfaceObjId.containsKey(newIntface)) { + throw new Error("IoTCompiler: Need to parse policy and requires files for callback class first! " + + "Please place the two files for callback class in front...\n"); + } else { + int retObjId = mapNewIntfaceObjId.get(newIntface); + return retObjId; + } + } + + + // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT private ParamCategory getParamCategory(String paramType) { if (mapPrimitives.containsKey(paramType)) { @@ -3914,7 +4574,7 @@ public class IoTCompiler { // Return full class name for non-primitives to generate Java import statements - // e.g. java.util.Set for Set, java.util.Map for Map + // e.g. java.util.Set for Set private String getNonPrimitiveJavaClass(String paramNonPrimitives) { return mapNonPrimitivesJava.get(paramNonPrimitives); @@ -3922,7 +4582,7 @@ public class IoTCompiler { // Return full class name for non-primitives to generate Cplus include statements - // e.g. #include for Set, #include for Map + // e.g. #include for Set private String getNonPrimitiveCplusClass(String paramNonPrimitives) { return mapNonPrimitivesCplus.get(paramNonPrimitives); @@ -3942,6 +4602,18 @@ public class IoTCompiler { } + // Generate a set of standard classes for import statements + private List getStandardJavaIntfaceImportClasses() { + + List importClasses = new ArrayList(); + // Add the standard list first + importClasses.add("java.util.List"); + importClasses.add("java.util.ArrayList"); + + return importClasses; + } + + // Generate a set of standard classes for import statements private List getStandardJavaImportClasses() { @@ -3972,7 +4644,7 @@ public class IoTCompiler { } - // Generate a set of standard classes for import statements + // Combine all classes for import statements private List getAllLibClasses(Collection stdLibClasses, Collection libClasses) { List allLibClasses = new ArrayList(stdLibClasses); @@ -3982,7 +4654,6 @@ public class IoTCompiler { allLibClasses.add(str); } } - return allLibClasses; } @@ -4156,6 +4827,8 @@ public class IoTCompiler { } } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) { includeClasses.add("\"" + simpleType + ".hpp\""); + } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) { + includeClasses.add("\"" + simpleType + ".hpp\""); } else if (param.contains("[]")) { // Check if this is array for C++; translate into vector includeClasses.add(""); @@ -4192,6 +4865,7 @@ public class IoTCompiler { } + // Print import statements into file private void printImportStatements(Collection importClasses) { for(String cls : importClasses) { @@ -4200,6 +4874,7 @@ public class IoTCompiler { } + // Print include statements into file private void printIncludeStatements(Collection includeClasses) { for(String cls : includeClasses) { @@ -4255,6 +4930,7 @@ public class IoTCompiler { } + // Checks and gets type in C++ private String checkAndGetCplusType(String paramType) { if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) { @@ -4277,7 +4953,7 @@ public class IoTCompiler { } else return getNonPrimitiveCplusClass(paramType); } else if(paramType.contains("[]")) { // Array type (used for return type only) - String cArray = "vector<" + getSimpleArrayType(paramType) + ">"; + String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">"; return cArray; } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { return paramType + "*"; @@ -4345,6 +5021,47 @@ public class IoTCompiler { } + // Return the class type for class resolution (for return value) + // - Check and return C++ array class, e.g. int A[] into int* + // - Check and return C++ vector class, e.g. List A into vector + private String checkAndGetCplusRetClsType(String paramType) { + + String paramTypeRet = null; + // Check for array declaration + if (paramType.contains("[]")) { + String type = paramType.split("\\[\\]")[0]; + paramTypeRet = getSimpleArrayType(type) + "*"; + } else if (paramType.contains("<") && paramType.contains(">")) { + // Just return it as is if it's not an array + String type = paramType.split("<")[1].split(">")[0]; + paramTypeRet = "vector<" + getGenericType(type) + ">"; + } else + paramTypeRet = paramType; + + return paramTypeRet; + } + + + // Return the class type for class resolution (for method arguments) + // - Check and return C++ array class, e.g. int A[] into int* + // - Check and return C++ vector class, e.g. List A into vector + private String checkAndGetCplusArgClsType(String paramType, String param) { + + String paramTypeRet = null; + // Check for array declaration + if (param.contains("[]")) { + paramTypeRet = getSimpleArrayType(paramType) + "*"; + } else if (paramType.contains("<") && paramType.contains(">")) { + // Just return it as is if it's not an array + String type = paramType.split("<")[1].split(">")[0]; + paramTypeRet = "vector<" + getGenericType(type) + ">"; + } else + paramTypeRet = paramType; + + return paramTypeRet; + } + + // Detect array declaration, e.g. int A[], // then generate type "int[]" private String checkAndGetArray(String paramType, String param) { @@ -4374,7 +5091,8 @@ public class IoTCompiler { } - // Is array? For return type we put the return type as input parameter + // Is array? + // For return type we use retType as input parameter private boolean isArray(String param) { // Check for array declaration @@ -4425,7 +5143,7 @@ public class IoTCompiler { } else { throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() + ". Only one new interface can be declared if the object " + intface + - " needs to be passed in as an input parameter!"); + " needs to be passed in as an input parameter!\n"); } } else { // NULL value - this means policy files missing @@ -4434,7 +5152,7 @@ public class IoTCompiler { " If this is an array please type the brackets after the variable name," + " e.g. \"String str[]\", not \"String[] str\"." + " If this is a Collections (Java) / STL (C++) type, this compiler only" + - " supports List/ArrayList (Java) or list (C++)."); + " supports List/ArrayList (Java) or list (C++).\n"); } } @@ -4493,12 +5211,12 @@ public class IoTCompiler { // Error checking if (!args[i].equals("-java") && !args[i].equals("-cplus")) { - throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]); + throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i] + "\n"); } else { if (i + 1 < args.length) { comp.setDirectory(args[i+1]); } else - throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i]); + throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i] + "\n"); if (args[i].equals("-java")) { comp.generateEnumJava(); @@ -4526,11 +5244,9 @@ public class IoTCompiler { } else { // Need to at least have exactly 2 parameters, i.e. main policy file and requires file IoTCompiler.printUsage(); - throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!"); + throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!\n"); } } } - -