InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
List<String> methods = intDecl.getMethods();
Set<String> importClasses = getImportClasses(methods, intDecl);
- printImportStatements(importClasses);
+ List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
+ List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+ printImportStatements(allImportClasses);
// Write interface header
println("");
println("public interface " + intface + " {");
DeclarationHandler decHandler = mapIntDeclHand.get(intface);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
// Pass in set of methods and get import classes
- Set<String> importClasses = getImportClasses(intMeth.getValue(), intDecl);
- printImportStatements(importClasses);
+ List<String> methods = intDecl.getMethods();
+ Set<String> importClasses = getImportClasses(methods, intDecl);
+ List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
+ List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+ printImportStatements(allImportClasses);
// Write interface header
println("");
println("public interface " + newIntface + " {\n");
// Write methods
- writeMethodJavaInterface(intMeth.getValue(), intDecl);
+ writeMethodJavaInterface(methods, intDecl);
println("}");
pw.close();
System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> 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<String> methodIds = intMeth.getValue();
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
- int newObjectId = mapNewIntfaceObjId.get(newIntface);
+ int newObjectId = getNewIntfaceObjectId(newIntface);
println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
}
}
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> 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("}");
println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
println("if (skel != null) {");
println("skel.invokeMethod(rmiObj);");
- println("} else {");
+ print("}");
+ println(" else {");
println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
println("}");
println("}");
- println("} catch (Exception ex) {");
+ print("}");
+ println(" catch (Exception ex) {");
println("ex.printStackTrace();");
println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
println("}");
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("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("}");
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> 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);");
List<String> methParams = intDecl.getMethodParams(method);
List<String> 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;
println("int numParam = " + methParams.size() + ";");
println("int methodId = " + intDecl.getMethodNumId(method) + ";");
String retType = intDecl.getMethodType(method);
- String retTypeC = checkAndGetCplusType(retType);
- println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
+ //String retTypeC = checkAndGetCplusType(retType);
+ //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
+ println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
// Generate array of parameter types
print("string paramCls[] = { ");
for (int i = 0; i < methParams.size(); i++) {
if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
print("\"int\"");
} else { // Generate normal classes if it's not a callback object
- String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
- String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
+ //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+ //String prmType = getSimpleType(getEnumType(paramTypeC));
+ String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ String prmType = getEnumType(paramTypeC);
print("\"" + prmType + "\"");
}
if (i != methParams.size() - 1) // Check if this is the last element
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))) + "\";");
+ //String retTypeC = checkAndGetCplusType(retType);
+ //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
+ println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
// Generate array of parameter types
if (isStructPresent(methParams, methPrmTypes)) {
writeStructParamClassCplusStub(methParams, methPrmTypes);
println("int numParam = " + methParams.size() + ";");
print("string paramCls[] = { ");
for (int i = 0; i < methParams.size(); i++) {
- String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
- String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
- print("\"" + getEnumType(paramType) + "\"");
+ //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+ //String prmType = getSimpleType(getEnumType(paramTypeC));
+ String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ String prmType = getEnumType(paramTypeC);
+ print("\"" + prmType + "\"");
// Check if this is the last element (don't print a comma)
if (i != methParams.size() - 1) {
print(", ");
if (getParamCategory(retType) == ParamCategory.ENUM) {
checkAndWriteEnumRetTypeCplusStub(retType);
} else {
- if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+ //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+ if (isArrayOrList(retType,retType))
println(checkAndGetCplusType(retType) + " retVal;");
- else
+ else {
println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
+ }
println("void* retObj = &retVal;");
println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
println("return retVal;");
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
- int newObjectId = mapNewIntfaceObjId.get(newIntface);
- println("const static int object" + newObjectId + "Id = " + newObjectId + ";");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface);
println("const static set<int> set" + newObjectId + "Allowed;");
}
}
println("ports = _ports;");
println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
if (callbackExist) {
- println("objIdCnt = 0;");
Iterator it = callbackClasses.iterator();
String callbackType = (String) it.next();
println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> 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(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface +
"_CallbackSkeleton*> (vecCallbackObj.at(objId));");
println("skel->invokeMethod(rmiObj);");
- println("} else {");
+ print("}");
+ println(" else {");
println("cerr << \"Illegal object Id: \" << to_string(objId);");
// TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
println("exit(-1);");
print("}"); println(";");
if (callbackExist)
writePermissionInitializationCplus(intface, newStubClass, intDecl);
+ writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
println("#endif");
pw.close();
System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
println("IoTRMICall *rmiCall;");
// Get the object Id
- println("static int objectId;");
+ println("int objectId;");
if (callbackExist) {
// We assume that each class only has one callback interface for now
Iterator it = callbackClasses.iterator();
println("};");
if (callbackExist)
writePermissionInitializationCplus(intface, newStubClass, intDecl);
+ writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
println("#endif");
pw.close();
System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
}
+ /**
+ * 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
*/
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
- int newObjectId = mapNewIntfaceObjId.get(newIntface);
+ int newObjectId = getNewIntfaceObjectId(newIntface);
print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
Set<String> methodIds = intMeth.getValue();
int i = 0;
println("bool _bResult = false;");
println("mainObj = _mainObj;");
println("rmiObj = new IoTRMIObject(_port, &_bResult);");
- // Callback
- if (callbackExist) {
- println("objIdCnt = 0;");
- }
- //println("set0Allowed = Arrays.asList(object0Permission);");
println("___waitRequestInvokeMethod();");
println("}\n");
}
println("int param1 = 0;");
println("string param2 = \"\";");
println("int param3 = 0;");
+ println("string paramCls[] = { \"int\", \"string\", \"int\" };");
println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
+ println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
println("bool bResult = false;");
println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
println("}\n");
if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
else
- println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");");
+ println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");");
}
}
callbackType = paramType;
print("\"int\"");
} else { // Generate normal classes if it's not a callback object
- String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
- String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
- print("\"" + getEnumType(prmType) + "\"");
+ //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+ //String prmType = getSimpleType(getEnumType(paramTypeC));
+ String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ String prmType = getEnumType(paramTypeC);
+ print("\"" + prmType + "\"");
}
if (i != methParams.size() - 1) {
print(", ");
println("vector<int> paramEnumInt" + i + ";");
} else {
String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
- //println(methParamComplete + " = " + generateCplusInitializer(methPrmType) + ";");
println(methParamComplete + ";");
}
}
Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
for (Map.Entry<String,Set<String>> 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;");
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...");
println(intface + " *mainObj;");
// Keep track of object Ids of all stubs registered to this interface
- println("static int objectId;");
+ println("int objectId;");
// Callback
if (callbackExist) {
Iterator it = callbackClasses.iterator();
println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
println("mainObj = _mainObj;");
println("objectId = _objectId;");
- // Callback
- if (callbackExist) {
- println("objIdCnt = 0;");
- }
println("}\n");
}
// 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...");
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;
}
+ // Check and find object Id for new interface in mapNewIntfaceObjId (callbacks)
+ // Throw an error if the new interface is not found!
+ // Basically the compiler needs to parse the policy (and requires) files for callback class first
+ private int getNewIntfaceObjectId(String newIntface) {
+
+ if (!mapNewIntfaceObjId.containsKey(newIntface)) {
+ throw new Error("IoTCompiler: Need to parse policy and requires files for callback class first! " +
+ "Please place the two files for callback class in front...\n");
+ } else {
+ int retObjId = mapNewIntfaceObjId.get(newIntface);
+ return retObjId;
+ }
+ }
+
+
// Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
private ParamCategory getParamCategory(String paramType) {
}
+ // Generate a set of standard classes for import statements
+ private List<String> getStandardJavaIntfaceImportClasses() {
+
+ List<String> importClasses = new ArrayList<String>();
+ // Add the standard list first
+ importClasses.add("java.util.List");
+ importClasses.add("java.util.ArrayList");
+
+ return importClasses;
+ }
+
+
// Generate a set of standard classes for import statements
private List<String> getStandardJavaImportClasses() {
} else
return getNonPrimitiveCplusClass(paramType);
} else if(paramType.contains("[]")) { // Array type (used for return type only)
- String cArray = "vector<" + getSimpleArrayType(paramType) + ">";
+ String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">";
return cArray;
} else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
return paramType + "*";
}
+ // Return the class type for class resolution (for return value)
+ // - Check and return C++ array class, e.g. int A[] into int*
+ // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
+ private String checkAndGetCplusRetClsType(String paramType) {
+
+ String paramTypeRet = null;
+ // Check for array declaration
+ if (paramType.contains("[]")) {
+ String type = paramType.split("\\[\\]")[0];
+ paramTypeRet = getSimpleArrayType(type) + "*";
+ } else if (paramType.contains("<") && paramType.contains(">")) {
+ // Just return it as is if it's not an array
+ String type = paramType.split("<")[1].split(">")[0];
+ paramTypeRet = "vector<" + getGenericType(type) + ">";
+ } else
+ paramTypeRet = paramType;
+
+ return paramTypeRet;
+ }
+
+
+ // Return the class type for class resolution (for method arguments)
+ // - Check and return C++ array class, e.g. int A[] into int*
+ // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
+ private String checkAndGetCplusArgClsType(String paramType, String param) {
+
+ String paramTypeRet = null;
+ // Check for array declaration
+ if (param.contains("[]")) {
+ paramTypeRet = getSimpleArrayType(paramType) + "*";
+ } else if (paramType.contains("<") && paramType.contains(">")) {
+ // Just return it as is if it's not an array
+ String type = paramType.split("<")[1].split(">")[0];
+ paramTypeRet = "vector<" + getGenericType(type) + ">";
+ } else
+ paramTypeRet = paramType;
+
+ return paramTypeRet;
+ }
+
+
// Detect array declaration, e.g. int A[],
// then generate type "int[]"
private String checkAndGetArray(String paramType, String param) {
} 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
" 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");
}
}
// 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 <directory> after option: " + args[i]);
+ throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i] + "\n");
if (args[i].equals("-java")) {
comp.generateEnumJava();
} 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");
}
}
}