X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=iotjava%2Fiotpolicy%2FIoTCompiler.java;h=66287f93a79b4fc58d5813757128ff71f2ef71d0;hb=47a251f41e05f47b4bc19c236ab9441cef5ed42c;hp=651a4b8cda51d19214416a84c679631052cb552d;hpb=695e2eefac04486856369e04112aefbdc8c539c6;p=iot2.git diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index 651a4b8..66287f9 100644 --- a/iotjava/iotpolicy/IoTCompiler.java +++ b/iotjava/iotpolicy/IoTCompiler.java @@ -48,6 +48,7 @@ public class IoTCompiler { private Map mapIntfacePTH; private Map mapIntDeclHand; private Map>> mapInt2NewInts; + private Map mapInt2NewIntName; // Data structure to store our types (primitives and non-primitives) for compilation private Map mapPrimitives; private Map mapNonPrimitivesJava; @@ -58,6 +59,8 @@ public class IoTCompiler { private PrintWriter pw; private String dir; private String subdir; + private Map mapPortCount; // Counter for ports + private static int portCount = 0; /** @@ -83,6 +86,7 @@ public class IoTCompiler { mapIntfacePTH = new HashMap(); mapIntDeclHand = new HashMap(); mapInt2NewInts = new HashMap>>(); + mapInt2NewIntName = new HashMap(); mapIntfaceObjId = new HashMap(); mapNewIntfaceObjId = new HashMap(); mapPrimitives = new HashMap(); @@ -91,6 +95,7 @@ public class IoTCompiler { arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs); mapNonPrimitivesCplus = new HashMap(); arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus); + mapPortCount = new HashMap(); pw = null; dir = OUTPUT_DIRECTORY; subdir = null; @@ -177,6 +182,9 @@ public class IoTCompiler { } // Add interface and methods information into map mapNewIntMethods.put(strInt, setMethods); + // Map new interface method name to the original interface + // TODO: perhaps need to check in the future if we have more than 1 stub interface for one original interface + mapInt2NewIntName.put(origInt, strInt); } // Map the map of interface-methods to the original interface mapInt2NewInts.put(origInt, mapNewIntMethods); @@ -342,6 +350,17 @@ public class IoTCompiler { } + /** + * HELPER: updateIntfaceObjIdMap() updates the mapping between new interface and object Id + */ + private void updateIntfaceObjIdMap(String intface, String newIntface) { + + Integer objId = mapIntfaceObjId.get(intface); + mapNewIntfaceObjId.put(newIntface, objId); + mapIntfaceObjId.put(intface, objId++); + } + + /** * generateJavaInterfaces() generate stub interfaces based on the methods list in Java */ @@ -361,7 +380,7 @@ public class IoTCompiler { DeclarationHandler decHandler = mapIntDeclHand.get(intface); InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); // Pass in set of methods and get import classes - List methods = intDecl.getMethods(); + Set methods = intMeth.getValue(); Set importClasses = getImportClasses(methods, intDecl); List stdImportClasses = getStandardJavaIntfaceImportClasses(); List allImportClasses = getAllLibClasses(stdImportClasses, importClasses); @@ -369,6 +388,7 @@ public class IoTCompiler { // Write interface header println(""); println("public interface " + newIntface + " {\n"); + updateIntfaceObjIdMap(intface, newIntface); // Write methods writeMethodJavaInterface(methods, intDecl); println("}"); @@ -387,7 +407,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(); @@ -403,7 +423,7 @@ public class IoTCompiler { i++; } println(" };"); - println("private List set" + newObjectId + "Allowed;"); + println("private static List set" + newObjectId + "Allowed;"); } } @@ -414,13 +434,13 @@ public class IoTCompiler { private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set callbackClasses) { println("private IoTRMICall rmiCall;"); - println("private String address;"); + println("private String callbackAddress;"); println("private int[] ports;\n"); // Get the object Id Integer objId = mapIntfaceObjId.get(intface); println("private final static int objectId = " + objId + ";"); - mapNewIntfaceObjId.put(newIntface, objId); - mapIntfaceObjId.put(intface, objId++); + //mapNewIntfaceObjId.put(newIntface, objId); + //mapIntfaceObjId.put(intface, objId++); if (callbackExist) { // We assume that each class only has one callback interface for now Iterator it = callbackClasses.iterator(); @@ -446,8 +466,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));"); } } @@ -457,15 +477,18 @@ public class IoTCompiler { */ private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set callbackClasses) { - println("public " + newStubClass + "(int _port, String _address, int _rev, int[] _ports) throws Exception {"); - println("address = _address;"); + println("public " + newStubClass + "(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {"); + println("callbackAddress = _callbackAddress;"); println("ports = _ports;"); - println("rmiCall = new IoTRMICall(_port, _address, _rev);"); + println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);"); if (callbackExist) { Iterator it = callbackClasses.iterator(); String callbackType = (String) it.next(); - writeConstructorJavaPermission(intface); + writeConstructorJavaPermission(callbackType); println("listCallbackObj = new ArrayList<" + callbackType + ">();"); + DeclarationHandler decHandler = mapIntDeclHand.get(callbackType); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType); + writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist); println("___initCallBack();"); } println("}\n"); @@ -482,7 +505,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("}"); @@ -490,29 +513,61 @@ public class IoTCompiler { } + /** + * 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: getPortCount() gets port count for different stubs and skeletons + */ + private int getPortCount(String intface) { + + if (!mapPortCount.containsKey(intface)) + mapPortCount.put(intface, portCount++); + return mapPortCount.get(intface); + } + + /** * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub */ - private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) { + private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl, String newStubClass) { println("public void ___initCallBack() {"); // Generate main thread for callbacks println("Thread thread = new Thread() {"); println("public void run() {"); println("try {"); - println("rmiObj = new IoTRMIObject(ports[0]);"); + int port = getPortCount(newStubClass); + println("rmiObj = new IoTRMIObject(ports[" + port + "]);"); println("while (true) {"); println("byte[] method = rmiObj.getMethodBytes();"); - writeJavaMethodCallbackPermission(intface); println("int objId = IoTRMIObject.getObjectId(method);"); println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);"); println("if (skel != null) {"); + writeJavaMethodCallbackPermission(intface); 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("}"); @@ -521,10 +576,11 @@ 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 };"); + println("Class[] paramCls = new Class[] { int[].class, String.class, int.class };"); + println("Object[] paramObj = new Object[] { ports, callbackAddress, 0 };"); println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); println("}\n"); } @@ -539,20 +595,20 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isEnumClass(simpleType)) { // Check if this is enum type if (isArray(param)) { // An array - println("int len" + i + " = " + param + ".length;"); - println("int paramEnum" + i + "[] = new int[len];"); + 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] = " + param + "[i].ordinal();"); + println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + "[i].ordinal();"); println("}"); } else if (isList(paramType)) { // A list - println("int len" + i + " = " + param + ".size();"); - println("int paramEnum" + i + "[] = new int[len];"); + 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] = " + param + ".get(i).ordinal();"); + println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + ".get(i).ordinal();"); println("}"); } else { // Just one element println("int paramEnum" + i + "[] = new int[1];"); @@ -569,10 +625,10 @@ public class IoTCompiler { private void checkAndWriteEnumRetTypeJavaStub(String retType) { // Strips off array "[]" for return type - String pureType = getSimpleArrayType(getSimpleType(retType)); + String pureType = getSimpleArrayType(getGenericType(retType)); // Take the inner type of generic if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(retType)[0]; + pureType = getGenericType(retType); if (isEnumClass(pureType)) { // Check if this is enum type // Enum decoder @@ -608,7 +664,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { // Check if this is enum type int methodNumId = intDecl.getMethodNumId(method); @@ -640,7 +696,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) return true; } @@ -661,10 +717,10 @@ public class IoTCompiler { if (isStructClass(simpleType)) { int members = getNumOfMembers(simpleType); if (isArray(param)) { // An array - String structLen = param + ".length"; + String structLen = getSimpleArrayType(param) + ".length"; print(members + "*" + structLen); } else if (isList(paramType)) { // A list - String structLen = param + ".size()"; + String structLen = getSimpleArrayType(param) + ".size()"; print(members + "*" + structLen); } else print(Integer.toString(members)); @@ -687,15 +743,21 @@ public class IoTCompiler { List memTypes = structDecl.getMemberTypes(simpleType); List members = structDecl.getMembers(simpleType); if (isArray(param)) { // An array - println("for(int i = 0; i < " + param + ".length; i++) {"); + println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".length; 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;"); + print("paramObj[pos++] = " + getSimpleIdentifier(param) + "[i]."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + println("}"); } else if (isList(paramType)) { // A list - println("for(int i = 0; i < " + param + ".size(); i++) {"); - } - if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".size(); 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;"); - print("paramObj[pos++] = " + param + "[i]."); + print("paramObj[pos++] = " + getSimpleIdentifier(param) + ".get(i)."); print(getSimpleIdentifier(members.get(i))); println(";"); } @@ -704,7 +766,7 @@ public class IoTCompiler { 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("paramObj[pos++] = " + getSimpleIdentifier(param) + "."); print(getSimpleIdentifier(members.get(i))); println(";"); } @@ -715,7 +777,7 @@ public class IoTCompiler { /** * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present */ - private void writeStructParamClassJavaStub(List methParams, List methPrmTypes) { + private void writeStructParamClassJavaStub(List methParams, List methPrmTypes, String callbackType) { print("int paramLen = "); writeLengthStructParamClassJavaStub(methParams, methPrmTypes); @@ -730,6 +792,16 @@ public class IoTCompiler { String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { writeStructMembersJavaStub(simpleType, paramType, param); + } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object + println("paramCls[pos] = int.class;"); + print("paramObj[pos++] = "); + if (isArray(methParams.get(i))) + print(getSimpleIdentifier(methParams.get(i)) + ".length"); + else if (isList(methPrmTypes.get(i))) + print(getSimpleIdentifier(methParams.get(i)) + ".size()"); + else + print("new Integer(1)"); + println(";"); } else { String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;"); @@ -832,7 +904,7 @@ public class IoTCompiler { * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class */ private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method) { + List methPrmTypes, String method, String callbackType) { checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); @@ -841,12 +913,17 @@ public class IoTCompiler { checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes); // Generate array of parameter types if (isStructPresent(methParams, methPrmTypes)) { - writeStructParamClassJavaStub(methParams, methPrmTypes); + writeStructParamClassJavaStub(methParams, methPrmTypes, callbackType); } 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"); + String prmType = methPrmTypes.get(i); + if (checkCallbackType(prmType, callbackType)) { // Check if this has callback object + print("int.class"); + } else { // Generate normal classes if it's not a callback object + String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + print(getSimpleType(getEnumType(paramType)) + ".class"); + } // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -856,7 +933,17 @@ public class IoTCompiler { // 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)); + String paramType = methPrmTypes.get(i); + if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object + //if (isArray(methPrmTypes.get(i), methParams.get(i))) + if (isArray(methParams.get(i))) + print(getSimpleIdentifier(methParams.get(i)) + ".length"); + else if (isList(methPrmTypes.get(i))) + print(getSimpleIdentifier(methParams.get(i)) + ".size()"); + else + print("new Integer(1)"); + } else + print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -872,16 +959,16 @@ public class IoTCompiler { if (isStructClass(getGenericType(getSimpleArrayType(retType)))) { writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType); } else { - // 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;"); - } else if (getParamCategory(retType) == ParamCategory.ENUM) { // 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;"); @@ -897,7 +984,7 @@ public class IoTCompiler { private String returnGenericCallbackType(String paramType) { if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) - return getTypeOfGeneric(paramType)[0]; + return getGenericType(paramType); else return paramType; } @@ -909,7 +996,10 @@ public class IoTCompiler { private boolean checkCallbackType(String paramType, String callbackType) { String prmType = returnGenericCallbackType(paramType); - return callbackType.equals(prmType); + if (callbackType == null) // If there is no callbackType it means not a callback method + return false; + else + return callbackType.equals(prmType); } @@ -926,78 +1016,30 @@ public class IoTCompiler { 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++);"); + println("for (" + getGenericType(paramType) + " cb : " + getSimpleIdentifier(param) + ") {"); + println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, callbackAddress, objIdCnt++);"); } else - println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(" + - getSimpleIdentifier(param) + ", objIdCnt++);"); - println("listCallbackObj.add(skel);"); + println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(" + + getSimpleIdentifier(param) + ", callbackAddress, objIdCnt++);"); + println("listCallbackObj.add(skel" + i + ");"); if (isArrayOrList(paramType, param)) 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(getEnumType(retType)) + ".class;"); - // Generate array of parameter types - print("Class[] paramCls = new Class[] { "); - 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.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"); - } - if (i != methParams.size() - 1) // Check if this is the last element - print(", "); - } - println(" };"); - // Generate array of parameter objects - print("Object[] paramObj = new Object[] { "); - for (int i = 0; i < methParams.size(); i++) { - String paramType = methPrmTypes.get(i); - if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - //if (isArray(methPrmTypes.get(i), methParams.get(i))) - if (isArray(methParams.get(i))) - print(getSimpleIdentifier(methParams.get(i)) + ".length"); - else if (isList(methPrmTypes.get(i))) - print(getSimpleIdentifier(methParams.get(i)) + ".size()"); - else - print("new Integer(1)"); - } else - print(getSimpleIdentifier(methParams.get(i))); - if (i != methParams.size() - 1) - print(", "); - } - println(" };"); - // Check if this is "void" - if (retType.equals("void")) { - println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); - } else { // We do have a return value - // 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;"); - } else { - println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);"); - println("return (" + retType + ")retObj;"); - } - } } /** * HELPER: writeMethodJavaStub() writes the methods of the stub class */ - private void writeMethodJavaStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { + private void writeMethodJavaStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses, String newStubClass) { + boolean isDefined = false; for (String method : methods) { List methParams = intDecl.getMethodParams(method); @@ -1025,16 +1067,27 @@ public class IoTCompiler { // Now, write the body of stub! if (isCallbackMethod) writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType); - else - writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method); + //else + writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType); println("}\n"); // Write the init callback helper method - if (isCallbackMethod) - writeInitCallbackJavaStub(callbackType, intDecl); + if (isCallbackMethod && !isDefined) { + writeInitCallbackJavaStub(callbackType, intDecl, newStubClass); + isDefined = true; + } } } + /** + * HELPER: getStubInterface() gets stub interface name based on original interface + */ + public String getStubInterface(String intface) { + + return mapInt2NewIntName.get(intface); + } + + /** * generateJavaStubClasses() generate stubs based on the methods list in Java */ @@ -1070,7 +1123,7 @@ public class IoTCompiler { // Write constructor writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses); // Write methods - writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses); + writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass); println("}"); pw.close(); System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java..."); @@ -1085,10 +1138,10 @@ public class IoTCompiler { private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set callbackClasses) { println("private IoTRMICall rmiCall;"); - println("private String address;"); + println("private String callbackAddress;"); println("private int[] ports;\n"); // Get the object Id - println("private static int objectId = 0;"); + println("private int objectId = 0;"); if (callbackExist) { // We assume that each class only has one callback interface for now Iterator it = callbackClasses.iterator(); @@ -1112,16 +1165,20 @@ public class IoTCompiler { private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set callbackClasses) { // TODO: If we want callback in callback, then we need to add address and port initializations - println("public " + newStubClass + "(IoTRMICall _rmiCall, int _objectId) throws Exception {"); + println("public " + newStubClass + "(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {"); + println("callbackAddress = _callbackAddress;"); println("objectId = _objectId;"); println("rmiCall = _rmiCall;"); + println("ports = _ports;"); if (callbackExist) { Iterator it = callbackClasses.iterator(); String callbackType = (String) it.next(); - writeConstructorJavaPermission(intface); + writeConstructorJavaPermission(callbackType); println("listCallbackObj = new ArrayList<" + callbackType + ">();"); + DeclarationHandler decHandler = mapIntDeclHand.get(callbackType); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType); + writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist); println("___initCallBack();"); - println("// TODO: Add address and port initialization here if we want callback in callback!"); } println("}\n"); } @@ -1167,7 +1224,7 @@ public class IoTCompiler { writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses); // Write methods // TODO: perhaps need to generate callback for callback - writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses); + writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass); println("}"); pw.close(); System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java..."); @@ -1184,26 +1241,62 @@ public class IoTCompiler { println("private " + intface + " mainObj;"); //println("private int ports;"); println("private IoTRMIObject rmiObj;\n"); + println("private String callbackAddress;"); // Callback if (callbackExist) { println("private static int objIdCnt = 0;"); println("private IoTRMICall rmiCall;"); + println("private int[] ports;\n"); } writePropertiesJavaPermission(intface, intDecl); println("\n"); } + /** + * 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 = getGenericType(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("public " + newSkelClass + "(" + intface + " _mainObj, String _callbackAddress, int _port) throws Exception {"); println("mainObj = _mainObj;"); + println("callbackAddress = _callbackAddress;"); println("rmiObj = new IoTRMIObject(_port);"); // Generate permission control initialization writeConstructorJavaPermission(intface); + writeJavaInitCallbackPermission(intface, intDecl, callbackExist); + writeStructPermissionJavaSkeleton(methods, intDecl, intface); println("___waitRequestInvokeMethod();"); println("}\n"); } @@ -1233,16 +1326,23 @@ public class IoTCompiler { /** * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class */ - private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) { + private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton, String intface) { // This is a callback skeleton generation if (callbackSkeleton) println("public void ___regCB(IoTRMIObject rmiObj) throws IOException {"); else println("public void ___regCB() throws IOException {"); - println("Object[] paramObj = rmiObj.getMethodParams(new Class[] { int.class, String.class, int.class },"); - println("\tnew Class[] { null, null, null });"); - println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], (int) paramObj[2]);"); + print("Object[] paramObj = rmiObj.getMethodParams(new Class[] { int[].class, String.class, int.class },"); + println("new Class[] { null, null, null });"); + println("ports = (int[]) paramObj[0];"); + String stubInt = null; + if (callbackSkeleton) + stubInt = getStubInterface(intface) + "_CallbackStub"; + else + stubInt = getStubInterface(intface) + "_Stub"; + int port = getPortCount(stubInt); + println("rmiCall = new IoTRMICall(ports[" + port + "], (String) paramObj[1], (int) paramObj[2]);"); println("}\n"); } @@ -1251,8 +1351,9 @@ public class IoTCompiler { * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class */ private void writeMethodJavaSkeleton(Collection methods, InterfaceDecl intDecl, Set callbackClasses, - boolean callbackSkeleton) { + boolean callbackSkeleton, String intface) { + boolean isDefined = false; for (String method : methods) { List methParams = intDecl.getMethodParams(method); @@ -1279,8 +1380,10 @@ public class IoTCompiler { // Now, write the body of skeleton! writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method)); println("}\n"); - if (isCallbackMethod) - writeInitCallbackJavaSkeleton(callbackSkeleton); + if (isCallbackMethod && !isDefined) { // Make sure that this function is only defined once! + writeInitCallbackJavaSkeleton(callbackSkeleton, intface); + isDefined = true; + } } } @@ -1289,40 +1392,41 @@ public class IoTCompiler { * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part */ private Map writeCallbackJavaStubGeneration(List methParams, List methPrmTypes, - String callbackType) { + String callbackType, boolean isStructMethod) { Map mapStubParam = new HashMap(); + String offsetPfx = ""; + if (isStructMethod) + offsetPfx = "offset"; // Iterate over callback objects for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - //if (callbackType.equals(paramType)) { if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - println("try {"); - String exchParamType = checkAndGetParamClass(paramType); + String exchParamType = checkAndGetParamClass(getGenericType(paramType)); // Print array if this is array or list if this is a list of callback objects if (isArray(param)) { - println("int numStubs" + i + " = (int) paramObj[" + i + "];"); + println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];"); println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];"); } else if (isList(paramType)) { - println("int numStubs" + i + " = (int) paramObj[" + i + "];"); + println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];"); println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();"); } else { - println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); + println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);"); println("objIdCnt++;"); } } // Generate a loop if needed if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - String exchParamType = checkAndGetParamClass(paramType); + String exchParamType = checkAndGetParamClass(getGenericType(paramType)); if (isArray(param)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); - println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); + println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);"); println("objIdCnt++;"); println("}"); } else if (isList(paramType)) { println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); - println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));"); + println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports));"); println("objIdCnt++;"); println("}"); } @@ -1336,28 +1440,35 @@ public class IoTCompiler { /** * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int) */ - private void checkAndWriteEnumTypeJavaSkeleton(List methParams, List methPrmTypes) { + private void checkAndWriteEnumTypeJavaSkeleton(List methParams, List methPrmTypes, boolean isStructMethod) { + String offsetPfx = ""; + if (isStructMethod) + offsetPfx = "offset"; // Iterate and find enum declarations + boolean printed = false; for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + 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();"); + println("int paramInt" + i + "[] = (int[]) paramObj[" + offsetPfx + i + "];"); + if (!printed) { + println(simpleType + "[] enumVals = " + simpleType + ".values();"); + printed = true; + } if (isArray(param)) { // An array println("int len" + i + " = paramInt" + i + ".length;"); - println(simpleType + "[] paramEnum = new " + simpleType + "[len];"); + println(simpleType + "[] paramEnum" + i + " = new " + simpleType + "[len" + i + "];"); println("for (int i = 0; i < len" + i + "; i++) {"); - println("paramEnum[i] = enumVals[paramInt" + 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 = new ArrayList<" + simpleType + ">();"); + println("List<" + simpleType + "> paramEnum" + i + " = new ArrayList<" + simpleType + ">();"); println("for (int i = 0; i < len" + i + "; i++) {"); - println("paramEnum.add(enumVals[paramInt" + i + "[i]]);"); + println("paramEnum" + i + ".add(enumVals[paramInt" + i + "[i]]);"); println("}"); } else { // Just one element println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];"); @@ -1373,10 +1484,10 @@ public class IoTCompiler { private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) { // Strips off array "[]" for return type - String pureType = getSimpleArrayType(getSimpleType(retType)); + String pureType = getSimpleArrayType(getGenericType(retType)); // Take the inner type of generic if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(retType)[0]; + pureType = getGenericType(retType); if (isEnumClass(pureType)) { // Check if this is enum type // Enum decoder @@ -1397,10 +1508,10 @@ public class IoTCompiler { private void checkAndWriteEnumRetConvJavaSkeleton(String retType) { // Strips off array "[]" for return type - String pureType = getSimpleArrayType(getSimpleType(retType)); + String pureType = getSimpleArrayType(getGenericType(retType)); // Take the inner type of generic if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(retType)[0]; + pureType = getGenericType(retType); if (isEnumClass(pureType)) { // Check if this is enum type if (isArray(retType)) { // An array @@ -1411,9 +1522,9 @@ public class IoTCompiler { println("}"); } else if (isList(retType)) { // A list println("int retLen = retEnum.size();"); - println("List<" + pureType + "> retEnumVal = new ArrayList<" + pureType + ">();"); + println("int[] retEnumVal = new int[retLen];"); println("for (int i = 0; i < retLen; i++) {"); - println("retEnumVal.add(retEnum[i].ordinal());"); + println("retEnumVal[i] = retEnum.get(i).ordinal();"); println("}"); } else { // Just one element println("int[] retEnumVal = new int[1];"); @@ -1459,14 +1570,12 @@ public class IoTCompiler { StructDecl structDecl = getStructDecl(simpleType); List memTypes = structDecl.getMemberTypes(simpleType); List members = structDecl.getMembers(simpleType); - if (isArrayOrList(param, paramType)) { // An array or list + if (isArrayOrList(paramType, param)) { // 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++) {"); + if (isArrayOrList(paramType, param)) { // 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;"); @@ -1489,6 +1598,7 @@ public class IoTCompiler { private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List methParams, List methPrmTypes, String method) { + println("int objPos = 0;"); for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); @@ -1506,12 +1616,11 @@ public class IoTCompiler { 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 + if (isArrayOrList(paramType, param)) { // An array or list println("for(int i = 0; i < " + counter + "; i++) {"); } if (isArray(param)) { // An array @@ -1539,7 +1648,7 @@ public class IoTCompiler { } } else { // Take offsets of parameters - println("int offset" + i +" = objPos;"); + println("int offset" + i +" = objPos++;"); } } } @@ -1567,7 +1676,7 @@ public class IoTCompiler { StructDecl structDecl = getStructDecl(simpleType); List memTypes = structDecl.getMemberTypes(simpleType); List members = structDecl.getMembers(simpleType); - if (isArrayOrList(retType, retType)) { // An array or list + if (isArray(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)); @@ -1577,6 +1686,16 @@ public class IoTCompiler { println(";"); } println("}"); + } else if (isList(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.get(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)); @@ -1597,31 +1716,34 @@ public class IoTCompiler { List methPrmTypes, String method, boolean isCallbackMethod, String callbackType, boolean isStructMethod) { - checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes); + checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes, isStructMethod); Map mapStubParam = null; - if (isCallbackMethod) - mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType); + if (isCallbackMethod) { + println("try {"); + mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType, isStructMethod); + } // Check if this is "void" String retType = intDecl.getMethodType(method); if (retType.equals("void")) { print(intDecl.getMethodId(method) + "("); - } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type + } else if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method)); - } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type + } 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) + "("); } for (int i = 0; i < methParams.size(); i++) { - if (isCallbackMethod) { + String paramType = methPrmTypes.get(i); + if (isCallbackMethod && checkCallbackType(paramType, callbackType)) { print(mapStubParam.get(i)); // Get the callback parameter - } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class - print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i)); - } else if (isStructClass(getSimpleType(methPrmTypes.get(i)))) { + } else if (isEnumClass(getGenericType(paramType))) { // Enum class + print(getEnumParam(paramType, methParams.get(i), i)); + } else if (isStructClass(getGenericType(paramType))) { print("paramStruct" + i); } else { - String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); + String prmType = checkAndGetArray(paramType, methParams.get(i)); if (isStructMethod) print("(" + prmType + ") paramObj[offset" + i + "]"); else @@ -1632,17 +1754,18 @@ public class IoTCompiler { } println(");"); if (!retType.equals("void")) { - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type checkAndWriteEnumRetConvJavaSkeleton(retType); println("rmiObj.sendReturnObj(retObj);"); - } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type - writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); + } 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("}"); @@ -1664,6 +1787,7 @@ public class IoTCompiler { println(";"); println("Class[] paramCls = new Class[paramLen];"); println("Class[] paramClsGen = 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); @@ -1726,8 +1850,10 @@ public class IoTCompiler { 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"); + if ((getParamCategory(prmType) == ParamCategory.NONPRIMITIVES) && + !isEnumClass(getGenericType(prmType)) && + !callbackClasses.contains(getGenericType(prmType))) + print(getGenericType(prmType) + ".class"); else print("null"); if (i != methParams.size() - 1) @@ -1764,11 +1890,12 @@ public class IoTCompiler { 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); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { - if (!begin) { // Generate comma for not the beginning variable - print(", "); begin = false; - } + if (!begin) // Generate comma for not the beginning variable + print(", "); + else + begin = false; int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } @@ -1819,7 +1946,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("public int ___"); @@ -1850,7 +1977,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("public int ___"); @@ -1880,7 +2007,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); println("int struct" + methodNumId + "Size" + i + " = 0;"); @@ -1898,17 +2025,18 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); boolean structExist = false; + boolean begin = true; // 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; + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { structExist = true; - if (!begin) { - print(", "); begin = false; - } + if (!begin) + print(", "); + else + begin = false; int methodNumId = intDecl.getMethodNumId(method); print("struct" + methodNumId + "Size" + i); } @@ -1931,7 +2059,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("case "); @@ -1960,7 +2088,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("case "); @@ -1984,7 +2112,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 (_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);"); @@ -2072,9 +2200,9 @@ 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); + writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false, intface); // Write method helper writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses); // Write waitRequestInvokeMethod() - main loop @@ -2093,11 +2221,14 @@ public class IoTCompiler { println("private " + intface + " mainObj;"); // For callback skeletons, this is its own object Id - println("private static int objectId = 0;"); + println("private int objectId = 0;"); + println("private String callbackAddress;"); // Callback if (callbackExist) { + println("private static int objIdCnt = 0;"); println("private IoTRMICall rmiCall;"); + println("private int[] ports;\n"); } println("\n"); } @@ -2106,9 +2237,10 @@ 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("public " + newSkelClass + "(" + intface + " _mainObj, String _callbackAddress, int _objectId) throws Exception {"); + println("callbackAddress = _callbackAddress;"); println("mainObj = _mainObj;"); println("objectId = _objectId;"); println("}\n"); @@ -2140,11 +2272,12 @@ public class IoTCompiler { 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); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { - if (!begin) { // Generate comma for not the beginning variable - print(", "); begin = false; - } + if (!begin) // Generate comma for not the beginning variable + print(", "); + else + begin = false; int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } @@ -2253,9 +2386,9 @@ 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); + writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true, intface); // Write method helper writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses); // Write waitRequestInvokeMethod() - main loop @@ -2386,6 +2519,7 @@ public class IoTCompiler { // 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); @@ -2470,8 +2604,10 @@ public class IoTCompiler { println("#ifndef _" + newIntface.toUpperCase() + "_HPP__"); println("#define _" + newIntface.toUpperCase() + "_HPP__"); println("#include "); + updateIntfaceObjIdMap(intface, newIntface); // Pass in set of methods and get import classes - Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false); + Set methods = intMeth.getValue(); + Set includeClasses = getIncludeClasses(methods, intDecl, intface, false); List stdIncludeClasses = getStandardCplusIncludeClasses(); List allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses); printIncludeStatements(allIncludeClasses); println(""); @@ -2480,7 +2616,7 @@ public class IoTCompiler { println("{"); println("public:"); // Write methods - writeMethodCplusInterface(intMeth.getValue(), intDecl); + writeMethodCplusInterface(methods, intDecl); println("};"); println("#endif"); pw.close(); @@ -2493,22 +2629,20 @@ public class IoTCompiler { /** * HELPER: writeMethodCplusStub() writes the methods of the stub */ - private void writeMethodCplusStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses) { + private void writeMethodCplusStub(Collection methods, InterfaceDecl intDecl, Set callbackClasses, String newStubClass) { + boolean isDefined = false; for (String method : methods) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - - //System.out.println("\n\nMethod return type: " + checkAndGetCplusType(intDecl.getMethodType(method)) + "\n\n"); - print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " + intDecl.getMethodId(method) + "("); boolean isCallbackMethod = false; String callbackType = null; for (int i = 0; i < methParams.size(); i++) { - String paramType = methPrmTypes.get(i); + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); // Check if this has callback object if (callbackClasses.contains(paramType)) { isCallbackMethod = true; @@ -2526,13 +2660,13 @@ public class IoTCompiler { println(") { "); if (isCallbackMethod) writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType); - else - writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method); + writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType, isCallbackMethod); println("}\n"); // Write the init callback helper method - if (isCallbackMethod) { - writeInitCallbackCplusStub(callbackType, intDecl); + if (isCallbackMethod && !isDefined) { + writeInitCallbackCplusStub(callbackType, intDecl, newStubClass); writeInitCallbackSendInfoCplusStub(intDecl); + isDefined = true; } } } @@ -2553,71 +2687,23 @@ public class IoTCompiler { 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++);"); + println("for (" + getGenericType(paramType) + "* cb : " + getSimpleIdentifier(param) + ") {"); + println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, callbackAddress, 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(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(" + + getSimpleIdentifier(param) + ", callbackAddress, objIdCnt++);"); + println("vecCallbackObj.push_back(skel" + i + ");"); + if (isArrayOrList) println("}"); + print("int ___paramCB" + i + " = "); + if (isArrayOrList) + println(callbackParam + ".size();"); + else + println("1;"); } } - 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 = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - //String prmType = getSimpleType(getEnumType(paramTypeC)); - String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); - String prmType = getEnumType(paramTypeC); - print("\"" + prmType + "\""); - } - if (i != methParams.size() - 1) // Check if this is the last element - 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;"); - } } @@ -2630,14 +2716,13 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); - if (isEnumClass(simpleType)) { + if (isEnumClass(getGenericType(paramType))) { // Check if this is enum type if (isArrayOrList(paramType, param)) { // An array or vector - println("int len" + i + " = " + param + ".size();"); - println("vector paramEnum" + i + "(len);"); + 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) " + param + "[i];"); + println("paramEnum" + i + "[i] = (int) " + getSimpleIdentifier(param) + "[i];"); println("}"); } else { // Just one element println("vector paramEnum" + i + "(1);"); @@ -2654,10 +2739,10 @@ public class IoTCompiler { private void checkAndWriteEnumRetTypeCplusStub(String retType) { // Strips off array "[]" for return type - String pureType = getSimpleArrayType(getSimpleType(retType)); + String pureType = getSimpleArrayType(getGenericType(retType)); // Take the inner type of generic if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(retType)[0]; + pureType = getGenericType(retType); if (isEnumClass(pureType)) { // Check if this is enum type println("vector retEnumInt;"); @@ -2687,7 +2772,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { // Check if this is enum type println("int numParam" + i + " = 1;"); @@ -2697,7 +2782,7 @@ public class IoTCompiler { println("string retTypeStruct" + i + " = \"void\";"); println("string paramClsStruct" + i + "[] = { \"int\" };"); print("int structLen" + i + " = "); - if (isArrayOrList(param, paramType)) { // An array + if (isArrayOrList(paramType, param)) { // An array println(getSimpleArrayType(param) + ".size();"); } else { // Just one element println("1;"); @@ -2724,8 +2809,8 @@ public class IoTCompiler { String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int members = getNumOfMembers(simpleType); - if (isArrayOrList(param, paramType)) { // An array - String structLen = param + ".size()"; + if (isArrayOrList(paramType, param)) { // An array or list + String structLen = getSimpleIdentifier(param) + ".size()"; print(members + "*" + structLen); } else print(Integer.toString(members)); @@ -2747,24 +2832,22 @@ public class IoTCompiler { 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(paramType, param)) { // An array or list + println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".size(); i++) {"); } - if (isArrayOrList(param, paramType)) { // An array or list + if (isArrayOrList(paramType, param)) { // An array or list for (int i = 0; i < members.size(); i++) { - String prmTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); - print("paramObj[pos++] = &" + param + "[i]."); + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + print("paramObj[pos++] = &" + getSimpleIdentifier(param) + "[i]."); print(getSimpleIdentifier(members.get(i))); println(";"); } println("}"); } else { // Just one struct element for (int i = 0; i < members.size(); i++) { - String prmTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); print("paramObj[pos++] = &" + param + "."); print(getSimpleIdentifier(members.get(i))); println(";"); @@ -2776,7 +2859,7 @@ public class IoTCompiler { /** * HELPER: writeStructParamClassCplusStub() writes member parameters of struct */ - private void writeStructParamClassCplusStub(List methParams, List methPrmTypes) { + private void writeStructParamClassCplusStub(List methParams, List methPrmTypes, String callbackType) { print("int numParam = "); writeLengthStructParamClassCplusStub(methParams, methPrmTypes); @@ -2791,10 +2874,12 @@ public class IoTCompiler { String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { writeStructMembersCplusStub(simpleType, paramType, param); + } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object + println("paramCls[pos] = \"int\";"); + println("paramObj[pos++] = &___paramCB" + i + ";"); } else { - String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i)); - println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + 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(";"); @@ -2870,17 +2955,15 @@ public class IoTCompiler { if (isArrayOrList(retType, retType)) { // An array or list println("for(int i = 0; i < retLen; i++) {"); for (int i = 0; i < members.size(); i++) { - String prmTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + 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 = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("retCls[retPos] = \"" + prmTypeC + "\";"); println("retObj[retPos++] = &retParam" + i + ";"); } } @@ -2897,37 +2980,41 @@ public class IoTCompiler { * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class */ private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, - List methPrmTypes, String method) { + List methPrmTypes, String method, String callbackType, boolean isCallbackMethod) { checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); - //String retTypeC = checkAndGetCplusType(retType); - //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";"); println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";"); + checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); // Generate array of parameter types if (isStructPresent(methParams, methPrmTypes)) { - writeStructParamClassCplusStub(methParams, methPrmTypes); + writeStructParamClassCplusStub(methParams, methPrmTypes, callbackType); } else { println("int numParam = " + methParams.size() + ";"); print("string paramCls[] = { "); for (int i = 0; i < methParams.size(); i++) { - //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - //String prmType = getSimpleType(getEnumType(paramTypeC)); - String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); - String prmType = getEnumType(paramTypeC); - print("\"" + prmType + "\""); + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (checkCallbackType(paramType, callbackType)) { + print("\"int\""); + } else { + 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(" };"); - 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)); + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (checkCallbackType(paramType, callbackType)) // Check if this has callback object + print("&___paramCB" + i); + else + print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -2945,7 +3032,7 @@ public class IoTCompiler { writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType); } else { // Check if the return value NONPRIMITIVES - if (getParamCategory(retType) == ParamCategory.ENUM) { + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { checkAndWriteEnumRetTypeCplusStub(retType); } else { //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) @@ -2971,9 +3058,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;"); } } @@ -2983,14 +3070,11 @@ public class IoTCompiler { private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set callbackClasses) { println("IoTRMICall *rmiCall;"); - //println("IoTRMIObject\t\t\t*rmiObj;"); - println("string address;"); + println("string callbackAddress;"); println("vector ports;\n"); // Get the object Id Integer objId = mapIntfaceObjId.get(intface); println("const static int objectId = " + objId + ";"); - mapNewIntfaceObjId.put(newIntface, objId); - mapIntfaceObjId.put(intface, objId++); if (callbackExist) { // We assume that each class only has one callback interface for now Iterator it = callbackClasses.iterator(); @@ -3012,14 +3096,16 @@ public class IoTCompiler { private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set callbackClasses) { println(newStubClass + - "(int _port, const char* _address, int _rev, bool* _bResult, vector _ports) {"); - println("address = _address;"); + "(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector _ports) {"); + println("callbackAddress = _callbackAddress;"); println("ports = _ports;"); - println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);"); + println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev, _bResult);"); if (callbackExist) { - println("objIdCnt = 0;"); Iterator it = callbackClasses.iterator(); String callbackType = (String) it.next(); + DeclarationHandler decHandler = mapIntDeclHand.get(callbackType); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType); + writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist); println("thread th1 (&" + newStubClass + "::___initCallBack, this);"); println("th1.detach();"); println("___regCB();"); @@ -3066,10 +3152,10 @@ 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);"); + println("return;"); println("}"); } } @@ -3078,29 +3164,50 @@ public class IoTCompiler { /** * HELPER: writeInitCallbackCplusStub() writes the initialization of callback */ - private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) { + private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl, String newStubClass) { println("void ___initCallBack() {"); println("bool bResult = false;"); - println("rmiObj = new IoTRMIObject(ports[0], &bResult);"); + int port = getPortCount(newStubClass); + println("rmiObj = new IoTRMIObject(ports[" + port + "], &bResult);"); println("while (true) {"); println("char* method = rmiObj->getMethodBytes();"); - writeCplusMethodCallbackPermission(intface); + //writeCplusMethodCallbackPermission(intface); println("int objId = IoTRMIObject::getObjectId(method);"); println("if (objId < vecCallbackObj.size()) { // Check if still within range"); println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface + "_CallbackSkeleton*> (vecCallbackObj.at(objId));"); + writeCplusMethodCallbackPermission(intface); 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);"); + println("return;"); println("}"); println("}"); println("}\n"); } + /** + * 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 */ @@ -3110,11 +3217,12 @@ 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 + ";"); println("string retType = \"void\";"); - println("string paramCls[] = { \"int\", \"string\", \"int\" };"); + println("string paramCls[] = { \"int*\", \"String\", \"int\" };"); println("int rev = 0;"); - println("void* paramObj[] = { &ports[0], &address, &rev };"); + println("void* paramObj[] = { &ports, &callbackAddress, &rev };"); println("void* retObj = NULL;"); println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); println("}\n"); @@ -3160,10 +3268,17 @@ public class IoTCompiler { writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses); writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses); // Write methods - writeMethodCplusStub(methods, intDecl, callbackClasses); + writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass); print("}"); println(";"); - if (callbackExist) - writePermissionInitializationCplus(intface, newStubClass, intDecl); + if (callbackExist) { + Iterator it = callbackClasses.iterator(); + String callbackType = (String) it.next(); + // Generate permission stuff for callback stubs + DeclarationHandler decHandlerCallback = mapIntDeclHand.get(callbackType); + InterfaceDecl intDeclCallback = (InterfaceDecl) decHandlerCallback.getInterfaceDecl(callbackType); + writePermissionInitializationCplus(callbackType, newStubClass, intDeclCallback); + } + writeObjectIdCountInitializationCplus(newStubClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp..."); @@ -3179,7 +3294,9 @@ public class IoTCompiler { println("IoTRMICall *rmiCall;"); // Get the object Id - println("static int objectId;"); + println("int objectId;"); + println("vector ports;\n"); + println("string callbackAddress;"); if (callbackExist) { // We assume that each class only has one callback interface for now Iterator it = callbackClasses.iterator(); @@ -3189,8 +3306,6 @@ public class IoTCompiler { println("vector<" + callbackType + "*> vecCallbackObj;"); println("static int objIdCnt;"); // TODO: Need to initialize address and ports if we want to have callback-in-callback - println("string address;"); - println("vector ports;\n"); writePropertiesCplusPermission(callbackType); } println("\n"); @@ -3202,12 +3317,17 @@ public class IoTCompiler { */ private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set callbackClasses) { - println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {"); + println(newStubClass + "(IoTRMICall* _rmiCall, string _callbackAddress, int _objectId, vector _ports) {"); println("objectId = _objectId;"); + println("callbackAddress = _callbackAddress;"); println("rmiCall = _rmiCall;"); + println("ports = _ports;"); if (callbackExist) { Iterator it = callbackClasses.iterator(); String callbackType = (String) it.next(); + DeclarationHandler decHandler = mapIntDeclHand.get(callbackType); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType); + writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist); println("thread th1 (&" + newStubClass + "::___initCallBack, this);"); println("th1.detach();"); println("___regCB();"); @@ -3255,10 +3375,17 @@ public class IoTCompiler { writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses); writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses); // Write methods - writeMethodCplusStub(methods, intDecl, callbackClasses); + writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass); println("};"); - if (callbackExist) - writePermissionInitializationCplus(intface, newStubClass, intDecl); + if (callbackExist) { + Iterator it = callbackClasses.iterator(); + String callbackType = (String) it.next(); + // Generate permission stuff for callback stubs + DeclarationHandler decHandlerCallback = mapIntDeclHand.get(callbackType); + InterfaceDecl intDeclCallback = (InterfaceDecl) decHandlerCallback.getInterfaceDecl(callbackType); + writePermissionInitializationCplus(callbackType, newStubClass, intDeclCallback); + } + writeObjectIdCountInitializationCplus(newStubClass, callbackExist); println("#endif"); pw.close(); System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp..."); @@ -3273,6 +3400,8 @@ public class IoTCompiler { private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set callbackClasses) { println(intface + " *mainObj;"); + println("vector ports;"); + println("string callbackAddress;"); // Callback if (callbackExist) { Iterator it = callbackClasses.iterator(); @@ -3290,6 +3419,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 */ @@ -3299,8 +3438,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) { @@ -3317,20 +3456,49 @@ 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 = getGenericType(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(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _port) {"); println("bool _bResult = false;"); println("mainObj = _mainObj;"); + println("callbackAddress = _callbackAddress;"); 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"); } @@ -3389,7 +3557,7 @@ public class IoTCompiler { /** * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class */ - private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) { + private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton, String intface) { // This is a callback skeleton generation if (callbackSkeleton) @@ -3397,12 +3565,20 @@ public class IoTCompiler { else println("void ___regCB() {"); println("int numParam = 3;"); - println("int param1 = 0;"); + println("vector param1;"); 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);"); + String stubInt = null; + if (callbackSkeleton) + stubInt = getStubInterface(intface) + "_CallbackStub"; + else + stubInt = getStubInterface(intface) + "_Stub"; + int port = getPortCount(stubInt); + println("rmiCall = new IoTRMICall(param1[" + port + "], param2.c_str(), param3, &bResult);"); println("}\n"); } @@ -3411,8 +3587,9 @@ public class IoTCompiler { * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class */ private void writeMethodCplusSkeleton(Collection methods, InterfaceDecl intDecl, - Set callbackClasses, boolean callbackSkeleton) { + Set callbackClasses, boolean callbackSkeleton, String intface) { + boolean isDefined = false; for (String method : methods) { List methParams = intDecl.getMethodParams(method); @@ -3442,8 +3619,10 @@ public class IoTCompiler { // Now, write the body of skeleton! writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method)); println("}\n"); - if (isCallbackMethod) - writeInitCallbackCplusSkeleton(callbackSkeleton); + if (isCallbackMethod && !isDefined) { + writeInitCallbackCplusSkeleton(callbackSkeleton, intface); + isDefined = true; + } } } @@ -3457,11 +3636,8 @@ public class IoTCompiler { String paramType = methPrmTypes.get(i); String param = methParams.get(i); //if (callbackType.equals(paramType)) { - if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - String exchParamType = checkAndGetParamClass(paramType); - // Print array if this is array or list if this is a list of callback objects + if (checkCallbackType(paramType, callbackType)) // Check if this has callback object println("int numStubs" + i + " = 0;"); - } } } @@ -3477,17 +3653,17 @@ public class IoTCompiler { String param = methParams.get(i); // Generate a loop if needed if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object - String exchParamType = checkAndGetParamClass(paramType); + String exchParamType = checkAndGetParamClass(getGenericType(paramType)); if (isArrayOrList(paramType, param)) { - println("vector<" + exchParamType + "> stub;"); + println("vector<" + exchParamType + "*> stub" + i + ";"); println("for (int objId = 0; objId < numStubs" + i + "; objId++) {"); - println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); - println("stub" + i + ".push_back(cb);"); - println("vecCallbackObj.push_back(cb);"); + println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);"); + println("stub" + i + ".push_back(cb" + i + ");"); + println("vecCallbackObj.push_back(cb" + i + ");"); println("objIdCnt++;"); println("}"); } else { - println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);"); + println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);"); println("vecCallbackObj.push_back(stub" + i + ");"); println("objIdCnt++;"); } @@ -3505,7 +3681,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isEnumClass(simpleType)) { // Check if this is enum type if (isArrayOrList(paramType, param)) { // An array @@ -3529,10 +3705,10 @@ public class IoTCompiler { private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) { // Strips off array "[]" for return type - String pureType = getSimpleArrayType(getSimpleType(retType)); + String pureType = getSimpleArrayType(getGenericType(retType)); // Take the inner type of generic if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(retType)[0]; + pureType = getGenericType(retType); if (isEnumClass(pureType)) { // Check if this is enum type // Enum decoder @@ -3551,7 +3727,7 @@ public class IoTCompiler { /** - * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton + * HELPER: writeMethodInputParameters() writes the parameter variables for C++ skeleton */ private void writeMethodInputParameters(List methParams, List methPrmTypes, Set callbackClasses, String methodId) { @@ -3561,9 +3737,9 @@ public class IoTCompiler { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(paramType)) print("stub" + i); - else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type print("paramEnum" + i); - else if (isStructClass(getSimpleType(paramType))) // Struct type + else if (isStructClass(getGenericType(paramType))) // Struct type print("paramStruct" + i); else print(getSimpleIdentifier(methParams.get(i))); @@ -3593,23 +3769,23 @@ public class IoTCompiler { if (retType.equals("void")) { writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId); } else { // We do have a return value - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type print(checkAndGetCplusType(retType) + " retEnum = "); - else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + 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(getSimpleType(retType)))) // Struct type - writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); - if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + 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(getSimpleType(retType)))) // Struct type + if (!isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type println("void* retObj = &retVal;"); String retTypeC = checkAndGetCplusType(retType); - if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);"); else println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");"); @@ -3634,11 +3810,8 @@ public class IoTCompiler { callbackType = paramType; print("\"int\""); } else { // Generate normal classes if it's not a callback object - //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); - //String prmType = getSimpleType(getEnumType(paramTypeC)); String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i)); - String prmType = getEnumType(paramTypeC); - print("\"" + prmType + "\""); + print("\"" + paramTypeC + "\""); } if (i != methParams.size() - 1) { print(", "); @@ -3652,10 +3825,12 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (!callbackClasses.contains(paramType)) { - String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); - if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type + 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 + ";"); } @@ -3667,7 +3842,7 @@ public class IoTCompiler { String paramType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(paramType)) print("&numStubs" + i); - else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type print("¶mEnumInt" + i); else print("&" + getSimpleIdentifier(methParams.get(i))); @@ -3694,39 +3869,35 @@ public class IoTCompiler { 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 + if (isArrayOrList(paramType, param)) { // 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 + "];"); + println(getSimpleType(getEnumType(prmType)) + " param" + iVar + 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(getSimpleType(getEnumType(prmType)) + " param" + iVar + i + ";"); } } - println("int pos = 0;"); - if (isArrayOrList(param, paramType)) { // An array or list - println("for(int i = 0; i < retLen; i++) {"); + if (isArrayOrList(paramType, param)) { // An array or list + println("for(int i = 0; i < " + counter + "; i++) {"); + } + if (isArrayOrList(paramType, param)) { // An array or list for (int i = 0; i < members.size(); i++) { - String prmTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); - println("paramObj[pos++] = ¶m" + i + "[i];"); + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + println("paramObj[pos++] = ¶m" + iVar + i + "[i];"); } println("}"); } else { // Just one struct element for (int i = 0; i < members.size(); i++) { - String prmTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); - println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); - println("paramObj[pos++] = ¶m" + i + ";"); + String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i)); + println("paramCls[pos] = \"" + prmTypeC + "\";"); + println("paramObj[pos++] = ¶m" + iVar + i + ";"); } } } @@ -3746,25 +3917,25 @@ public class IoTCompiler { 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 + ";"); + if (isArrayOrList(paramType, param)) { // An array or list + println("vector<" + simpleType + "> paramStruct" + i + "(" + counter + ");"); } 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 + if (isArrayOrList(paramType, param)) { // 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(" = param" + i + 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 + ";"); + println(" = param" + i + j + ";"); } } } @@ -3796,9 +3967,8 @@ public class IoTCompiler { if (isArrayOrList(retType, retType)) { // An array or list println("for(int i = 0; i < retLen; i++) {"); for (int i = 0; i < members.size(); i++) { - String paramTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); - println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + 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(";"); @@ -3806,9 +3976,8 @@ public class IoTCompiler { println("}"); } else { // Just one struct element for (int i = 0; i < members.size(); i++) { - String paramTypeC = checkAndGetCplusType(memTypes.get(i)); - String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); - println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + 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(";"); @@ -3832,6 +4001,7 @@ public class IoTCompiler { println(";"); println("string paramCls[numParam];"); println("void* paramObj[numParam];"); + println("int pos = 0;"); // Iterate again over the parameters for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); @@ -3843,22 +4013,22 @@ public class IoTCompiler { String prmType = returnGenericCallbackType(methPrmTypes.get(i)); if (callbackClasses.contains(prmType)) { isCallbackMethod = true; - callbackType = paramType; - writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType); + callbackType = prmType; + println("int numStubs" + i + " = 0;"); println("paramCls[pos] = \"int\";"); println("paramObj[pos++] = &numStubs" + i + ";"); } else { // Generate normal classes if it's not a callback object String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type + if (isEnumClass(getGenericType(paramTypeC))) { // Check if this is enum type println("vector paramEnumInt" + i + ";"); } else { String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i)); println(methParamComplete + ";"); } - println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";"); - if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type - println("paramObj[pos++] = ¶mEnumInt" + i); + 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)) + ";"); } @@ -3895,11 +4065,12 @@ public class IoTCompiler { 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); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { - if (!begin) { // Generate comma for not the beginning variable - print(", "); begin = false; - } + if (!begin) // Generate comma for not the beginning variable + print(", "); + else + begin = false; int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } @@ -3943,7 +4114,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("int ___"); @@ -3978,7 +4149,7 @@ public class IoTCompiler { for (int i = 0; i < methParams.size(); i++) { String paramType = methPrmTypes.get(i); String param = methParams.get(i); - String simpleType = getSimpleType(paramType); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { int methodNumId = intDecl.getMethodNumId(method); print("int ___"); @@ -4007,16 +4178,16 @@ 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("return;"); println("}"); println("}"); println("else {"); println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;"); - println("exit(-1);"); + println("return;"); println("}"); } } @@ -4105,17 +4276,18 @@ 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 - writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false); + writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false, intface); // Write method helper writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses); // Write waitRequestInvokeMethod() - main loop 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..."); @@ -4130,7 +4302,9 @@ 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;"); + println("vector ports;\n"); + println("string callbackAddress;"); // Callback if (callbackExist) { Iterator it = callbackClasses.iterator(); @@ -4148,15 +4322,12 @@ 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(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _objectId) {"); println("mainObj = _mainObj;"); + println("callbackAddress = _callbackAddress;"); println("objectId = _objectId;"); - // Callback - if (callbackExist) { - println("objIdCnt = 0;"); - } println("}\n"); } @@ -4213,11 +4384,12 @@ public class IoTCompiler { 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); + String simpleType = getGenericType(paramType); if (isStructClass(simpleType)) { - if (!begin) { // Generate comma for not the beginning variable - print(", "); begin = false; - } + if (!begin) // Generate comma for not the beginning variable + print(", "); + else + begin = false; int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } @@ -4328,16 +4500,17 @@ 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 - writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true); + writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true, intface); // Write method helper writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses); // 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..."); @@ -4420,7 +4593,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; @@ -4451,9 +4624,12 @@ 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; } @@ -4530,6 +4706,22 @@ public class IoTCompiler { } + // 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"); +// return -1; +// } else { + int retObjId = mapNewIntfaceObjId.get(newIntface); + return retObjId; +// } + } + + // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT private ParamCategory getParamCategory(String paramType) { @@ -4691,7 +4883,7 @@ public class IoTCompiler { String pureType = getSimpleArrayType(type); // Take the inner type of generic if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(type)[0]; + pureType = getGenericType(type); if (isEnumClass(pureType)) { String enumType = "int[]"; return enumType; @@ -4699,6 +4891,21 @@ public class IoTCompiler { 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) { @@ -4707,7 +4914,7 @@ public class IoTCompiler { String pureType = getSimpleArrayType(type); // Take the inner type of generic if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) - pureType = getTypeOfGeneric(type)[0]; + pureType = getGenericType(type); if (isStructClass(pureType)) { String structType = "int"; return structType; @@ -4915,14 +5122,14 @@ public class IoTCompiler { if (paramType.contains("<") && paramType.contains(">")) { String genericClass = getSimpleType(paramType); - String[] genericType = getTypeOfGeneric(paramType); + String genericType = getGenericType(paramType); String cplusTemplate = null; - if (genericType.length == 1) // Generic/template with one type - cplusTemplate = getNonPrimitiveCplusClass(genericClass) + - "<" + convertType(genericType[0]) + ">"; - else // Generic/template with two types - cplusTemplate = getNonPrimitiveCplusClass(genericClass) + - "<" + convertType(genericType[0]) + "," + convertType(genericType[1]) + ">"; + cplusTemplate = getNonPrimitiveCplusClass(genericClass); + if(getParamCategory(getGenericType(paramType)) == ParamCategory.USERDEFINED) { + cplusTemplate = cplusTemplate + "<" + genericType + "*>"; + } else { + cplusTemplate = cplusTemplate + "<" + convertType(genericType) + ">"; + } return cplusTemplate; } else return getNonPrimitiveCplusClass(paramType); @@ -4934,7 +5141,6 @@ public class IoTCompiler { } else // Just return it as is if it's not non-primitives return paramType; - //return checkAndGetParamClass(paramType, true); } @@ -5021,7 +5227,12 @@ public class IoTCompiler { // - Check and return C++ vector class, e.g. List A into vector private String checkAndGetCplusArgClsType(String paramType, String param) { - String paramTypeRet = null; + 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) + "*"; @@ -5094,6 +5305,9 @@ public class IoTCompiler { // Check if this is generics if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { return exchangeParamType(paramType); + } else if (isList(paramType) && + (getParamCategory(getGenericType(paramType)) == ParamCategory.USERDEFINED)) { + return "List<" + exchangeParamType(getGenericType(paramType)) + ">"; } else return paramType; } @@ -5117,7 +5331,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 @@ -5126,7 +5340,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"); } } @@ -5185,12 +5399,12 @@ public class IoTCompiler { // Error checking if (!args[i].equals("-java") && !args[i].equals("-cplus")) { - throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]); + throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i] + "\n"); } else { if (i + 1 < args.length) { comp.setDirectory(args[i+1]); } else - throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i]); + throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i] + "\n"); if (args[i].equals("-java")) { comp.generateEnumJava(); @@ -5218,7 +5432,7 @@ 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"); } } }