X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=iotjava%2Fiotpolicy%2FIoTCompiler.java;h=6555f9d9e934034586a93f608d24baf9fc28d745;hb=43511149805bfc92d9332532445d5e0040d613bd;hp=8c84a4cbbf0ec8f39fa3302690749443ca721e14;hpb=109357614cd72cfa5b9b1280bfbe31c18bba1092;p=iot2.git diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index 8c84a4c..6555f9d 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 */ @@ -68,9 +69,12 @@ public class IoTCompiler { PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc. NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc. - USERDEFINED // Non-supported type by default; assumed as driver classes + ENUM, // Enum type + STRUCT, // Struct type + USERDEFINED // Assumed as driver classes } + /** * Class constructors */ @@ -102,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) { @@ -181,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) { @@ -233,50 +236,72 @@ public class IoTCompiler { /** - * HELPER: writeEnumJava() writes the enumeration declaration + * HELPER: generateEnumJava() writes the enumeration declaration */ - private void writeEnumJava(EnumDecl enumDecl) { - - Set enumTypes = enumDecl.getEnumDeclarations(); - // Iterate over enum declarations - for (String enType : enumTypes) { - - println("public enum " + enType + " {"); - List enumMembers = enumDecl.getMembers(enType); - for (int i = 0; i < enumMembers.size(); i++) { + private void generateEnumJava() throws IOException { - String member = enumMembers.get(i); - print(member); - // Check if this is the last element (don't print a comma) - if (i != enumMembers.size() - 1) - println(","); - else - println(""); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right EnumDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set enumTypes = enumDecl.getEnumDeclarations(); + // Iterate over enum declarations + for (String enType : enumTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + enType + ".java"); + pw = new PrintWriter(new BufferedWriter(fw)); + println("public enum " + enType + " {"); + List enumMembers = enumDecl.getMembers(enType); + for (int i = 0; i < enumMembers.size(); i++) { + + String member = enumMembers.get(i); + print(member); + // Check if this is the last element (don't print a comma) + if (i != enumMembers.size() - 1) + println(","); + else + println(""); + } + println("}\n"); + pw.close(); + System.out.println("IoTCompiler: Generated enum class " + enType + ".java..."); } - println("}\n"); } } /** - * HELPER: writeStructJava() writes the struct declaration + * HELPER: generateStructJava() writes the struct declaration */ - private void writeStructJava(StructDecl structDecl) { + private void generateStructJava() throws IOException { - List structTypes = structDecl.getStructTypes(); - // Iterate over enum declarations - for (String stType : structTypes) { - - println("public class " + stType + " {"); - List structMemberTypes = structDecl.getMemberTypes(stType); - List structMembers = structDecl.getMembers(stType); - for (int i = 0; i < structMembers.size(); i++) { - - String memberType = structMemberTypes.get(i); - String member = structMembers.get(i); - println("public static " + memberType + " " + member + ";"); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List structTypes = structDecl.getStructTypes(); + // Iterate over enum declarations + for (String stType : structTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + stType + ".java"); + pw = new PrintWriter(new BufferedWriter(fw)); + println("public class " + stType + " {"); + List structMemberTypes = structDecl.getMemberTypes(stType); + List structMembers = structDecl.getMembers(stType); + for (int i = 0; i < structMembers.size(); i++) { + + String memberType = structMemberTypes.get(i); + String member = structMembers.get(i); + println("public static " + memberType + " " + member + ";"); + } + println("}\n"); + pw.close(); + System.out.println("IoTCompiler: Generated struct class " + stType + ".java..."); } - println("}\n"); } } @@ -302,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("}"); @@ -340,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..."); @@ -363,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(); @@ -379,7 +403,7 @@ public class IoTCompiler { i++; } println(" };"); - println("private List set" + newObjectId + "Allowed;"); + println("private static List set" + newObjectId + "Allowed;"); } } @@ -422,8 +446,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("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);"); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("set" + newObjectId + "Allowed = new ArrayList(Arrays.asList(object" + newObjectId +"Permission));"); } } @@ -458,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("}"); @@ -467,7 +491,25 @@ public class IoTCompiler { /** - * HELPER: writeConstructorJavaStub() writes the constructor of the stub class + * HELPER: writeJavaInitCallbackPermission() writes the permission for callback + */ + private void writeJavaInitCallbackPermission(String intface, InterfaceDecl intDecl, boolean callbackExist) { + + if (callbackExist) { + String method = "___initCallBack()"; + int methodNumId = intDecl.getHelperMethodNumId(method); + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + String newIntface = intMeth.getKey(); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("set" + newObjectId + "Allowed.add(" + methodNumId + ");"); + } + } + } + + + /** + * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub */ private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) { @@ -484,11 +526,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("}"); @@ -497,7 +541,8 @@ public class IoTCompiler { println("thread.start();\n"); // Generate info sending part String method = "___initCallBack()"; - println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";"); + int methodNumId = intDecl.getHelperMethodNumId(method); + println("int methodId = " + methodNumId + ";"); println("Class retType = void.class;"); println("Class[] paramCls = new Class[] { int.class, String.class, int.class };"); println("Object[] paramObj = new Object[] { ports[0], address, 0 };"); @@ -506,49 +551,362 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeJavaStub(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + if (isArray(param)) { // An array + println("int len" + i + " = " + getSimpleIdentifier(param) + ".length;"); + println("int paramEnum" + i + "[] = new int[len" + i + "];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + "[i].ordinal();"); + println("}"); + } else if (isList(paramType)) { // A list + println("int len" + i + " = " + getSimpleIdentifier(param) + ".size();"); + println("int paramEnum" + i + "[] = new int[len" + i + "];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + ".get(i).ordinal();"); + println("}"); + } else { // Just one element + println("int paramEnum" + i + "[] = new int[1];"); + println("paramEnum" + i + "[0] = " + param + ".ordinal();"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeJavaStub(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getGenericType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(retType); + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + println("int[] retEnum = (int[]) retObj;"); + println(pureType + "[] enumVals = " + pureType + ".values();"); + if (isArray(retType)) { // An array + println("int retLen = retEnum.length;"); + println(pureType + "[] enumRetVal = new " + pureType + "[retLen];"); + println("for (int i = 0; i < retLen; i++) {"); + println("enumRetVal[i] = enumVals[retEnum[i]];"); + println("}"); + } else if (isList(retType)) { // A list + println("int retLen = retEnum.length;"); + println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();"); + println("for (int i = 0; i < retLen; i++) {"); + println("enumRetVal.add(enumVals[retEnum[i]]);"); + println("}"); + } else { // Just one element + println(pureType + " enumRetVal = enumVals[retEnum[0]];"); + } + println("return enumRetVal;"); + } + } + + + /** + * HELPER: checkAndWriteStructSetupJavaStub() writes the struct type setup + */ + private void checkAndWriteStructSetupJavaStub(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 + int methodNumId = intDecl.getMethodNumId(method); + String helperMethod = methodNumId + "struct" + i; + println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";"); + println("Class retTypeStruct" + i + " = void.class;"); + println("Class[] paramClsStruct" + i + " = new Class[] { int.class };"); + if (isArray(param)) { // An array + println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };"); + } else if (isList(paramType)) { // A list + println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".size() };"); + } else { // Just one element + println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };"); + } + println("rmiCall.remoteCall(objectId, methodIdStruct" + i + + ", retTypeStruct" + i + ", null, paramClsStruct" + i + + ", paramObjStruct" + i + ");\n"); + } + } + } + + + /** + * HELPER: isStructPresent() checks presence of struct + */ + private boolean isStructPresent(List methParams, List methPrmTypes) { + + // Iterate and find enum 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)) + return true; + } + return false; + } + + + /** + * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters + */ + private void writeLengthStructParamClassJavaStub(List methParams, List methPrmTypes) { + + // Iterate and find struct declarations - count number of params + 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 members = getNumOfMembers(simpleType); + if (isArray(param)) { // An array + String structLen = param + ".length"; + print(members + "*" + structLen); + } else if (isList(paramType)) { // A list + String structLen = param + ".size()"; + print(members + "*" + structLen); + } else + print(Integer.toString(members)); + } else + print("1"); + if (i != methParams.size() - 1) { + print("+"); + } + } + } + + + /** + * HELPER: writeStructMembersJavaStub() writes parameters of struct + */ + private void writeStructMembersJavaStub(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 (isArray(param)) { // An array + println("for(int i = 0; i < " + param + ".length; i++) {"); + } else if (isList(paramType)) { // A 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + print("paramObj[pos++] = " + param + "."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + } + } + + + /** + * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present + */ + private void writeStructParamClassJavaStub(List methParams, List methPrmTypes) { + + print("int paramLen = "); + writeLengthStructParamClassJavaStub(methParams, methPrmTypes); + println(";"); + println("Object[] paramObj = new Object[paramLen];"); + println("Class[] paramCls = new Class[paramLen];"); + 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)) { + writeStructMembersJavaStub(simpleType, paramType, param); + } else { + String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + print("paramObj[pos++] = "); + print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement + */ + private void writeStructRetMembersJavaStub(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 (isArray(retType)) { // An array + 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(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];"); + } + println("}"); + } else if (isList(retType)) { // A list + println(simpleType + " structRetMem = new " + simpleType + "();"); + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + print("structRetMem." + getSimpleIdentifier(members.get(i))); + println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];"); + } + println("structRet.add(structRetMem);"); + 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(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];"); + } + } + println("return structRet;"); + } + + + /** + * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement + */ + private void writeStructReturnJavaStub(String simpleType, String retType) { + + // Handle the returned struct!!! + println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); + // Minimum retLen is 1 if this is a single struct object + println("int retLen = (int) retLenObj;"); + int numMem = getNumOfMembers(simpleType); + println("Class[] retCls = new Class[" + numMem + "*retLen];"); + println("Class[] retClsVal = new Class[" + numMem + "*retLen];"); + 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + println("retClsVal[retPos++] = null;"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + println("retClsVal[retPos++] = null;"); + } + } + println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);"); + if (isArray(retType)) { // An array + println(simpleType + "[] structRet = new " + simpleType + "[retLen];"); + println("for(int i = 0; i < retLen; i++) {"); + println("structRet[i] = new " + simpleType + "();"); + println("}"); + } else if (isList(retType)) { // A list + println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();"); + } else + println(simpleType + " structRet = new " + simpleType + "();"); + println("int retObjPos = 0;"); + writeStructRetMembersJavaStub(simpleType, retType); + } + + /** * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class */ private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List methParams, List methPrmTypes, String method) { + checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - println("Class retType = " + getSimpleType(retType) + ".class;"); + println("Class retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;"); + checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes); // Generate array of parameter types - print("Class[] paramCls = new Class[] { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print(getSimpleType(paramType) + ".class"); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + if (isStructPresent(methParams, methPrmTypes)) { + writeStructParamClassJavaStub(methParams, methPrmTypes); + } else { + print("Class[] paramCls = new Class[] { "); + for (int i = 0; i < methParams.size(); i++) { + 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++) { - print(getSimpleIdentifier(methParams.get(i))); - // 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++) { + 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(" };"); } - 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 - // Check if the return value NONPRIMITIVES - if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) { - String[] retGenValType = getTypeOfGeneric(retType); - println("Class retGenValType = " + retGenValType[0] + ".class;"); - println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);"); - println("return (" + retType + ")retObj;"); + // Generate array of parameter types + if (isStructClass(getGenericType(getSimpleArrayType(retType)))) { + writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType); } else { - println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); - println("return (" + retType + ")retObj;"); + // 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;"); + } } } } @@ -585,7 +943,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); @@ -600,13 +957,14 @@ 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"); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - println("Class retType = " + getSimpleType(retType) + ".class;"); + println("Class retType = " + getSimpleType(getEnumType(retType)) + ".class;"); // Generate array of parameter types print("Class[] paramCls = new Class[] { "); for (int i = 0; i < methParams.size(); i++) { @@ -626,9 +984,10 @@ public class IoTCompiler { 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(methPrmTypes.get(i), methParams.get(i))) + if (isArray(methParams.get(i))) print(getSimpleIdentifier(methParams.get(i)) + ".length"); - else if (isList(methPrmTypes.get(i), methParams.get(i))) + else if (isList(methPrmTypes.get(i))) print(getSimpleIdentifier(methParams.get(i)) + ".size()"); else print("new Integer(1)"); @@ -657,7 +1016,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) { @@ -857,16 +1216,49 @@ public class IoTCompiler { } + /** + * HELPER: writeStructPermissionJavaSkeleton() writes permission for struct helper + */ + private void writeStructPermissionJavaSkeleton(Collection methods, InterfaceDecl intDecl, String intface) { + + // 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); + String helperMethod = methodNumId + "struct" + i; + int methodHelperNumId = intDecl.getHelperMethodNumId(helperMethod); + // Iterate over interfaces to give permissions to + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + String newIntface = intMeth.getKey(); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("set" + newObjectId + "Allowed.add(" + methodHelperNumId + ");"); + } + } + } + } + } + + /** * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class */ - private void writeConstructorJavaSkeleton(String newSkelClass, String intface) { + private void writeConstructorJavaSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl, Collection methods, boolean callbackExist) { println("public " + newSkelClass + "(" + intface + " _mainObj, int _port) throws Exception {"); println("mainObj = _mainObj;"); println("rmiObj = new IoTRMIObject(_port);"); // Generate permission control initialization writeConstructorJavaPermission(intface); + writeJavaInitCallbackPermission(intface, intDecl, callbackExist); + writeStructPermissionJavaSkeleton(methods, intDecl, intface); println("___waitRequestInvokeMethod();"); println("}\n"); } @@ -951,7 +1343,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 @@ -963,10 +1356,10 @@ public class IoTCompiler { println("try {"); String exchParamType = checkAndGetParamClass(paramType); // Print array if this is array or list if this is a list of callback objects - if (isArray(paramType, param)) { + if (isArray(param)) { println("int numStubs" + i + " = (int) paramObj[" + i + "];"); println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];"); - } else if (isList(paramType, param)) { + } else if (isList(paramType)) { println("int numStubs" + i + " = (int) paramObj[" + i + "];"); println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();"); } else { @@ -977,12 +1370,12 @@ public class IoTCompiler { // Generate a loop if needed if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object String exchParamType = checkAndGetParamClass(paramType); - if (isArray(paramType, param)) { + if (isArray(param)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); println("objIdCnt++;"); println("}"); - } else if (isList(paramType, param)) { + } else if (isList(paramType)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));"); println("objIdCnt++;"); @@ -996,48 +1389,281 @@ public class IoTCompiler { /** - * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class + * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int) */ - private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method, Set callbackClasses) { - // Generate array of parameter objects - boolean isCallbackMethod = false; - String callbackType = null; - print("Object[] paramObj = rmiObj.getMethodParams(new Class[] { "); + private void checkAndWriteEnumTypeJavaSkeleton(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + println("int paramInt" + i + "[] = (int[]) paramObj[" + i + "];"); + println(simpleType + "[] enumVals = " + simpleType + ".values();"); + if (isArray(param)) { // An array + println("int len" + i + " = paramInt" + i + ".length;"); + println(simpleType + "[] paramEnum" + i + " = new " + simpleType + "[len" + i + "];"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = enumVals[paramInt" + i + "[i]];"); + println("}"); + } else if (isList(paramType)) { // A list + println("int len" + i + " = paramInt" + i + ".length;"); + println("List<" + simpleType + "> paramEnum" + i + " = new ArrayList<" + simpleType + ">();"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + ".add(enumVals[paramInt" + i + "[i]]);"); + println("}"); + } else { // Just one element + println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];"); + } + } + } + } - String paramType = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) { - isCallbackMethod = true; - callbackType = paramType; - print("int.class"); - } else { // Generate normal classes if it's not a callback object - String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print(getSimpleType(prmType) + ".class"); + + /** + * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getGenericType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(retType); + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + if (isArray(retType)) { // An array + print(pureType + "[] retEnum = " + methodId + "("); + } else if (isList(retType)) { // A list + print("List<" + pureType + "> retEnum = " + methodId + "("); + } else { // Just one element + print(pureType + " retEnum = " + methodId + "("); } - if (i != methParams.size() - 1) - print(", "); } - println(" }, "); - // Generate generic class if it's a generic type.. null otherwise - print("new Class[] { "); - for (int i = 0; i < methParams.size(); i++) { - String prmType = methPrmTypes.get(i); - if (getParamCategory(prmType) == ParamCategory.NONPRIMITIVES) - print(getTypeOfGeneric(prmType)[0] + ".class"); - else - print("null"); - if (i != methParams.size() - 1) - print(", "); + } + + + /** + * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetConvJavaSkeleton(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getGenericType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(retType); + if (isEnumClass(pureType)) { + // Check if this is enum type + if (isArray(retType)) { // An array + println("int retLen = retEnum.length;"); + println("int[] retEnumVal = new int[retLen];"); + println("for (int i = 0; i < retLen; i++) {"); + println("retEnumVal[i] = retEnum[i].ordinal();"); + println("}"); + } else if (isList(retType)) { // A list + println("int retLen = retEnum.size();"); + println("int[] retEnumVal = new int[retLen];"); + println("for (int i = 0; i < retLen; i++) {"); + println("retEnumVal[i] = retEnum.get(i).ordinal();"); + println("}"); + } else { // Just one element + println("int[] retEnumVal = new int[1];"); + println("retEnumVal[0] = retEnum.ordinal();"); + } + println("Object retObj = retEnumVal;"); } - println(" });"); - Map mapStubParam = null; - if (isCallbackMethod) + } + + + /** + * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params + */ + private void writeLengthStructParamClassSkeleton(List methParams, List methPrmTypes, + String method, InterfaceDecl intDecl) { + + // Iterate and find struct declarations - count number of params + 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 members = getNumOfMembers(simpleType); + print(Integer.toString(members) + "*"); + int methodNumId = intDecl.getMethodNumId(method); + print("struct" + methodNumId + "Size" + i); + } else + print("1"); + if (i != methParams.size() - 1) { + print("+"); + } + } + } + + + /** + * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct + */ + private void writeStructMembersJavaSkeleton(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); + if (isArrayOrList(param, paramType)) { // An array or list + int methodNumId = intDecl.getMethodNumId(method); + String counter = "struct" + methodNumId + "Size" + iVar; + println("for(int i = 0; i < " + counter + "; 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + println("paramClsGen[pos++] = null;"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + println("paramClsGen[pos++] = null;"); + } + } + } + + + /** + * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct + */ + private void writeStructMembersInitJavaSkeleton(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 (isArray(param)) { // An array + println(simpleType + "[] paramStruct" + i + " = new " + simpleType + "[" + counter + "];"); + println("for(int i = 0; i < " + counter + "; i++) {"); + println("paramStruct" + i + "[i] = new " + simpleType + "();"); + println("}"); + } else if (isList(paramType)) { // A list + println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();"); + } else + println(simpleType + " paramStruct" + i + " = new " + simpleType + "();"); + println("int objPos = 0;"); + // 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++) {"); + } + if (isArray(param)) { // An array + for (int j = 0; j < members.size(); j++) { + String prmType = checkAndGetArray(memTypes.get(j), members.get(j)); + print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j))); + println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];"); + } + println("}"); + } else if (isList(paramType)) { // A list + println(simpleType + " paramStructMem = new " + simpleType + "();"); + for (int j = 0; j < members.size(); j++) { + String prmType = checkAndGetArray(memTypes.get(j), members.get(j)); + print("paramStructMem." + getSimpleIdentifier(members.get(j))); + println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];"); + } + println("paramStruct" + i + ".add(paramStructMem);"); + println("}"); + } else { // Just one struct element + for (int j = 0; j < members.size(); j++) { + String prmType = checkAndGetArray(memTypes.get(j), members.get(j)); + print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j))); + println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];"); + } + } + } else { + // Take offsets of parameters + println("int offset" + i +" = objPos;"); + } + } + } + + + /** + * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement + */ + private void writeStructReturnJavaSkeleton(String simpleType, String retType) { + + // Minimum retLen is 1 if this is a single struct object + if (isArray(retType)) + println("int retLen = retStruct.length;"); + else if (isList(retType)) + println("int retLen = retStruct.size();"); + else // Just single struct object + println("int retLen = 1;"); + println("Object retLenObj = retLen;"); + println("rmiObj.sendReturnObj(retLenObj);"); + int numMem = getNumOfMembers(simpleType); + println("Class[] retCls = new Class[" + numMem + "*retLen];"); + println("Object[] retObj = new Object[" + numMem + "*retLen];"); + 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + 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 prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); + print("retObj[retPos++] = retStruct."); + print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton + */ + private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, boolean isCallbackMethod, String callbackType, + boolean isStructMethod) { + + 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(getGenericType(retType)))) { // Enum type + checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method)); + } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type + print(retType + " retStruct = " + intDecl.getMethodId(method) + "("); } else { // We do have a return value print("Object retObj = " + intDecl.getMethodId(method) + "("); } @@ -1045,18 +1671,34 @@ public class IoTCompiler { if (isCallbackMethod) { print(mapStubParam.get(i)); // Get the callback parameter + } else if (isEnumClass(getGenericType(methPrmTypes.get(i)))) { // Enum class + print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i)); + } else if (isStructClass(getGenericType(methPrmTypes.get(i)))) { + print("paramStruct" + i); } else { String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - print("(" + prmType + ") paramObj[" + i + "]"); + if (isStructMethod) + print("(" + prmType + ") paramObj[offset" + i + "]"); + else + print("(" + prmType + ") paramObj[" + i + "]"); } if (i != methParams.size() - 1) print(", "); } println(");"); - if (!retType.equals("void")) - println("rmiObj.sendReturnObj(retObj);"); + if (!retType.equals("void")) { + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type + checkAndWriteEnumRetConvJavaSkeleton(retType); + println("rmiObj.sendReturnObj(retObj);"); + } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type + writeStructReturnJavaSkeleton(getSimpleArrayType(getGenericType(retType)), retType); + println("rmiObj.sendReturnObj(retCls, retObj);"); + } else + 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("}"); @@ -1064,6 +1706,96 @@ public class IoTCompiler { } + /** + * 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); + } + + + /** + * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class + */ + private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, Set callbackClasses) { + + // Generate array of parameter objects + boolean isCallbackMethod = false; + String callbackType = null; + print("Object[] paramObj = rmiObj.getMethodParams(new Class[] { "); + for (int i = 0; i < methParams.size(); i++) { + + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) { + isCallbackMethod = true; + callbackType = paramType; + print("int.class"); + } else { // Generate normal classes if it's not a callback object + String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + print(getSimpleType(getEnumType(prmType)) + ".class"); + } + if (i != methParams.size() - 1) + print(", "); + } + println(" }, "); + // Generate generic class if it's a generic type.. null otherwise + print("new Class[] { "); + for (int i = 0; i < methParams.size(); i++) { + String prmType = methPrmTypes.get(i); + if ((getParamCategory(prmType) == ParamCategory.NONPRIMITIVES) && + !isEnumClass(getGenericType(prmType))) + print(getGenericType(prmType) + ".class"); + else + print("null"); + if (i != methParams.size() - 1) + print(", "); + } + println(" });"); + // Write the return value part + writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false); + } + + /** * HELPER: writeMethodHelperJavaSkeleton() writes the method helper of the skeleton class */ @@ -1075,22 +1807,227 @@ 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 + "() {"); - else - println(helperMethod + "() 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(") {"); + else + println(") 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 + "() {"); + else + println(helperMethod + "() throws IOException {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses); + println("}\n"); + } + } + // Write method helper for structs + writeMethodHelperStructSetupJavaSkeleton(methods, intDecl); + } + + + /** + * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class + */ + private void writeMethodHelperStructSetupJavaSkeleton(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 + "() {"); + // 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: 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 writeCountVarStructSkeleton(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); + println("int struct" + methodNumId + "Size" + i + " = 0;"); + } + } + } + } + + + /** + * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton + */ + 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); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + boolean begin = true; + if (isStructClass(simpleType)) { + structExist = true; + if (!begin) { + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("struct" + methodNumId + "Size" + i); + } + } + return structExist; + } + + + /** + * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton + */ + private void writeMethodCallStructSkeleton(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 + "(); break;"); + } + } + } + } + + + /** + * 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;"); + } + } } } @@ -1104,15 +2041,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("}"); } } @@ -1126,6 +2063,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 + writeCountVarStructSkeleton(methods, intDecl); println("while (true) {"); println("rmiObj.getMethodBytes();"); println("int _objectId = rmiObj.getObjectId();"); @@ -1143,7 +2081,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 @@ -1151,6 +2091,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(); break;"); } + writeMethodCallStructSkeleton(methods, intDecl); println("default: "); println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");"); println("}"); @@ -1188,7 +2129,7 @@ public class IoTCompiler { // Write properties writePropertiesJavaSkeleton(intface, callbackExist, intDecl); // Write constructor - writeConstructorJavaSkeleton(newSkelClass, intface); + writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist); // Write methods writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false); // Write method helper @@ -1222,7 +2163,7 @@ public class IoTCompiler { /** * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class */ - private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface) { + private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl, Collection methods) { println("public " + newSkelClass + "(" + intface + " _mainObj, int _objectId) throws Exception {"); println("mainObj = _mainObj;"); @@ -1242,28 +2183,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) { @@ -1271,6 +2246,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) {"); @@ -1284,7 +2261,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 @@ -1292,6 +2273,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("}"); @@ -1328,7 +2310,7 @@ public class IoTCompiler { // Write properties writePropertiesJavaCallbackSkeleton(intface, callbackExist); // Write constructor - writeConstructorJavaCallbackSkeleton(newSkelClass, intface); + writeConstructorJavaCallbackSkeleton(newSkelClass, intface, intDecl, methods); // Write methods writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true); // Write method helper @@ -1343,7 +2325,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) { @@ -1401,52 +2383,83 @@ public class IoTCompiler { /** - * HELPER: writeEnumCplus() writes the enumeration declaration + * HELPER: generateEnumCplus() writes the enumeration declaration */ - private void writeEnumCplus(EnumDecl enumDecl) { + public void generateEnumCplus() throws IOException { - Set enumTypes = enumDecl.getEnumDeclarations(); - // Iterate over enum declarations - for (String enType : enumTypes) { - - println("enum " + enType + " {"); - List enumMembers = enumDecl.getMembers(enType); - for (int i = 0; i < enumMembers.size(); i++) { - - String member = enumMembers.get(i); - print(member); - // Check if this is the last element (don't print a comma) - if (i != enumMembers.size() - 1) - println(","); - else - println(""); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set enumTypes = enumDecl.getEnumDeclarations(); + // Iterate over enum declarations + for (String enType : enumTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + // Write file headers + println("#ifndef _" + enType.toUpperCase() + "_HPP__"); + println("#define _" + enType.toUpperCase() + "_HPP__"); + println("enum " + enType + " {"); + List enumMembers = enumDecl.getMembers(enType); + for (int i = 0; i < enumMembers.size(); i++) { + + String member = enumMembers.get(i); + print(member); + // Check if this is the last element (don't print a comma) + if (i != enumMembers.size() - 1) + println(","); + else + println(""); + } + println("};\n"); + println("#endif"); + pw.close(); + System.out.println("IoTCompiler: Generated enum " + enType + ".hpp..."); } - println("};\n"); } } /** - * HELPER: writeStructCplus() writes the struct declaration + * HELPER: generateStructCplus() writes the struct declaration */ - private void writeStructCplus(StructDecl structDecl) { - - List structTypes = structDecl.getStructTypes(); - // Iterate over enum declarations - for (String stType : structTypes) { - - println("struct " + stType + " {"); - List structMemberTypes = structDecl.getMemberTypes(stType); - List structMembers = structDecl.getMembers(stType); - for (int i = 0; i < structMembers.size(); i++) { + public void generateStructCplus() throws IOException { - String memberType = structMemberTypes.get(i); - String member = structMembers.get(i); - String structTypeC = checkAndGetCplusType(memberType); - String structComplete = checkAndGetCplusArray(structTypeC, member); - println(structComplete + ";"); + // Create a new directory + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { + // Get the right StructDecl + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List structTypes = structDecl.getStructTypes(); + // Iterate over enum declarations + for (String stType : structTypes) { + // Open a new file to write into + FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + // Write file headers + println("#ifndef _" + stType.toUpperCase() + "_HPP__"); + println("#define _" + stType.toUpperCase() + "_HPP__"); + println("using namespace std;"); + println("struct " + stType + " {"); + List structMemberTypes = structDecl.getMemberTypes(stType); + List structMembers = structDecl.getMembers(stType); + for (int i = 0; i < structMembers.size(); i++) { + + String memberType = structMemberTypes.get(i); + String member = structMembers.get(i); + String structTypeC = checkAndGetCplusType(memberType); + String structComplete = checkAndGetCplusArray(structTypeC, member); + println(structComplete + ";"); + } + println("};\n"); + println("#endif"); + pw.close(); + System.out.println("IoTCompiler: Generated struct " + stType + ".hpp..."); } - println("};\n"); } } @@ -1475,15 +2488,10 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + 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); + //writeStructCplus(structDecl); println("class " + intface); println("{"); println("public:"); // Write methods @@ -1521,7 +2529,7 @@ public class IoTCompiler { println("#define _" + newIntface.toUpperCase() + "_HPP__"); println("#include "); // Pass in set of methods and get import classes - Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, false); + Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -1541,7 +2549,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) { @@ -1586,82 +2594,348 @@ public class IoTCompiler { /** - * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class + * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class + */ + private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, + List 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 (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {"); + println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);"); + isArrayOrList = true; + callbackParam = getSimpleIdentifier(param); + } else + println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" + + getSimpleIdentifier(param) + ", objIdCnt++);"); + println("vecCallbackObj.push_back(skel);"); + if (isArrayOrList(paramType, param)) + println("}"); + } + } + println("int numParam = " + methParams.size() + ";"); + 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 + print("string paramCls[] = { "); + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + 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 = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + print("\"" + paramTypeC + "\""); + } + if (i != methParams.size() - 1) // Check if this is the last element + print(", "); + } + println(" };"); + print("int ___paramCB = "); + if (isArrayOrList) + println(callbackParam + ".size();"); + else + println("1;"); + // Generate array of parameter objects + print("void* paramObj[] = { "); + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object + print("&___paramCB"); + } else + print(getSimpleIdentifier(methParams.get(i))); + 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.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;"); + } + } + + + /** + * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeCplusStub(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + if (isEnumClass(getGenericType(paramType))) { + // Check if this is enum type + if (isArrayOrList(paramType, param)) { // An array or vector + println("int len" + i + " = " + getSimpleIdentifier(param) + ".size();"); + println("vector paramEnum" + i + "(len" + i + ");"); + println("for (int i = 0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = (int) " + getSimpleIdentifier(param) + "[i];"); + println("}"); + } else { // Just one element + println("vector paramEnum" + i + "(1);"); + println("paramEnum" + i + "[0] = (int) " + param + ";"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeCplusStub(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getGenericType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(retType); + if (isEnumClass(pureType)) { + // Check if this is enum type + println("vector retEnumInt;"); + println("void* retObj = &retEnumInt;"); + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); + if (isArrayOrList(retType, retType)) { // An array or vector + println("int retLen = retEnumInt.size();"); + println("vector<" + pureType + "> retVal(retLen);"); + println("for (int i = 0; i < retLen; i++) {"); + println("retVal[i] = (" + pureType + ") retEnumInt[i];"); + println("}"); + } else { // Just one element + println(pureType + " retVal = (" + pureType + ") retEnumInt[0];"); + } + println("return retVal;"); + } + } + + + /** + * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup + */ + 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"); + } + } + } + + + /** + * 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++) { + 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("+"); + } + } + } + + + /** + * 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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + 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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + 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 = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + 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 writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, - List 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 (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {"); - println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);"); - isArrayOrList = true; - callbackParam = getSimpleIdentifier(param); - } else - println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" + - getSimpleIdentifier(param) + ", objIdCnt++);"); - println("vecCallbackObj.push_back(skel);"); - if (isArrayOrList(paramType, param)) - println("}"); + 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];"); } - } - 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) + "\";"); - // Generate array of parameter types - print("string paramCls[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = methPrmTypes.get(i); - 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)); - print("\"" + prmType + "\""); + } 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 + ";"); } - if (i != methParams.size() - 1) // Check if this is the last element - print(", "); - } - println(" };"); - print("int ___paramCB = "); - if (isArrayOrList) - println(callbackParam + ".size();"); - else - println("1;"); - // Generate array of parameter objects - print("void* paramObj[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = methPrmTypes.get(i); - if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - print("&___paramCB"); - } else - print(getSimpleIdentifier(methParams.get(i))); - 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.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;"); + 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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("retCls[retPos] = \"" + prmTypeC + "\";"); + println("retObj[retPos++] = &retParam" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("retCls[retPos] = \"" + prmTypeC + "\";"); + 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); } @@ -1671,45 +2945,61 @@ public class IoTCompiler { private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, List methPrmTypes, String method) { - println("int numParam = " + methParams.size() + ";"); + checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - String retTypeC = checkAndGetCplusType(retType); - println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";"); + println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";"); // 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("\"" + paramType + "\""); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + 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 = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + print("\"" + paramTypeC + "\""); + // 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("void* paramObj[] = { "); - for (int i = 0; i < methParams.size(); i++) { - print("&" + getSimpleIdentifier(methParams.get(i))); - // 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(" };"); } - 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.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;"); + // Generate array of parameter types + if (isStructClass(getGenericType(getSimpleArrayType(retType)))) { + writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType); + } else { + // Check if the return value NONPRIMITIVES + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { + 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;"); + } + } } } @@ -1722,9 +3012,9 @@ 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 + ";"); - println("const static set set" + newObjectId + "Allowed;"); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface); + println("static set set" + newObjectId + "Allowed;"); } } @@ -1768,7 +3058,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);"); @@ -1817,7 +3106,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);"); @@ -1842,7 +3131,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);"); @@ -1853,7 +3143,25 @@ public class IoTCompiler { /** - * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization of callback + * HELPER: writeCplusInitCallbackPermission() writes the permission for callback + */ + private void writeCplusInitCallbackPermission(String intface, InterfaceDecl intDecl, boolean callbackExist) { + + if (callbackExist) { + String method = "___initCallBack()"; + int methodNumId = intDecl.getHelperMethodNumId(method); + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + String newIntface = intMeth.getKey(); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("set" + newObjectId + "Allowed.insert(" + methodNumId + ");"); + } + } + } + + + /** + * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback */ private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) { @@ -1861,7 +3169,9 @@ public class IoTCompiler { println("void ___regCB() {"); println("int numParam = 3;"); String method = "___initCallBack()"; - println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";"); + int methodNumId = intDecl.getHelperMethodNumId(method); + println("int methodId = " + methodNumId + ";"); + //writeCplusCallbackPermission(intface, methodNumId); println("string retType = \"void\";"); println("string paramCls[] = { \"int\", \"string\", \"int\" };"); println("int rev = 0;"); @@ -1915,6 +3225,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..."); @@ -1930,7 +3241,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(); @@ -2010,6 +3321,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..."); @@ -2041,6 +3353,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 */ @@ -2050,8 +3372,8 @@ public class IoTCompiler { Map> mapNewIntMethods = mapInt2NewInts.get(intface); for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { String newIntface = intMeth.getKey(); - int newObjectId = mapNewIntfaceObjId.get(newIntface); - print("const set " + newSkelClass + "::set" + newObjectId + "Allowed {"); + int newObjectId = getNewIntfaceObjectId(newIntface); + print("set " + newSkelClass + "::set" + newObjectId + "Allowed {"); Set methodIds = intMeth.getValue(); int i = 0; for (String methodId : methodIds) { @@ -2068,20 +3390,48 @@ public class IoTCompiler { } + /** + * HELPER: writeStructPermissionCplusSkeleton() writes permission for struct helper + */ + private void writeStructPermissionCplusSkeleton(Collection methods, InterfaceDecl intDecl, String intface) { + + // 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); + String helperMethod = methodNumId + "struct" + i; + int helperMethodNumId = intDecl.getHelperMethodNumId(helperMethod); + // Iterate over interfaces to give permissions to + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + String newIntface = intMeth.getKey(); + int newObjectId = getNewIntfaceObjectId(newIntface); + println("set" + newObjectId + "Allowed.insert(" + helperMethodNumId + ");"); + } + } + } + } + } + + /** * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class */ - private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist) { + private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection methods) { println(newSkelClass + "(" + intface + " *_mainObj, int _port) {"); println("bool _bResult = false;"); println("mainObj = _mainObj;"); println("rmiObj = new IoTRMIObject(_port, &_bResult);"); - // Callback - if (callbackExist) { - println("objIdCnt = 0;"); - } - //println("set0Allowed = Arrays.asList(object0Permission);"); + writeCplusInitCallbackPermission(intface, intDecl, callbackExist); + writeStructPermissionCplusSkeleton(methods, intDecl, intface); println("___waitRequestInvokeMethod();"); println("}\n"); } @@ -2151,7 +3501,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"); @@ -2247,6 +3599,127 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int) + */ + private void checkAndWriteEnumTypeCplusSkeleton(List methParams, List methPrmTypes) { + + // Iterate and find enum declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isEnumClass(simpleType)) { + // Check if this is enum type + if (isArrayOrList(paramType, param)) { // An array + println("int len" + i + " = paramEnumInt" + i + ".size();"); + println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");"); + println("for (int i=0; i < len" + i + "; i++) {"); + println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];"); + println("}"); + } else { // Just one element + println(simpleType + " paramEnum" + i + ";"); + println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];"); + } + } + } + } + + + /** + * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int) + */ + private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(getGenericType(retType)); + // Take the inner type of generic + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(retType); + if (isEnumClass(pureType)) { + // Check if this is enum type + // Enum decoder + if (isArrayOrList(retType, retType)) { // An array + println("int retLen = retEnum.size();"); + println("vector retEnumInt(retLen);"); + println("for (int i=0; i < retLen; i++) {"); + println("retEnumInt[i] = (int) retEnum[i];"); + println("}"); + } else { // Just one element + println("vector retEnumInt(1);"); + println("retEnumInt[0] = (int) retEnum;"); + } + } + } + + + /** + * 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(getGenericType(paramType))) // Check if this is enum type + print("paramEnum" + i); + else if (isStructClass(getGenericType(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(getGenericType(retType)))) // Enum type + print(checkAndGetCplusType(retType) + " retEnum = "); + else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type + print(checkAndGetCplusType(retType) + " retStruct = "); + else + print(checkAndGetCplusType(retType) + " retVal = "); + writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId); + checkAndWriteEnumRetTypeCplusSkeleton(retType); + if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type + writeStructReturnCplusSkeleton(getSimpleArrayType(getGenericType(retType)), retType); + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type + println("void* retObj = &retEnumInt;"); + else + if (!isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type + println("void* retObj = &retVal;"); + String retTypeC = checkAndGetCplusType(retType); + if (isStructClass(getSimpleArrayType(getGenericType(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 */ @@ -2264,9 +3737,8 @@ public class IoTCompiler { 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("\"" + prmType + "\""); + String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + print("\"" + paramTypeC + "\""); } if (i != methParams.size() - 1) { print(", "); @@ -2279,87 +3751,347 @@ public class IoTCompiler { // 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)); - String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i)); - println(methParamComplete + ";"); + if (!callbackClasses.contains(paramType)) { + String methParamType = methPrmTypes.get(i); + if (isEnumClass(getSimpleArrayType(getGenericType(methParamType)))) { + // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methPrmType = checkAndGetCplusType(methParamType); + 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(getGenericType(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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + println("paramObj[pos++] = ¶m" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + 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 prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("retCls[retPos] = \"" + prmTypeC + "\";"); + 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 prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("retCls[retPos] = \"" + prmTypeC + "\";"); + 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 - print("void* paramObj[] = { "); + 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 = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) - print("&numStubs" + 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 = 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)); + if (isEnumClass(getGenericType(paramTypeC))) { // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i)); + println(methParamComplete + ";"); + } + String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + if (isEnumClass(getGenericType(paramType))) // Check if this is enum type + println("paramObj[pos++] = ¶mEnumInt" + i); + else + println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";"); + } } } - println(" };"); - println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); - if (isCallbackMethod) - writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType); - 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); + // 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 - print(getSimpleIdentifier(methParams.get(i))); - if (i != methParams.size() - 1) { - print(", "); + 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"); } - println(");"); - } else { // We do have a return value - print(checkAndGetCplusType(retType) + " retVal = " + methodId + "("); + } + // Write method helper for structs + writeMethodHelperStructSetupCplusSkeleton(methods, intDecl); + } + + + /** + * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class + */ + private void writeMethodHelperStructSetupCplusSkeleton(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 = returnGenericCallbackType(methPrmTypes.get(i)); - if (callbackClasses.contains(paramType)) - print("stub" + 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(");"); - println("void* retObj = &retVal;"); - String retTypeC = checkAndGetCplusType(retType); - println("rmiObj->sendReturnObj(retObj, \"" + 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"); + } + } } } @@ -2373,17 +4105,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("}"); } } @@ -2397,6 +4129,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();"); @@ -2414,7 +4147,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 @@ -2422,6 +4157,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();"); @@ -2452,7 +4188,7 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -2467,7 +4203,7 @@ public class IoTCompiler { writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses); println("public:\n"); // Write constructor - writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist); + writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods); // Write deconstructor writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses); // Write methods @@ -2478,6 +4214,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..."); @@ -2492,7 +4229,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(); @@ -2510,15 +4247,11 @@ public class IoTCompiler { /** * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class */ - private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) { + private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection methods) { println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {"); println("mainObj = _mainObj;"); println("objectId = _objectId;"); - // Callback - if (callbackExist) { - println("objIdCnt = 0;"); - } println("}\n"); } @@ -2550,7 +4283,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) { @@ -2561,25 +4294,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) { @@ -2588,6 +4351,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) {"); @@ -2601,7 +4366,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 @@ -2609,6 +4378,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();"); @@ -2617,7 +4387,6 @@ public class IoTCompiler { } - /** * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++ */ @@ -2639,7 +4408,7 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods, intDecl, true); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, true); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -2654,7 +4423,7 @@ public class IoTCompiler { writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses); println("public:\n"); // Write constructor - writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist); + writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist, intDecl, methods); // Write deconstructor writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses); // Write methods @@ -2664,6 +4433,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..."); @@ -2701,35 +4471,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 */ @@ -2775,7 +4516,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; @@ -2783,7 +4524,7 @@ public class IoTCompiler { /**================ - * Helper functions + * Basic helper functions **================ */ boolean newline=true; @@ -2806,12 +4547,18 @@ public class IoTCompiler { /** * This function converts Java to C++ type for compilation */ - private String convertType(String jType) { + private String convertType(String type) { - return mapPrimitives.get(jType); + if (mapPrimitives.containsKey(type)) + return mapPrimitives.get(type); + else + return type; } + /** + * A collection of methods with print-to-file functionality + */ private void println(String str) { if (newline) { int tab = tablevel; @@ -2882,7 +4629,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)) { @@ -2890,13 +4652,17 @@ public class IoTCompiler { // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) { return ParamCategory.NONPRIMITIVES; + } else if (isEnumClass(paramType)) { + return ParamCategory.ENUM; + } else if (isStructClass(paramType)) { + return ParamCategory.STRUCT; } else return ParamCategory.USERDEFINED; } // 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); @@ -2904,7 +4670,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); @@ -2924,6 +4690,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() { @@ -2954,7 +4732,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); @@ -2964,7 +4742,6 @@ public class IoTCompiler { allLibClasses.add(str); } } - return allLibClasses; } @@ -2988,8 +4765,148 @@ public class IoTCompiler { } + // Handle and return the correct enum declaration + // In Java, if we declare enum in Camera interface, then it becomes "Camera." + private String getEnumParamDecl(String type, InterfaceDecl intDecl) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(type)[0]; + if (isEnumClass(pureType)) { + String enumType = intDecl.getInterface() + "." + type; + return enumType; + } else + return type; + } + + + // Handle and return the correct type + private String getEnumParam(String type, String param, int i) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getTypeOfGeneric(type)[0]; + if (isEnumClass(pureType)) { + String enumParam = "paramEnum" + i; + return enumParam; + } else + return param; + } + + + // Handle and return the correct enum declaration translate into int[] + private String getEnumType(String type) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(type); + if (isEnumClass(pureType)) { + String enumType = "int[]"; + return enumType; + } else + return type; + } + + // Handle and return the correct enum declaration translate into int* for C + private String getEnumCplusClsType(String type) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(type); + if (isEnumClass(pureType)) { + String enumType = "int*"; + return enumType; + } else + return type; + } + + + // Handle and return the correct struct declaration + private String getStructType(String type) { + + // Strips off array "[]" for return type + String pureType = getSimpleArrayType(type); + // Take the inner type of generic + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) + pureType = getGenericType(type); + if (isStructClass(pureType)) { + String structType = "int"; + return structType; + } else + return type; + } + + + // Check if this an enum declaration + private boolean isEnumClass(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface); + Set setEnumDecl = enumDecl.getEnumDeclarations(); + if (setEnumDecl.contains(type)) + return true; + } + return false; + } + + + // Check if this an struct declaration + private boolean isStructClass(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List listStructDecl = structDecl.getStructTypes(); + if (listStructDecl.contains(type)) + return true; + } + return false; + } + + + // Return a struct declaration + private StructDecl getStructDecl(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List listStructDecl = structDecl.getStructTypes(); + if (listStructDecl.contains(type)) + return structDecl; + } + return null; + } + + + // Return number of members (-1 if not found) + private int getNumOfMembers(String type) { + + // Just iterate over the set of interfaces + for (String intface : mapIntfacePTH.keySet()) { + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface); + List listStructDecl = structDecl.getStructTypes(); + if (listStructDecl.contains(type)) + return structDecl.getNumOfMembers(type); + } + return -1; + } + + // Generate a set of classes for include statements - private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl, boolean needExchange) { + private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl, String intface, boolean needExchange) { Set includeClasses = new HashSet(); for (String method : methods) { @@ -3011,6 +4928,10 @@ public class IoTCompiler { includeClasses.add("\"" + simpleType + ".hpp\""); includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\""); } + } 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(""); @@ -3047,6 +4968,7 @@ public class IoTCompiler { } + // Print import statements into file private void printImportStatements(Collection importClasses) { for(String cls : importClasses) { @@ -3055,6 +4977,7 @@ public class IoTCompiler { } + // Print include statements into file private void printIncludeStatements(Collection includeClasses) { for(String cls : includeClasses) { @@ -3074,6 +4997,30 @@ public class IoTCompiler { } + // Gets generic type inside "<" and ">" + private String getGenericType(String type) { + + // Handle <, >, and , for 2-type generic/template + if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) { + String[] substr = type.split("<")[1].split(">")[0].split(","); + return substr[0]; + } else + return type; + } + + + // This helper function strips off array declaration, e.g. int[] becomes int + private String getSimpleArrayType(String type) { + + // Handle [ for array declaration + String substr = type; + if (type.contains("[]")) { + substr = type.split("\\[\\]")[0]; + } + return substr; + } + + // This helper function strips off array declaration, e.g. D[] becomes D private String getSimpleIdentifier(String ident) { @@ -3086,6 +5033,7 @@ public class IoTCompiler { } + // Checks and gets type in C++ private String checkAndGetCplusType(String paramType) { if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) { @@ -3107,6 +5055,9 @@ public class IoTCompiler { return cplusTemplate; } else return getNonPrimitiveCplusClass(paramType); + } else if(paramType.contains("[]")) { // Array type (used for return type only) + String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">"; + return cArray; } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { return paramType + "*"; } else @@ -3173,6 +5124,52 @@ 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 = getEnumCplusClsType(paramType); + if (!paramTypeRet.equals(paramType)) + // Just return if it is an enum type + // Type will still be the same if it's not an enum type + return paramTypeRet; + + // 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) { @@ -3193,17 +5190,18 @@ public class IoTCompiler { private boolean isArrayOrList(String paramType, String param) { // Check for array declaration - if (isArray(paramType, param)) + if (isArray(param)) return true; - else if (isList(paramType, param)) + else if (isList(paramType)) return true; else return false; } - // Is array or list? - private boolean isArray(String paramType, String param) { + // Is array? + // For return type we use retType as input parameter + private boolean isArray(String param) { // Check for array declaration if (param.contains("[]")) @@ -3213,8 +5211,8 @@ public class IoTCompiler { } - // Is array or list? - private boolean isList(String paramType, String param) { + // Is list? + private boolean isList(String paramType) { // Check for array declaration if (paramType.contains("List")) @@ -3253,7 +5251,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 @@ -3262,7 +5260,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"); } } @@ -3299,12 +5297,16 @@ public class IoTCompiler { // Generate everything if we don't see "-java" or "-cplus" if (i == args.length) { + comp.generateEnumJava(); + comp.generateStructJava(); comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); comp.generateJavaCallbackStubClasses(); comp.generateJavaSkeletonClass(); comp.generateJavaCallbackSkeletonClass(); + comp.generateEnumCplus(); + comp.generateStructCplus(); comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); @@ -3317,14 +5319,16 @@ 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(); + comp.generateStructJava(); comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); @@ -3332,6 +5336,8 @@ public class IoTCompiler { comp.generateJavaSkeletonClass(); comp.generateJavaCallbackSkeletonClass(); } else { + comp.generateEnumCplus(); + comp.generateStructCplus(); comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); @@ -3346,11 +5352,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"); } } } - -