private Map<String,ParseTreeHandler> mapIntfacePTH;
private Map<String,DeclarationHandler> mapIntDeclHand;
private Map<String,Map<String,Set<String>>> mapInt2NewInts;
+ private Map<String,String> mapInt2NewIntName;
// Data structure to store our types (primitives and non-primitives) for compilation
private Map<String,String> mapPrimitives;
private Map<String,String> mapNonPrimitivesJava;
private PrintWriter pw;
private String dir;
private String subdir;
+ private Map<String,Integer> mapPortCount; // Counter for ports
+ private static int portCount = 0;
+ private static int countObjId = 1; // Always increment object Id for a new stub/skeleton
+ private String mainClass;
+
/**
* Class constants
USERDEFINED // Assumed as driver classes
}
+
/**
* Class constructors
*/
mapIntfacePTH = new HashMap<String,ParseTreeHandler>();
mapIntDeclHand = new HashMap<String,DeclarationHandler>();
mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
+ mapInt2NewIntName = new HashMap<String,String>();
mapIntfaceObjId = new HashMap<String,Integer>();
mapNewIntfaceObjId = new HashMap<String,Integer>();
mapPrimitives = new HashMap<String,String>();
arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs);
mapNonPrimitivesCplus = new HashMap<String,String>();
arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
+ mapPortCount = new HashMap<String,Integer>();
pw = null;
dir = OUTPUT_DIRECTORY;
subdir = null;
+ mainClass = null;
}
* data structures.
* Additionally, the data structure handles are
* returned from tree-parsing for further process.
- *
*/
public void setDataStructures(String origInt, ParseNode pnPol, ParseNode pnReq) {
mapIntfacePTH.put(origInt, ptHandler);
mapIntDeclHand.put(origInt, decHandler);
// Set object Id counter to 0 for each interface
- mapIntfaceObjId.put(origInt, new Integer(0));
+ mapIntfaceObjId.put(origInt, countObjId++);
}
}
// 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);
+ if (mainClass == null) // Take the first class as the main class (whichever is placed first in the order of compilation files)
+ mainClass = origInt;
}
// Map the map of interface-methods to the original interface
mapInt2NewInts.put(origInt, mapNewIntMethods);
}
+
+/*================
+ * Java generation
+ *================/
/**
- * HELPER: writeMethodJavaLocalInterface() writes the method of the interface
+ * HELPER: writeMethodJavaLocalInterface() writes the method of the local interface
*/
private void writeMethodJavaLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
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 + " {");
- // Write enum if any...
- //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
- //writeEnumJava(enumDecl);
- // Write struct if any...
- //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
- //writeStructJava(structDecl);
// Write methods
writeMethodJavaLocalInterface(methods, intDecl);
println("}");
}
+ /**
+ * HELPER: updateIntfaceObjIdMap() updates the mapping between new interface and object Id
+ */
+ private void updateIntfaceObjIdMap(String intface, String newIntface) {
+
+ // We are assuming that we only generate one stub per one skeleton at this point @Feb 2017
+ Integer objId = mapIntfaceObjId.get(intface);
+ mapNewIntfaceObjId.put(newIntface, objId);
+ }
+
+
/**
* generateJavaInterfaces() generate stub interfaces based on the methods list in Java
*/
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);
+ Set<String> methods = intMeth.getValue();
+ 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");
+ updateIntfaceObjIdMap(intface, newIntface);
// 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);
- println("private final static int object" + newObjectId + "Id = " +
- newObjectId + ";\t//" + newIntface);
+ int newObjectId = getNewIntfaceObjectId(newIntface);
Set<String> methodIds = intMeth.getValue();
print("private static Integer[] object" + newObjectId + "Permission = { ");
int i = 0;
i++;
}
println(" };");
- println("private List<Integer> set" + newObjectId + "Allowed;");
+ println("private static List<Integer> set" + newObjectId + "Allowed;");
}
}
/**
* HELPER: writePropertiesJavaStub() writes the properties of the stub class
*/
- private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
+ private void writePropertiesJavaStub(String intface, Set<String> methods, InterfaceDecl intDecl) {
- println("private IoTRMICall rmiCall;");
- println("private String address;");
- 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++);
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- println("// Callback properties");
- println("private IoTRMIObject rmiObj;");
- println("List<" + callbackType + "> listCallbackObj;");
- println("private static int objIdCnt = 0;");
- // Generate permission stuff for callback stubs
- DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
- InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
- writePropertiesJavaPermission(callbackType, intDecl);
+ println("private int objectId = " + objId + ";");
+ println("private IoTRMIComm rmiComm;");
+ // Write the list of AtomicBoolean variables
+ println("// Synchronization variables");
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("private AtomicBoolean retValueReceived" + methodNumId + " = new AtomicBoolean(false);");
+ }
}
println("\n");
}
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("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("set" + newObjectId + "Allowed = new ArrayList<Integer>(Arrays.asList(object" + newObjectId +"Permission));");
}
}
/**
* HELPER: writeConstructorJavaStub() writes the constructor of the stub class
*/
- private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
-
- println("public " + newStubClass + "(int _port, String _address, int _rev, int[] _ports) throws Exception {");
- println("address = _address;");
- println("ports = _ports;");
- println("rmiCall = new IoTRMICall(_port, _address, _rev);");
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- writeConstructorJavaPermission(intface);
- println("listCallbackObj = new ArrayList<" + callbackType + ">();");
- println("___initCallBack();");
+ private void writeConstructorJavaStub(String intface, String newStubClass, Set<String> methods, InterfaceDecl intDecl) {
+
+ println("public " + newStubClass + "(int _localPortSend, int _localPortRecv, int _portSend, int _portRecv, String _skeletonAddress, int _rev) throws Exception {");
+ println("if (_localPortSend != 0 && _localPortRecv != 0) {");
+ println("rmiComm = new IoTRMICommClient(_localPortSend, _localPortRecv, _portSend, _portRecv, _skeletonAddress, _rev);");
+ println("} else");
+ println("{");
+ println("rmiComm = new IoTRMICommClient(_portSend, _portRecv, _skeletonAddress, _rev);");
+ println("}");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm.registerStub(objectId, " + methodNumId + ", retValueReceived" + methodNumId + ");");
+ }
}
+ println("IoTRMIUtil.mapStub.put(objectId, this);");
println("}\n");
}
/**
- * HELPER: writeJavaMethodCallbackPermission() writes permission checks in stub for callbacks
+ * HELPER: writeCallbackConstructorJavaStub() writes the callback constructor of the stub class
*/
- private void writeJavaMethodCallbackPermission(String intface) {
+ private void writeCallbackConstructorJavaStub(String intface, String newStubClass, Set<String> methods, InterfaceDecl intDecl) {
- println("int methodId = IoTRMIObject.getMethodId(method);");
- // Get all the different stubs
- 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("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
- println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
- println("}");
+ println("public " + newStubClass + "(IoTRMIComm _rmiComm, int _objectId) throws Exception {");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm.registerStub(objectId, " + methodNumId + ", retValueReceived" + methodNumId + ");");
+ }
}
+ println("}\n");
}
/**
- * HELPER: writeConstructorJavaStub() writes the constructor of the stub class
+ * HELPER: getPortCount() gets port count for different stubs and skeletons
*/
- private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) {
+ private int getPortCount(String intface) {
- 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]);");
- 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) {");
- println("skel.invokeMethod(rmiObj);");
- println("} else {");
- println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
- println("}");
- println("}");
- println("} catch (Exception ex) {");
- println("ex.printStackTrace();");
- println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
- println("}");
- println("}");
- println("};");
- println("thread.start();\n");
- // Generate info sending part
- String method = "___initCallBack()";
- println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
- 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("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
- println("}\n");
+ if (!mapPortCount.containsKey(intface))
+ mapPortCount.put(intface, portCount++);
+ return mapPortCount.get(intface);
}
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];");
/**
* HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int)
*/
- private void checkAndWriteEnumRetTypeJavaStub(String retType) {
+ private void checkAndWriteEnumRetTypeJavaStub(String retType, String method, InterfaceDecl intDecl) {
+ // Write the wait-for-return-value part
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
// 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
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);
String helperMethod = methodNumId + "struct" + i;
println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
- println("Class<?> retTypeStruct" + i + " = void.class;");
println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
if (isArray(param)) { // An array
println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
} else { // Just one element
println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };");
}
- println("rmiCall.remoteCall(objectId, methodIdStruct" + i +
- ", retTypeStruct" + i + ", null, paramClsStruct" + i +
- ", paramObjStruct" + i + ");\n");
+ println("rmiComm.remoteCall(objectId, methodIdStruct" + i +
+ ", paramClsStruct" + i + ", paramObjStruct" + i + ");\n");
}
}
}
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;
}
/**
- * HELPER: writeLengthStructParamClassJavaStub() writes lengths of params
+ * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters
*/
private void writeLengthStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
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));
List<String> memTypes = structDecl.getMemberTypes(simpleType);
List<String> 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(";");
}
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(";");
}
/**
* HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
*/
- private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
+ private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes, Set<String> callbackType) {
print("int paramLen = ");
writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
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;");
+ println("paramObj[pos++] = objIdSent" + i + ";");
} else {
String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
/**
- * HELPER: writeStructRetMembersJavaStub() writes parameters of struct
+ * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement
*/
private void writeStructRetMembersJavaStub(String simpleType, String retType) {
List<String> memTypes = structDecl.getMemberTypes(simpleType);
List<String> members = structDecl.getMembers(simpleType);
if (isArrayOrList(retType, retType)) { // An array or list
- println("for(int i = 0; i < retLen.length; i++) {");
+ println("for(int i = 0; i < retLen; i++) {");
}
if (isArray(retType)) { // An array
for (int i = 0; i < members.size(); i++) {
String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
print("structRet[i]." + getSimpleIdentifier(members.get(i)));
- println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
+ println(" = (" + getSimpleType(getEnumType(prmType)) + ") retActualObj[retObjPos++];");
}
println("}");
} else if (isList(retType)) { // A list
for (int i = 0; i < members.size(); i++) {
String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
print("structRetMem." + getSimpleIdentifier(members.get(i)));
- println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
+ println(" = (" + getSimpleType(getEnumType(prmType)) + ") retActualObj[retObjPos++];");
}
println("structRet.add(structRetMem);");
println("}");
for (int i = 0; i < members.size(); i++) {
String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
print("structRet." + getSimpleIdentifier(members.get(i)));
- println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
+ println(" = (" + getSimpleType(getEnumType(prmType)) + ") retActualObj[retObjPos++];");
}
}
println("return structRet;");
/**
- * HELPER: writeStructReturnJavaStub() writes parameters if struct is present
+ * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement
*/
- private void writeStructReturnJavaStub(String simpleType, String retType) {
+ private void writeStructReturnJavaStub(String simpleType, String retType, String method, InterfaceDecl intDecl) {
- // Handle the returned struct!!!
- println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+ // Handle the returned struct size
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
// Minimum retLen is 1 if this is a single struct object
- println("int retLen = (int) retLenObj;");
+ println("int retLen = (int) retObj;");
int numMem = getNumOfMembers(simpleType);
println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
println("Class<?>[] retClsVal = new Class<?>[" + numMem + "*retLen];");
println("retClsVal[retPos++] = null;");
}
}
- println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);");
+ // Handle the actual returned struct
+ writeWaitForReturnValueJava(method, intDecl, "Object[] retActualObj = rmiComm.getStructObjects(retCls, retClsVal);");
if (isArray(retType)) { // An array
println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
println("for(int i = 0; i < retLen; i++) {");
}
+ /**
+ * HELPER: writeWaitForReturnValueJava() writes the synchronization part for return values
+ */
+ private void writeWaitForReturnValueJava(String method, InterfaceDecl intDecl, String getReturnValue) {
+
+ println("// Waiting for return value");
+ int methodNumId = intDecl.getMethodNumId(method);
+ println("while (!retValueReceived" + methodNumId + ".get());");
+ println(getReturnValue);
+ println("retValueReceived" + methodNumId + ".set(false);");
+ println("rmiComm.setGetReturnBytes();\n");
+ }
+
+
/**
* HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
*/
private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
- List<String> methPrmTypes, String method) {
+ List<String> methPrmTypes, String method, Set<String> callbackType) {
checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
println("int methodId = " + intDecl.getMethodNumId(method) + ";");
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(", ");
// 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
+ print("objIdSent" + 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(", ");
}
println(" };");
}
+ // Send method call first and wait for return value separately
+ println("rmiComm.remoteCall(objectId, methodId, paramCls, paramObj);");
// 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
+ if (!retType.equals("void")) { // We do have a return value
// Generate array of parameter types
if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
- writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
+ writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType, method, intDecl);
} 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
- println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
- checkAndWriteEnumRetTypeJavaStub(retType);
+ if (getParamCategory(getGenericType(getSimpleArrayType(retType))) == ParamCategory.ENUM) {
+ //println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+ checkAndWriteEnumRetTypeJavaStub(retType, method, intDecl);
+ } else if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
+ // Check if the return value NONPRIMITIVES
+ String retGenValType = getGenericType(retType);
+ println("Class<?> retGenValType = " + retGenValType + ".class;");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, retGenValType);");
+ println("return (" + retType + ")retObj;");
} else {
- println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
println("return (" + retType + ")retObj;");
}
}
private String returnGenericCallbackType(String paramType) {
if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
- return getTypeOfGeneric(paramType)[0];
+ return getGenericType(paramType);
else
return paramType;
}
+ /**
+ * HELPER: checkCallbackType() checks the callback type
+ */
+ private boolean checkCallbackType(String paramType, Set<String> callbackType) {
+
+ String prmType = returnGenericCallbackType(paramType);
+ if (callbackType == null) // If there is no callbackType it means not a callback method
+ return false;
+ else {
+ for (String type : callbackType) {
+ if (type.equals(prmType))
+ return true; // Check callbackType one by one
+ }
+ return false;
+ }
+ }
+
+
/**
* HELPER: checkCallbackType() checks the callback type
*/
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);
+ }
+
+
+ /**
+ * HELPER: writeCallbackInstantiationMethodBodyJavaStub() writes the callback object instantiation in the method of the stub class
+ */
+ private void writeCallbackInstantiationMethodBodyJavaStub(String paramIdent, String callbackType, int counter, boolean isMultipleCallbacks) {
+
+ println("if (!IoTRMIUtil.mapSkel.containsKey(" + paramIdent + ")) {");
+ println("int newObjIdSent = rmiComm.getObjectIdCounter();");
+ if (isMultipleCallbacks)
+ println("objIdSent" + counter + "[cnt" + counter + "++] = newObjIdSent;");
+ else
+ println("objIdSent" + counter + "[0] = newObjIdSent;");
+ println("rmiComm.decrementObjectIdCounter();");
+ println(callbackType + "_Skeleton skel" + counter + " = new " + callbackType + "_Skeleton(" + paramIdent + ", rmiComm, newObjIdSent);");
+ println("IoTRMIUtil.mapSkel.put(" + paramIdent + ", skel" + counter + ");");
+ println("IoTRMIUtil.mapSkelId.put(" + paramIdent + ", newObjIdSent);");
+ println("Thread thread = new Thread() {");
+ println("public void run() {");
+ println("try {");
+ println("skel" + counter + ".___waitRequestInvokeMethod();");
+ println("} catch (Exception ex) {");
+ println("ex.printStackTrace();");
+ println("throw new Error(\"Exception when trying to run ___waitRequestInvokeMethod() for " +
+ callbackType + "_Skeleton!\");");
+ println("}");
+ println("}");
+ println("};");
+ println("thread.start();");
+ println("while(!skel" + counter + ".didAlreadyInitWaitInvoke());");
+ println("}");
+ println("else");
+ println("{");
+ println("int newObjIdSent = IoTRMIUtil.mapSkelId.get(" + paramIdent + ");");
+ if (isMultipleCallbacks)
+ println("objIdSent" + counter + "[cnt" + counter + "++] = newObjIdSent;");
+ else
+ println("objIdSent" + counter + "[0] = newObjIdSent;");
+ println("}");
}
* HELPER: writeCallbackMethodBodyJavaStub() writes the callback method of the stub class
*/
private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
- List<String> methPrmTypes, String method, String callbackType) {
+ List<String> methPrmTypes, String method, Set<String> callbackType) {
+ // Determine callback object counter type (List vs. single variable)
+ 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[] objIdSent" + i + " = ");
+ String param = methParams.get(i);
+ if (isArray(methParams.get(i)))
+ println("new int[" + getSimpleIdentifier(methParams.get(i)) + ".length];");
+ else if (isList(methPrmTypes.get(i)))
+ println("new int[" + getSimpleIdentifier(methParams.get(i)) + ".size()];");
+ else
+ println("new int[1];");
+ }
+ }
println("try {");
// Check if this is single object, array, or list of objects
for (int i = 0; i < methParams.size(); i++) {
-
String paramType = methPrmTypes.get(i);
if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
String param = methParams.get(i);
if (isArrayOrList(paramType, param)) { // Generate loop
- println("for (" + paramType + " cb : " + getSimpleIdentifier(param) + ") {");
- println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
+ println("int cnt" + i + " = 0;");
+ println("for (" + getGenericType(paramType) + " cb : " + getSimpleIdentifier(param) + ") {");
+ writeCallbackInstantiationMethodBodyJavaStub("cb", returnGenericCallbackType(paramType), i, true);
} else
- println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(" +
- getSimpleIdentifier(param) + ", objIdCnt++);");
- println("listCallbackObj.add(skel);");
+ writeCallbackInstantiationMethodBodyJavaStub(getSimpleIdentifier(param), returnGenericCallbackType(paramType), i, false);
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 method of the stub class
+ * HELPER: writeMethodJavaStub() writes the methods of the stub class
*/
- private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
+ private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
for (String method : methods) {
print("public " + intDecl.getMethodType(method) + " " +
intDecl.getMethodId(method) + "(");
boolean isCallbackMethod = false;
- String callbackType = null;
+ //String callbackType = null;
+ Set<String> callbackType = new HashSet<String>();
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
// Check if this has callback object
if (callbackClasses.contains(paramType)) {
isCallbackMethod = true;
- callbackType = paramType;
+ //callbackType = paramType;
+ callbackType.add(paramType);
// Even if there're 2 callback arguments, we expect them to be of the same interface
}
print(methPrmTypes.get(i) + " " + methParams.get(i));
// Now, write the body of stub!
if (isCallbackMethod)
writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
- else
- writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method);
+ writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
println("}\n");
- // Write the init callback helper method
- if (isCallbackMethod)
- writeInitCallbackJavaStub(callbackType, intDecl);
}
}
+ /**
+ * 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
*/
// Write class header
println("public class " + newStubClass + " implements " + newIntface + " {\n");
// Write properties
- writePropertiesJavaStub(intface, newIntface, callbackExist, callbackClasses);
+ writePropertiesJavaStub(intface, intMeth.getValue(), intDecl);
// Write constructor
- writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
+ writeConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
+ // Write callback constructor (used if this stub is treated as a callback stub)
+ writeCallbackConstructorJavaStub(intface, newStubClass, intMeth.getValue(), intDecl);
// 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...");
/**
- * HELPER: writePropertiesJavaCallbackStub() writes the properties of the callback stub class
+ * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
*/
- private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
+ private void writePropertiesJavaSkeleton(String intface, InterfaceDecl intDecl) {
- println("private IoTRMICall rmiCall;");
- println("private String address;");
- println("private int[] ports;\n");
- // Get the object Id
- println("private static int objectId = 0;");
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- println("// Callback properties");
- println("private IoTRMIObject rmiObj;");
- println("List<" + callbackType + "> listCallbackObj;");
- println("private static int objIdCnt = 0;");
- // Generate permission stuff for callback stubs
- DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
- InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
- writePropertiesJavaPermission(callbackType, intDecl);
- }
+ println("private " + intface + " mainObj;");
+ Integer objId = mapIntfaceObjId.get(intface);
+ println("private int objectId = " + objId + ";");
+ println("// Communications and synchronizations");
+ println("private IoTRMIComm rmiComm;");
+ println("private AtomicBoolean didAlreadyInitWaitInvoke;");
+ println("private AtomicBoolean methodReceived;");
+ println("private byte[] methodBytes = null;");
+ println("// Permissions");
+ writePropertiesJavaPermission(intface, intDecl);
println("\n");
}
/**
- * HELPER: writeConstructorJavaCallbackStub() writes the constructor of the callback stub class
- */
- private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set<String> 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("objectId = _objectId;");
- println("rmiCall = _rmiCall;");
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- writeConstructorJavaPermission(intface);
- println("listCallbackObj = new ArrayList<" + callbackType + ">();");
- println("___initCallBack();");
- println("// TODO: Add address and port initialization here if we want callback in callback!");
- }
- println("}\n");
- }
-
-
- /**
- * generateJavaCallbackStubClasses() generate callback stubs based on the methods list in Java
- * <p>
- * Callback stubs gets the IoTRMICall objects from outside of the class as contructor input
- * because all these stubs are populated by the class that takes in this object as a callback
- * object. In such a class, we only use one socket, hence one IoTRMICall, for all callback objects.
+ * HELPER: writeStructPermissionJavaSkeleton() writes permission for struct helper
*/
- public void generateJavaCallbackStubClasses() throws IOException {
-
- // Create a new directory
- String path = createDirectories(dir, subdir);
- for (String intface : mapIntfacePTH.keySet()) {
-
- Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
- for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+ private void writeStructPermissionJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, String intface) {
- // Open a new file to write into
- String newIntface = intMeth.getKey();
- String newStubClass = newIntface + "_CallbackStub";
- FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
- pw = new PrintWriter(new BufferedWriter(fw));
- DeclarationHandler decHandler = mapIntDeclHand.get(intface);
- InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
- // Pass in set of methods and get import classes
- Set<String> methods = intMeth.getValue();
- Set<String> importClasses = getImportClasses(methods, intDecl);
- List<String> stdImportClasses = getStandardJavaImportClasses();
- List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
- printImportStatements(allImportClasses); println("");
- // Find out if there are callback objects
- Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
- boolean callbackExist = !callbackClasses.isEmpty();
- // Write class header
- println("public class " + newStubClass + " implements " + newIntface + " {\n");
- // Write properties
- writePropertiesJavaCallbackStub(intface, newIntface, callbackExist, callbackClasses);
- // Write constructor
- writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
- // Write methods
- // TODO: perhaps need to generate callback for callback
- writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
- println("}");
- pw.close();
- System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+ for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+ String newIntface = intMeth.getKey();
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("set" + newObjectId + "Allowed.add(" + methodHelperNumId + ");");
+ }
+ }
}
}
}
/**
- * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
+ * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
*/
- private void writePropertiesJavaSkeleton(String intface, boolean callbackExist, InterfaceDecl intDecl) {
+ private void writeConstructorJavaSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl,
+ Collection<String> methods, boolean callbackExist) {
- println("private " + intface + " mainObj;");
- //println("private int ports;");
- println("private IoTRMIObject rmiObj;\n");
- // Callback
- if (callbackExist) {
- println("private static int objIdCnt = 0;");
- println("private IoTRMICall rmiCall;");
- }
- writePropertiesJavaPermission(intface, intDecl);
- println("\n");
+ println("public " + newSkelClass + "(" + intface + " _mainObj, int _portSend, int _portRecv) throws Exception {");
+ println("mainObj = _mainObj;");
+ println("rmiComm = new IoTRMICommServer(_portSend, _portRecv);");
+ // Generate permission control initialization
+ writeConstructorJavaPermission(intface);
+ writeStructPermissionJavaSkeleton(methods, intDecl, intface);
+ println("IoTRMIUtil.mapSkel.put(_mainObj, this);");
+ println("IoTRMIUtil.mapSkelId.put(_mainObj, objectId);");
+ println("didAlreadyInitWaitInvoke = new AtomicBoolean(false);");
+ println("methodReceived = new AtomicBoolean(false);");
+ println("rmiComm.registerSkeleton(objectId, methodReceived);");
+ println("Thread thread1 = new Thread() {");
+ println("public void run() {");
+ println("try {");
+ println("___waitRequestInvokeMethod();");
+ println("}");
+ println("catch (Exception ex)");
+ println("{");
+ println("ex.printStackTrace();");
+ println("}");
+ println("}");
+ println("};");
+ println("thread1.start();");
+ println("}\n");
}
/**
- * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
+ * HELPER: writeCallbackConstructorJavaSkeleton() writes the constructor of the skeleton class
*/
- private void writeConstructorJavaSkeleton(String newSkelClass, String intface) {
+ private void writeCallbackConstructorJavaSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl,
+ Collection<String> methods, boolean callbackExist) {
- println("public " + newSkelClass + "(" + intface + " _mainObj, int _port) throws Exception {");
+ println("public " + newSkelClass + "(" + intface + " _mainObj, IoTRMIComm _rmiComm, int _objectId) throws Exception {");
println("mainObj = _mainObj;");
- println("rmiObj = new IoTRMIObject(_port);");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
// Generate permission control initialization
writeConstructorJavaPermission(intface);
- println("___waitRequestInvokeMethod();");
+ writeStructPermissionJavaSkeleton(methods, intDecl, intface);
+ println("didAlreadyInitWaitInvoke = new AtomicBoolean(false);");
+ println("methodReceived = new AtomicBoolean(false);");
+ println("rmiComm.registerSkeleton(objectId, methodReceived);");
println("}\n");
}
}
- /**
- * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
- */
- private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) {
-
- // 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]);");
- println("}\n");
- }
-
-
/**
* HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
*/
- private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
- boolean callbackSkeleton) {
+ private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
for (String method : methods) {
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
String methodId = intDecl.getMethodId(method);
print("public " + intDecl.getMethodType(method) + " " + methodId + "(");
- boolean isCallbackMethod = false;
- String callbackType = null;
for (int i = 0; i < methParams.size(); i++) {
String origParamType = methPrmTypes.get(i);
String paramType = checkAndGetParamClass(origParamType);
- if (callbackClasses.contains(origParamType)) { // Check if this has callback object
- isCallbackMethod = true;
- callbackType = origParamType;
- }
print(paramType + " " + methParams.get(i));
// Check if this is the last element (don't print a comma)
if (i != methParams.size() - 1) {
// Now, write the body of skeleton!
writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
println("}\n");
- if (isCallbackMethod)
- writeInitCallbackJavaSkeleton(callbackSkeleton);
}
}
/**
- * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
+ * HELPER: writeCallbackInstantiationJavaStubGeneration() writes the instantiation of callback stubs
*/
- private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+ private void writeCallbackInstantiationJavaStubGeneration(String exchParamType, int counter) {
+
+ println(exchParamType + " newStub" + counter + " = null;");
+ println("if(!IoTRMIUtil.mapStub.containsKey(objIdRecv" + counter + ")) {");
+ println("newStub" + counter + " = new " + exchParamType + "_Stub(rmiComm, objIdRecv" + counter + ");");
+ println("IoTRMIUtil.mapStub.put(objIdRecv" + counter + ", newStub" + counter + ");");
+ println("rmiComm.setObjectIdCounter(objIdRecv" + counter + ");");
+ println("rmiComm.decrementObjectIdCounter();");
+ println("}");
+ println("else {");
+ println("newStub" + counter + " = (" + exchParamType + "_Stub) IoTRMIUtil.mapStub.get(objIdRecv" + counter + ");");
+ println("}");
+ }
+
+
+ /**
+ * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
+ */
+ private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes,
+ Set<String> callbackType, boolean isStructMethod) {
Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
+ String offsetPfx = "";
+ if (isStructMethod)
+ offsetPfx = "offset";
// Iterate over callback objects
for (int i = 0; i < methParams.size(); i++) {
String paramType = methPrmTypes.get(i);
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[] stubIdArray" + i + " = (int[]) paramObj[" + offsetPfx + i + "];");
+ if (isArray(param)) {
+ println("int numStubs" + i + " = stubIdArray" + i + ".length;");
println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
} else if (isList(paramType)) {
- println("int numStubs" + i + " = (int) paramObj[" + i + "];");
+ println("int numStubs" + i + " = stubIdArray" + i + ".length;");
println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
} else {
- println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
- println("objIdCnt++;");
+ println("int objIdRecv" + i + " = stubIdArray" + i + "[0];");
+ writeCallbackInstantiationJavaStubGeneration(exchParamType, 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 (isArray(param)) {
- println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
- println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
- println("objIdCnt++;");
+ println("for (int i = 0; i < numStubs" + i + "; i++) {");
+ println("int objIdRecv" + i + " = stubIdArray" + i + "[i];");
+ writeCallbackInstantiationJavaStubGeneration(exchParamType, i);
+ println("stub" + i + "[i] = newStub" + i + ";");
println("}");
} else if (isList(paramType)) {
- println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
- println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));");
- println("objIdCnt++;");
+ println("for (int i = 0; i < numStubs" + i + "; i++) {");
+ println("int objIdRecv" + i + " = stubIdArray" + i + "[i];");
+ writeCallbackInstantiationJavaStubGeneration(exchParamType, i);
+ println("stub" + i + ".add(newStub" + i + ");");
println("}");
- }
+ } else
+ println(exchParamType + " stub" + i + " = newStub" + i + ";");
mapStubParam.put(i, "stub" + i); // List of all stub parameters
}
}
/**
* HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int)
*/
- private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> methPrmTypes) {
+ private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> 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]];");
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
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
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];");
/**
- * HELPER: writeLengthStructParamClassJavaSkeleton() writes lengths of params
+ * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params
*/
- private void writeLengthStructParamClassJavaSkeleton(List<String> methParams, List<String> methPrmTypes,
+ private void writeLengthStructParamClassSkeleton(List<String> methParams, List<String> methPrmTypes,
String method, InterfaceDecl intDecl) {
// Iterate and find struct declarations - count number of params
/**
- * HELPER: writeStructMembersJavaSkeleton() writes parameters of struct
+ * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct
*/
private void writeStructMembersJavaSkeleton(String simpleType, String paramType,
String param, String method, InterfaceDecl intDecl, int iVar) {
StructDecl structDecl = getStructDecl(simpleType);
List<String> memTypes = structDecl.getMemberTypes(simpleType);
List<String> 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;");
}
-
/**
- * HELPER: writeStructMembersInitJavaSkeleton() writes parameters of struct
+ * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct
*/
private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
List<String> 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);
println("paramStruct" + i + "[i] = new " + simpleType + "();");
println("}");
} else if (isList(paramType)) { // A list
- println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();");
+ println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();");
} else
println(simpleType + " paramStruct" + i + " = new " + simpleType + "();");
- println("int objPos = 0;");
// Initialize members
StructDecl structDecl = getStructDecl(simpleType);
List<String> members = structDecl.getMembers(simpleType);
List<String> 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
}
} else {
// Take offsets of parameters
- println("int offset" + i +" = objPos;");
+ println("int offset" + i +" = objPos++;");
}
}
}
/**
- * HELPER: writeStructReturnJavaSkeleton() writes parameters if struct is present
+ * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement
*/
private void writeStructReturnJavaSkeleton(String simpleType, String retType) {
else // Just single struct object
println("int retLen = 1;");
println("Object retLenObj = retLen;");
- println("rmiObj.sendReturnObj(retLenObj);");
+ println("rmiComm.sendReturnObj(retLenObj, localMethodBytes);");
int numMem = getNumOfMembers(simpleType);
println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
println("Object[] retObj = new Object[" + numMem + "*retLen];");
StructDecl structDecl = getStructDecl(simpleType);
List<String> memTypes = structDecl.getMemberTypes(simpleType);
List<String> 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));
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));
}
+ /**
+ * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton
+ */
+ private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method, boolean isCallbackMethod, Set<String> callbackType,
+ boolean isStructMethod) {
+
+ checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes, isStructMethod);
+ Map<Integer,String> mapStubParam = null;
+ 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(getGenericType(retType)))) { // Enum type
+ checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
+ } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type
+ print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
+ } else { // We do have a return value
+ print("Object retObj = " + intDecl.getMethodId(method) + "(");
+ }
+ for (int i = 0; i < methParams.size(); i++) {
+
+ String paramType = methPrmTypes.get(i);
+ if (isCallbackMethod && checkCallbackType(paramType, callbackType)) {
+ print(mapStubParam.get(i)); // Get the callback parameter
+ } 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(paramType, methParams.get(i));
+ if (isStructMethod)
+ print("(" + prmType + ") paramObj[offset" + i + "]");
+ else
+ print("(" + prmType + ") paramObj[" + i + "]");
+ }
+ if (i != methParams.size() - 1)
+ print(", ");
+ }
+ println(");");
+ if (!retType.equals("void")) {
+ if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type
+ checkAndWriteEnumRetConvJavaSkeleton(retType);
+ println("rmiComm.sendReturnObj(retObj, localMethodBytes);");
+ } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type
+ writeStructReturnJavaSkeleton(getSimpleArrayType(getGenericType(retType)), retType);
+ println("rmiComm.sendReturnObj(retCls, retObj, localMethodBytes);");
+ } else
+ println("rmiComm.sendReturnObj(retObj, localMethodBytes);");
+ }
+ if (isCallbackMethod) { // Catch exception if this is callback
+ print("}");
+ println(" catch(Exception ex) {");
+ println("ex.printStackTrace();");
+ println("throw new Error(\"Exception from callback object instantiation!\");");
+ println("}");
+ }
+ }
+
+
/**
* HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton
*/
// Generate array of parameter objects
boolean isCallbackMethod = false;
- String callbackType = null;
+ Set<String> callbackType = new HashSet<String>();
+ println("byte[] localMethodBytes = methodBytes;");
+ println("rmiComm.setGetMethodBytes();");
print("int paramLen = ");
- writeLengthStructParamClassJavaSkeleton(methParams, methPrmTypes, method, intDecl);
+ writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
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);
String prmType = returnGenericCallbackType(methPrmTypes.get(i));
if (callbackClasses.contains(prmType)) {
isCallbackMethod = true;
- callbackType = prmType;
- print("int.class");
+ //callbackType = prmType;
+ callbackType.add(prmType);
+ println("paramCls[pos] = int[].class;");
+ println("paramClsGen[pos++] = null;");
} else { // Generate normal classes if it's not a callback object
String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;");
}
}
}
- println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);");
+ println("Object[] paramObj = rmiComm.getMethodParams(paramCls, paramClsGen, localMethodBytes);");
writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method);
- checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
- Map<Integer,String> mapStubParam = null;
- if (isCallbackMethod)
- mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
- // Check if this is "void"
- String retType = intDecl.getMethodType(method);
- if (retType.equals("void")) {
- print(intDecl.getMethodId(method) + "(");
- } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
- checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
- } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
- print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
- } else { // We do have a return value
- print("Object retObj = " + intDecl.getMethodId(method) + "(");
- }
- for (int i = 0; i < methParams.size(); i++) {
-
- if (isCallbackMethod) {
- print(mapStubParam.get(i)); // Get the callback parameter
- } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class
- print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i));
- } else if (isStructClass(getSimpleType(methPrmTypes.get(i)))) {
- print("paramStruct" + i);
- } else {
- String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
- print("(" + prmType + ") paramObj[offset" + i + "]");
- }
- if (i != methParams.size() - 1)
- print(", ");
- }
- println(");");
- if (!retType.equals("void")) {
- if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
- checkAndWriteEnumRetConvJavaSkeleton(retType);
- println("rmiObj.sendReturnObj(retObj);");
- } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
- writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
- println("rmiObj.sendReturnObj(retCls, retObj);");
- } else
- println("rmiObj.sendReturnObj(retObj);");
- }
- if (isCallbackMethod) { // Catch exception if this is callback
- println("} catch(Exception ex) {");
- println("ex.printStackTrace();");
- println("throw new Error(\"Exception from callback object instantiation!\");");
- println("}");
- }
+ // Write the return value part
+ writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true);
}
// Generate array of parameter objects
boolean isCallbackMethod = false;
- String callbackType = null;
- print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
+ Set<String> callbackType = new HashSet<String>();
+ println("byte[] localMethodBytes = methodBytes;");
+ println("rmiComm.setGetMethodBytes();");
+ print("Object[] paramObj = rmiComm.getMethodParams(new Class<?>[] { ");
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
if (callbackClasses.contains(paramType)) {
isCallbackMethod = true;
- callbackType = paramType;
- print("int.class");
+ callbackType.add(paramType);
+ print("int[].class");
} else { // Generate normal classes if it's not a callback object
String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
print(getSimpleType(getEnumType(prmType)) + ".class");
if (i != methParams.size() - 1)
print(", ");
}
- println(" }, ");
// Generate generic class if it's a generic type.. null otherwise
- print("new Class<?>[] { ");
+ 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)
print(", ");
}
- println(" });");
- checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
- Map<Integer,String> mapStubParam = null;
- if (isCallbackMethod)
- mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
- // Check if this is "void"
- String retType = intDecl.getMethodType(method);
- if (retType.equals("void")) {
- print(intDecl.getMethodId(method) + "(");
- } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
- checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
- } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
- print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
- } else { // We do have a return value
- print("Object retObj = " + intDecl.getMethodId(method) + "(");
- }
- for (int i = 0; i < methParams.size(); i++) {
-
- if (isCallbackMethod) {
- print(mapStubParam.get(i)); // Get the callback parameter
- } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class
- print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i));
- } else {
- String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
- print("(" + prmType + ") paramObj[" + i + "]");
- }
- if (i != methParams.size() - 1)
- print(", ");
- }
- println(");");
- if (!retType.equals("void")) {
- if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
- checkAndWriteEnumRetConvJavaSkeleton(retType);
- println("rmiObj.sendReturnObj(retObj);");
- } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
- writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
- println("rmiObj.sendReturnObj(retCls, retObj);");
- } else
- println("rmiObj.sendReturnObj(retObj);");
- }
- if (isCallbackMethod) { // Catch exception if this is callback
- println("} catch(Exception ex) {");
- println("ex.printStackTrace();");
- println("throw new Error(\"Exception from callback object instantiation!\");");
- println("}");
- }
+ println(" }, localMethodBytes);");
+ // Write the return value part
+ writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false);
}
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);
}
- // TODO: Need to create comma separation
}
// Check if this is "void"
if (retType.equals("void"))
/**
- * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of the struct in skeleton class
+ * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class
*/
private void writeMethodHelperStructSetupJavaSkeleton(Collection<String> methods,
InterfaceDecl intDecl) {
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 ___");
String helperMethod = methodNumId + "struct" + i;
println(helperMethod + "() {");
// Now, write the helper body of skeleton!
- println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
+ println("byte[] localMethodBytes = methodBytes;");
+ println("rmiComm.setGetMethodBytes();");
+ println("Object[] paramObj = rmiComm.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null }, localMethodBytes);");
println("return (int) paramObj[0];");
println("}\n");
}
/**
- * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of the struct in skeleton class
+ * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class
*/
private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection<String> methods,
InterfaceDecl intDecl) {
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 ___");
String helperMethod = methodNumId + "struct" + i;
println(helperMethod + "(IoTRMIObject rmiObj) {");
// Now, write the helper body of skeleton!
- println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
+ println("Object[] paramObj = rmiComm.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
println("return (int) paramObj[0];");
println("}\n");
}
/**
- * HELPER: writeCountVarStructJavaSkeleton() writes counter variable of struct for skeleton
+ * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton
*/
- private void writeCountVarStructJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+ private void writeCountVarStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
// Use this set to handle two same methodIds
for (String method : methods) {
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;");
}
}
-
+
/**
- * HELPER: writeInputCountVarStructJavaSkeleton() writes counter variable of struct for skeleton
+ * HELPER: writeInputCountVarStructJavaSkeleton() writes input counter variable of struct for skeleton
*/
private boolean writeInputCountVarStructJavaSkeleton(String method, InterfaceDecl intDecl) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> 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 + "Final");
+ }
+ }
+ return structExist;
+ }
+
+
+ /**
+ * HELPER: writeInputCountVarStructCplusSkeleton() writes input counter variable of struct for skeleton
+ */
+ private boolean writeInputCountVarStructCplusSkeleton(String method, InterfaceDecl intDecl) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ structExist = true;
+ if (!begin)
+ print(", ");
+ else
+ begin = false;
int methodNumId = intDecl.getMethodNumId(method);
print("struct" + methodNumId + "Size" + i);
}
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 ");
/**
- * HELPER: writeMethodCallStructJavaCallbackSkeleton() writes method call for wait invoke in skeleton
+ * HELPER: writeMethodCallStructCplusSkeleton() writes method call for wait invoke in skeleton
*/
- private void writeMethodCallStructJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+ private void writeMethodCallStructCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
// Use this set to handle two same methodIds
for (String method : methods) {
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 ");
+ String helperMethod = methodNumId + "struct" + i;
+ String tempVar = "struct" + methodNumId + "Size" + i;
+ print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
+ print(tempVar + " = ___");
+ println(helperMethod + "(skel); break;");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
+ */
+ private void writeMethodCallStructCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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);
print("case ");
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("if (_objectId == object" + newObjectId + "Id) {");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("if (_objectId == objectId) {");
println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
println("}");
- println("else {");
- println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");");
println("}");
+ println("else {");
+ println("continue;");
println("}");
}
}
+ /**
+ * HELPER: writeFinalInputCountVarStructSkeleton() writes the final version of input counter variable of struct for skeleton
+ */
+ private boolean writeFinalInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ structExist = true;
+ int methodNumId = intDecl.getMethodNumId(method);
+ println("final int struct" + methodNumId + "Size" + i +
+ "Final = struct" + methodNumId + "Size" + i + ";");
+ }
+ }
+ return structExist;
+ }
+
+
/**
* HELPER: writeJavaWaitRequestInvokeMethod() writes the main loop of the skeleton class
*/
- private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
+ private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, String intface) {
// Use this set to handle two same methodIds
Set<String> uniqueMethodIds = new HashSet<String>();
- println("private void ___waitRequestInvokeMethod() throws IOException {");
+ println("public void ___waitRequestInvokeMethod() throws IOException {");
// Write variables here if we have callbacks or enums or structs
- writeCountVarStructJavaSkeleton(methods, intDecl);
+ writeCountVarStructSkeleton(methods, intDecl);
+ println("didAlreadyInitWaitInvoke.compareAndSet(false, true);");
println("while (true) {");
- println("rmiObj.getMethodBytes();");
- println("int _objectId = rmiObj.getObjectId();");
- println("int methodId = rmiObj.getMethodId();");
+ println("if (!methodReceived.get()) {");
+ println("continue;");
+ println("}");
+ println("methodBytes = rmiComm.getMethodBytes();");
+ println("methodReceived.set(false);");
+ println("int _objectId = IoTRMIComm.getObjectId(methodBytes);");
+ println("int methodId = IoTRMIComm.getMethodId(methodBytes);");
// Generate permission check
writeJavaMethodPermission(intface);
println("switch (methodId) {");
for (String method : methods) {
String methodId = intDecl.getMethodId(method);
int methodNumId = intDecl.getMethodNumId(method);
- print("case " + methodNumId + ": ___");
+ println("case " + methodNumId + ":");
+ // Check for stuct counters
+ writeFinalInputCountVarStructSkeleton(method, intDecl);
+ println("new Thread() {");
+ println("public void run() {");
+ println("try {");
+ print("___");
String helperMethod = methodId;
if (uniqueMethodIds.contains(methodId))
helperMethod = helperMethod + methodNumId;
uniqueMethodIds.add(methodId);
print(helperMethod + "(");
writeInputCountVarStructJavaSkeleton(method, intDecl);
- println("); break;");
+ println(");");
+ println("}");
+ println("catch (Exception ex) {");
+ println("ex.printStackTrace();");
+ println("}");
+ println("}");
+ println("}.start();");
+ println("break;");
}
String method = "___initCallBack()";
- // Print case -9999 (callback handler) if callback exists
- if (callbackExist) {
- int methodId = intDecl.getHelperMethodNumId(method);
- println("case " + methodId + ": ___regCB(); break;");
- }
writeMethodCallStructJavaSkeleton(methods, intDecl);
println("default: ");
println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
}
+ /**
+ * HELPER: writeReturnDidAlreadyInitWaitInvoke() writes the function to return didAlreadyInitWaitInvoke
+ */
+ private void writeReturnDidAlreadyInitWaitInvoke() {
+
+ println("public boolean didAlreadyInitWaitInvoke() {");
+ println("return didAlreadyInitWaitInvoke.get();");
+ println("}\n");
+ }
+
+
/**
* generateJavaSkeletonClass() generate skeletons based on the methods list in Java
*/
println("");
println("public class " + newSkelClass + " implements " + intface + " {\n");
// Write properties
- writePropertiesJavaSkeleton(intface, callbackExist, intDecl);
+ writePropertiesJavaSkeleton(intface, intDecl);
// Write constructor
- writeConstructorJavaSkeleton(newSkelClass, intface);
+ writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
+ // Write constructor that is called when this object is a callback object
+ writeCallbackConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
+ // Write function to return didAlreadyInitWaitInvoke
+ writeReturnDidAlreadyInitWaitInvoke();
// Write methods
- writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false);
+ writeMethodJavaSkeleton(methods, intDecl);
// Write method helper
writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
// Write waitRequestInvokeMethod() - main loop
- writeJavaWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
+ writeJavaWaitRequestInvokeMethod(methods, intDecl, intface);
println("}");
pw.close();
System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
}
}
+
+/*================================================================================
+ *
+ * C++ generation
+ *
+ *================================================================================/
/**
- * HELPER: writePropertiesJavaCallbackSkeleton() writes the properties of the callback skeleton class
+ * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
*/
- private void writePropertiesJavaCallbackSkeleton(String intface, boolean callbackExist) {
+ private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
- println("private " + intface + " mainObj;");
- // For callback skeletons, this is its own object Id
- println("private static int objectId = 0;");
- // Callback
- if (callbackExist) {
- println("private static int objIdCnt = 0;");
- println("private IoTRMICall rmiCall;");
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
+ intDecl.getMethodId(method) + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+ // Check for params with driver class types and exchange it
+ // with its remote interface
+ String paramType = checkAndGetParamClass(methPrmTypes.get(i));
+ paramType = checkAndGetCplusType(paramType);
+ // Check for arrays - translate into vector in C++
+ String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
+ print(paramComplete);
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(") = 0;");
}
- println("\n");
}
/**
- * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class
+ * HELPER: writeMethodCplusInterface() writes the method of the interface
*/
- private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface) {
-
- println("public " + newSkelClass + "(" + intface + " _mainObj, int _objectId) throws Exception {");
- println("mainObj = _mainObj;");
- println("objectId = _objectId;");
- println("}\n");
- }
+ private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
-
- /**
- * HELPER: writeMethodHelperJavaCallbackSkeleton() writes the method helper of the callback skeleton class
- */
- private void writeMethodHelperJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
-
- // Use this set to handle two same methodIds
- Set<String> uniqueMethodIds = new HashSet<String>();
- for (String method : methods) {
-
- List<String> methParams = intDecl.getMethodParams(method);
- List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
- if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
- String methodId = intDecl.getMethodId(method);
- print("public void ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + intDecl.getMethodNumId(method);
- else
- uniqueMethodIds.add(methodId);
- String retType = intDecl.getMethodType(method);
- print(helperMethod + "(");
- boolean begin = true;
- for (int i = 0; i < methParams.size(); i++) { // Print size variables
- String paramType = methPrmTypes.get(i);
- String param = methParams.get(i);
- String simpleType = getSimpleType(paramType);
- if (isStructClass(simpleType)) {
- if (!begin) { // Generate comma for not the beginning variable
- print(", "); begin = false;
- }
- int methodNumId = intDecl.getMethodNumId(method);
- print("int struct" + methodNumId + "Size" + i);
- }
- // TODO: Need to create comma separation
- }
- // Check if this is "void"
- if (retType.equals("void"))
- println(", IoTRMIObject rmiObj) {");
- else
- println(", IoTRMIObject rmiObj) throws IOException {");
- writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
- println("}\n");
- } else {
- String methodId = intDecl.getMethodId(method);
- print("public void ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + intDecl.getMethodNumId(method);
- else
- uniqueMethodIds.add(methodId);
- // Check if this is "void"
- String retType = intDecl.getMethodType(method);
- if (retType.equals("void"))
- println(helperMethod + "(IoTRMIObject rmiObj) {");
- else
- println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {");
- // Now, write the helper body of skeleton!
- writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
- println("}\n");
- }
- }
- // Write method helper for structs
- writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl);
- }
-
-
- /**
- * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the main loop of the skeleton class
- */
- private void writeJavaCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
-
- // Use this set to handle two same methodIds
- Set<String> uniqueMethodIds = new HashSet<String>();
- println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {");
- // Write variables here if we have callbacks or enums or structs
- writeCountVarStructJavaSkeleton(methods, intDecl);
- // Write variables here if we have callbacks or enums or structs
- println("int methodId = rmiObj.getMethodId();");
- // TODO: code the permission check here!
- println("switch (methodId) {");
- // Print methods and method Ids
- for (String method : methods) {
- String methodId = intDecl.getMethodId(method);
- int methodNumId = intDecl.getMethodNumId(method);
- print("case " + methodNumId + ": ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + methodNumId;
- else
- uniqueMethodIds.add(methodId);
- print(helperMethod + "(");
- if (writeInputCountVarStructJavaSkeleton(method, intDecl))
- println(", rmiObj); break;");
- else
- println("rmiObj); break;");
- }
- String method = "___initCallBack()";
- // Print case -9999 (callback handler) if callback exists
- if (callbackExist) {
- int methodId = intDecl.getHelperMethodNumId(method);
- println("case " + methodId + ": ___regCB(rmiObj); break;");
- }
- writeMethodCallStructJavaCallbackSkeleton(methods, intDecl);
- println("default: ");
- println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
- println("}");
- println("}\n");
- }
-
-
- /**
- * generateJavaCallbackSkeletonClass() generate callback skeletons based on the methods list in Java
- */
- public void generateJavaCallbackSkeletonClass() throws IOException {
-
- // Create a new directory
- String path = createDirectories(dir, subdir);
- for (String intface : mapIntfacePTH.keySet()) {
- // Open a new file to write into
- String newSkelClass = intface + "_CallbackSkeleton";
- FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
- pw = new PrintWriter(new BufferedWriter(fw));
- // Pass in set of methods and get import classes
- DeclarationHandler decHandler = mapIntDeclHand.get(intface);
- InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
- List<String> methods = intDecl.getMethods();
- Set<String> importClasses = getImportClasses(methods, intDecl);
- List<String> stdImportClasses = getStandardJavaImportClasses();
- List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
- printImportStatements(allImportClasses);
- // Find out if there are callback objects
- Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
- boolean callbackExist = !callbackClasses.isEmpty();
- // Write class header
- println("");
- println("public class " + newSkelClass + " implements " + intface + " {\n");
- // Write properties
- writePropertiesJavaCallbackSkeleton(intface, callbackExist);
- // Write constructor
- writeConstructorJavaCallbackSkeleton(newSkelClass, intface);
- // Write methods
- writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true);
- // Write method helper
- writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
- // Write waitRequestInvokeMethod() - main loop
- writeJavaCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
- println("}");
- pw.close();
- System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".java...");
- }
- }
-
-
- /**
- * HELPER: writeMethodCplusLocalInterface() writes the method of the interface
- */
- private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
-
- for (String method : methods) {
-
- List<String> methParams = intDecl.getMethodParams(method);
- List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
- print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
- intDecl.getMethodId(method) + "(");
- for (int i = 0; i < methParams.size(); i++) {
- // Check for params with driver class types and exchange it
- // with its remote interface
- String paramType = checkAndGetParamClass(methPrmTypes.get(i));
- paramType = checkAndGetCplusType(paramType);
- // Check for arrays - translate into vector in C++
- String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
- print(paramComplete);
- // Check if this is the last element (don't print a comma)
- if (i != methParams.size() - 1) {
- print(", ");
- }
- }
- println(") = 0;");
- }
- }
-
-
- /**
- * HELPER: writeMethodCplusInterface() writes the method of the interface
- */
- private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
-
- for (String method : methods) {
+ for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
// Write file headers
println("#ifndef _" + stType.toUpperCase() + "_HPP__");
println("#define _" + stType.toUpperCase() + "_HPP__");
+ println("using namespace std;");
println("struct " + stType + " {");
List<String> structMemberTypes = structDecl.getMemberTypes(stType);
List<String> structMembers = structDecl.getMembers(stType);
Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
printIncludeStatements(includeClasses); println("");
println("using namespace std;\n");
- // Write enum if any...
- //EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
- //writeEnumCplus(enumDecl);
- // Write struct if any...
- //StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
- //writeStructCplus(structDecl);
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ if (!intface.equals(mainClass)) // Forward declare if not main class
+ writeMethodCplusInterfaceForwardDecl(methods, intDecl, callbackClasses, true);
println("class " + intface); println("{");
println("public:");
// Write methods
}
+ /**
+ * HELPER: writeMethodCplusInterfaceForwardDecl() writes the forward declaration of the interface
+ */
+ private void writeMethodCplusInterfaceForwardDecl(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, boolean needNewIntface) {
+
+ Set<String> isDefined = new HashSet<String>();
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ // Check if this has callback object
+ if (callbackClasses.contains(paramType)) {
+ if (!isDefined.contains(paramType)) {
+ if (needNewIntface)
+ println("class " + getStubInterface(paramType) + ";\n");
+ else
+ println("class " + paramType + ";\n");
+ isDefined.add(paramType);
+ }
+ }
+ }
+ }
+ }
+
+
/**
* generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
* <p>
println("#ifndef _" + newIntface.toUpperCase() + "_HPP__");
println("#define _" + newIntface.toUpperCase() + "_HPP__");
println("#include <iostream>");
+ updateIntfaceObjIdMap(intface, newIntface);
// Pass in set of methods and get import classes
- Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false);
- List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
- List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
- printIncludeStatements(allIncludeClasses); println("");
+ Set<String> methods = intMeth.getValue();
+ Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, false);
+ printIncludeStatements(includeClasses); println("");
println("using namespace std;\n");
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ writeMethodCplusInterfaceForwardDecl(methods, intDecl, callbackClasses, false);
println("class " + newIntface);
println("{");
println("public:");
// Write methods
- writeMethodCplusInterface(intMeth.getValue(), intDecl);
+ writeMethodCplusInterface(methods, intDecl);
println("};");
println("#endif");
pw.close();
/**
- * HELPER: writeMethodCplusStub() writes the method of the stub
+ * HELPER: writeMethodDeclCplusStub() writes the method declarations of the stub
*/
- private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
+ private void writeMethodDeclCplusStub(Collection<String> methods, InterfaceDecl intDecl) {
for (String method : methods) {
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
intDecl.getMethodId(method) + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
+ String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+ print(methParamComplete);
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodCplusStub() writes the methods of the stub
+ */
+ private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
+
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ // Print the mutex lock first
+ int methodNumId = intDecl.getMethodNumId(method);
+ String mutexVar = "mtx" + newStubClass + "MethodExec" + methodNumId;
+ println("mutex " + mutexVar + ";");
+ print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " + newStubClass + "::" +
+ intDecl.getMethodId(method) + "(");
boolean isCallbackMethod = false;
- String callbackType = null;
+ Set<String> callbackType = new HashSet<String>();
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;
- callbackType = paramType;
+ //callbackType = paramType;
+ callbackType.add(paramType);
// Even if there're 2 callback arguments, we expect them to be of the same interface
}
String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
}
}
println(") { ");
+ println("lock_guard<mutex> guard(" + mutexVar + ");");
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);
- writeInitCallbackSendInfoCplusStub(intDecl);
- }
+
}
}
+ /**
+ * HELPER: writeCallbackInstantiationMethodBodyCplusStub() writes the callback object instantiation in the method of the stub class
+ */
+ private void writeCallbackInstantiationMethodBodyCplusStub(String paramIdent, String callbackType, int counter) {
+
+ println("auto it" + counter + " = IoTRMIUtil::mapSkel->find(" + paramIdent + ");");
+ println("if (it" + counter + " == IoTRMIUtil::mapSkel->end()) {");
+ println("int newObjIdSent = rmiComm->getObjectIdCounter();");
+ println("objIdSent" + counter + ".push_back(newObjIdSent);");
+ println("rmiComm->decrementObjectIdCounter();");
+ println(callbackType + "_Skeleton* skel" + counter + " = new " + callbackType + "_Skeleton(" + paramIdent + ", rmiComm, newObjIdSent);");
+ println("IoTRMIUtil::mapSkel->insert(make_pair(" + paramIdent + ", skel" + counter + "));");
+ println("IoTRMIUtil::mapSkelId->insert(make_pair(" + paramIdent + ", newObjIdSent));");
+ println("thread th" + counter + " (&" + callbackType + "_Skeleton::___waitRequestInvokeMethod, std::ref(skel" + counter +
+ "), std::ref(skel" + counter +"));");
+ println("th" + counter + ".detach();");
+ println("while(!skel" + counter + "->didInitWaitInvoke());");
+ println("}");
+ println("else");
+ println("{");
+ println("auto itId = IoTRMIUtil::mapSkelId->find(" + paramIdent + ");");
+ println("objIdSent" + counter + ".push_back(itId->second);");
+ println("}");
+ }
+
+
/**
* HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
*/
private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
- List<String> methPrmTypes, String method, String callbackType) {
+ List<String> methPrmTypes, String method, Set<String> callbackType) {
// Check if this is single object, array, or list of objects
boolean isArrayOrList = false;
String callbackParam = null;
for (int i = 0; i < methParams.size(); i++) {
-
String paramType = methPrmTypes.get(i);
if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+ println("vector<int> objIdSent" + i + ";");
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++);");
+ if (isArrayOrList(paramType, param)) { // Generate loop
+ println("for (" + getGenericType(paramType) + "* cb : " + getSimpleIdentifier(param) + ") {");
+ writeCallbackInstantiationMethodBodyCplusStub("cb", returnGenericCallbackType(paramType), i);
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))
+ } else {
+ writeCallbackInstantiationMethodBodyCplusStub(getSimpleIdentifier(param), returnGenericCallbackType(paramType), i);
+ }
+ if (isArrayOrList)
println("}");
+ println("vector<int> ___paramCB" + i + " = objIdSent" + i + ";");
}
}
- println("int numParam = " + methParams.size() + ";");
- println("int methodId = " + intDecl.getMethodNumId(method) + ";");
- String retType = intDecl.getMethodType(method);
- String retTypeC = checkAndGetCplusType(retType);
- println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
- // Generate array of parameter types
- print("string paramCls[] = { ");
- for (int i = 0; i < methParams.size(); i++) {
- String paramType = methPrmTypes.get(i);
- if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
- print("\"int\"");
- } else { // Generate normal classes if it's not a callback object
- String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
- String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
- print("\"" + prmType + "\"");
- }
- 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;");
- }
}
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<int> paramEnum" + i + "(len);");
+ println("int len" + i + " = " + getSimpleIdentifier(param) + ".size();");
+ println("vector<int> 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<int> paramEnum" + i + "(1);");
/**
* HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
*/
- private void checkAndWriteEnumRetTypeCplusStub(String retType) {
+ private void checkAndWriteEnumRetTypeCplusStub(String retType, String method, InterfaceDecl intDecl) {
// 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<int> retEnumInt;");
println("void* retObj = &retEnumInt;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retObj);");
if (isArrayOrList(retType, retType)) { // An array or vector
println("int retLen = retEnumInt.size();");
println("vector<" + pureType + "> retVal(retLen);");
/**
- * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
+ * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup
*/
- private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
- List<String> methPrmTypes, String method) {
-
- println("int numParam = " + methParams.size() + ";");
- println("int methodId = " + intDecl.getMethodNumId(method) + ";");
- String retType = intDecl.getMethodType(method);
- String retTypeC = checkAndGetCplusType(retType);
- println("string retType = \"" + checkAndGetCplusArrayType(getEnumType(retTypeC)) + "\";");
- // Generate array of parameter types
- print("string paramCls[] = { ");
+ private void checkAndWriteStructSetupCplusStub(List<String> methParams, List<String> methPrmTypes,
+ InterfaceDecl intDecl, String method) {
+
+ // Iterate and find struct declarations
for (int i = 0; i < methParams.size(); i++) {
- String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
- String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
- print("\"" + getEnumType(paramType) + "\"");
- // Check if this is the last element (don't print a comma)
- if (i != methParams.size() - 1) {
- print(", ");
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ // Check if this is enum type
+ println("int numParam" + i + " = 1;");
+ int methodNumId = intDecl.getMethodNumId(method);
+ String helperMethod = methodNumId + "struct" + i;
+ println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
+ //println("string retTypeStruct" + i + " = \"void\";");
+ println("string paramClsStruct" + i + "[] = { \"int\" };");
+ print("int structLen" + i + " = ");
+ if (isArrayOrList(paramType, param)) { // An array
+ println(getSimpleArrayType(param) + ".size();");
+ } else { // Just one element
+ println("1;");
+ }
+ println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };");
+ println("rmiComm->remoteCall(objectId, methodIdStruct" + i +
+ ", paramClsStruct" + i + ", paramObjStruct" + i +
+ ", numParam" + i + ");\n");
}
}
- println(" };");
- checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
- // Generate array of parameter objects
- print("void* paramObj[] = { ");
+ }
+
+
+ /**
+ * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params
+ */
+ private void writeLengthStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
+
+ // Iterate and find struct declarations - count number of params
for (int i = 0; i < methParams.size(); i++) {
- print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
- // Check if this is the last element (don't print a comma)
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int members = getNumOfMembers(simpleType);
+ if (isArrayOrList(paramType, param)) { // An array or list
+ String structLen = getSimpleIdentifier(param) + ".size()";
+ print(members + "*" + structLen);
+ } else
+ print(Integer.toString(members));
+ } else
+ print("1");
if (i != methParams.size() - 1) {
- print(", ");
+ print("+");
}
}
- println(" };");
- // Check if this is "void"
- if (retType.equals("void")) {
- println("void* retObj = NULL;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
- } else { // We do have a return value
- if (getParamCategory(retType) == ParamCategory.ENUM) {
- checkAndWriteEnumRetTypeCplusStub(retType);
- } else {
- if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
- println(checkAndGetCplusType(retType) + " retVal;");
- else
- println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
- println("void* retObj = &retVal;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
- println("return retVal;");
+ }
+
+
+ /**
+ * HELPER: writeStructMembersCplusStub() writes member parameters of struct
+ */
+ private void writeStructMembersCplusStub(String simpleType, String paramType, String param) {
+
+ // Get the struct declaration for this struct and generate initialization code
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ if (isArrayOrList(paramType, param)) { // An array or list
+ println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".size(); i++) {");
+ }
+ if (isArrayOrList(paramType, param)) { // An array or list
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("paramCls[pos] = \"" + prmTypeC + "\";");
+ print("paramObj[pos++] = &" + 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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("paramCls[pos] = \"" + prmTypeC + "\";");
+ print("paramObj[pos++] = &" + param + ".");
+ print(getSimpleIdentifier(members.get(i)));
+ println(";");
}
}
}
/**
- * HELPER: writePropertiesCplusStub() writes the properties of the stub class
+ * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
*/
- private void writePropertiesCplusPermission(String intface) {
+ private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes, Set<String> callbackType) {
- 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 + ";");
- println("const static set<int> set" + newObjectId + "Allowed;");
+ print("int numParam = ");
+ writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
+ println(";");
+ println("void* paramObj[numParam];");
+ println("string paramCls[numParam];");
+ println("int pos = 0;");
+ // Iterate again over the parameters
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ writeStructMembersCplusStub(simpleType, paramType, param);
+ } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
+ println("paramCls[pos] = \"int\";");
+ println("paramObj[pos++] = &___paramCB" + i + ";");
+ } else {
+ String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ println("paramCls[pos] = \"" + prmTypeC + "\";");
+ print("paramObj[pos++] = &");
+ print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
+ println(";");
+ }
}
- }
+
+ }
+
/**
- * HELPER: writePropertiesCplusStub() writes the properties of the stub class
+ * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement
*/
- private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
+ private void writeStructRetMembersCplusStub(String simpleType, String retType) {
- println("IoTRMICall *rmiCall;");
- //println("IoTRMIObject\t\t\t*rmiObj;");
- println("string address;");
- println("vector<int> 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();
- String callbackType = (String) it.next();
- println("// Callback properties");
- println("IoTRMIObject *rmiObj;");
- println("vector<" + callbackType + "*> vecCallbackObj;");
- println("static int objIdCnt;");
- // Generate permission stuff for callback stubs
- writePropertiesCplusPermission(callbackType);
+ // Get the struct declaration for this struct and generate initialization code
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ if (isArrayOrList(retType, retType)) { // An array or list
+ println("for(int i = 0; i < retLen; i++) {");
}
- println("\n");
+ if (isArrayOrList(retType, retType)) { // An array or list
+ for (int i = 0; i < members.size(); i++) {
+ String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
+ print("structRet[i]." + getSimpleIdentifier(members.get(i)));
+ println(" = retParam" + i + "[i];");
+ }
+ println("}");
+ } else { // Just one struct element
+ for (int i = 0; i < members.size(); i++) {
+ String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
+ print("structRet." + getSimpleIdentifier(members.get(i)));
+ println(" = retParam" + i + ";");
+ }
+ }
+ println("return structRet;");
}
/**
- * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
+ * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
*/
- private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
-
- println(newStubClass +
- "(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {");
- println("address = _address;");
- 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);");
- println("th1.detach();");
- println("___regCB();");
+ private void writeStructReturnCplusStub(String simpleType, String retType, String method, InterfaceDecl intDecl) {
+
+ // Minimum retLen is 1 if this is a single struct object
+ println("int retLen = 0;");
+ println("void* retLenObj = { &retLen };");
+ // Handle the returned struct!!!
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retLenObj);");
+ int numMem = getNumOfMembers(simpleType);
+ println("int numRet = " + numMem + "*retLen;");
+ println("string retCls[numRet];");
+ println("void* retObj[numRet];");
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ // Set up variables
+ if (isArrayOrList(retType, retType)) { // An array or list
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusType(memTypes.get(i));
+ String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
+ println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];");
+ }
+ } else { // Just one struct element
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusType(memTypes.get(i));
+ String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
+ println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";");
+ }
}
- println("}\n");
+ println("int retPos = 0;");
+ // Get the struct declaration for this struct and generate initialization code
+ if (isArrayOrList(retType, retType)) { // An array or list
+ println("for(int i = 0; i < retLen; i++) {");
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("retCls[retPos] = \"" + prmTypeC + "\";");
+ println("retObj[retPos++] = &retParam" + i + "[i];");
+ }
+ println("}");
+ } else { // Just one struct element
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("retCls[retPos] = \"" + prmTypeC + "\";");
+ println("retObj[retPos++] = &retParam" + i + ";");
+ }
+ }
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getStructObjects(retCls, numRet, retObj);");
+ if (isArrayOrList(retType, retType)) { // An array or list
+ println("vector<" + simpleType + "> structRet(retLen);");
+ } else
+ println(simpleType + " structRet;");
+ writeStructRetMembersCplusStub(simpleType, retType);
}
/**
- * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
+ * HELPER: writeWaitForReturnValueCplus() writes the synchronization part for return values
*/
- private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
+ private void writeWaitForReturnValueCplus(String method, InterfaceDecl intDecl, String getReturnValue) {
- println("~" + newStubClass + "() {");
- println("if (rmiCall != NULL) {");
- println("delete rmiCall;");
- println("rmiCall = NULL;");
- println("}");
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- println("if (rmiObj != NULL) {");
- println("delete rmiObj;");
- println("rmiObj = NULL;");
- println("}");
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- println("for(" + callbackType + "* cb : vecCallbackObj) {");
- println("delete cb;");
- println("cb = NULL;");
- println("}");
+ println("// Waiting for return value");
+ int methodNumId = intDecl.getMethodNumId(method);
+ println("while (!retValueReceived" + methodNumId + ");");
+ println(getReturnValue);
+ println("retValueReceived" + methodNumId + " = false;");
+ println("didGetReturnBytes.exchange(true);\n");
+ }
+
+
+ /**
+ * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
+ */
+ private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method, Set<String> callbackType, boolean isCallbackMethod) {
+
+ checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
+ println("int methodId = " + intDecl.getMethodNumId(method) + ";");
+ String retType = intDecl.getMethodType(method);
+ println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
+ checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
+ // Generate array of parameter types
+ if (isStructPresent(methParams, methPrmTypes)) {
+ writeStructParamClassCplusStub(methParams, methPrmTypes, callbackType);
+ } else {
+ println("int numParam = " + methParams.size() + ";");
+ print("string paramCls[] = { ");
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ if (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(" };");
+ // Generate array of parameter objects
+ print("void* paramObj[] = { ");
+ for (int i = 0; i < methParams.size(); 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(", ");
+ }
+ }
+ println(" };");
+ }
+ // Check if this is "void"
+ if (retType.equals("void")) {
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ } else { // We do have a return value
+ // Generate array of parameter types
+ if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
+ writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType, method, intDecl);
+ } else {
+ // Check if the return value NONPRIMITIVES
+ if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) {
+ checkAndWriteEnumRetTypeCplusStub(retType, method, intDecl);
+ } else {
+ //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+ if (isArrayOrList(retType,retType))
+ println(checkAndGetCplusType(retType) + " retVal;");
+ else {
+ println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
+ }
+ println("void* retObj = &retVal;");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retObj);");
+ println("return retVal;");
+ }
+ }
}
- println("}");
- println("");
}
/**
- * HELPER: writeCplusMethodCallbackPermission() writes permission checks in stub for callbacks
+ * HELPER: writePropertiesCplusPermission() writes the properties of the stub class
*/
- private void writeCplusMethodCallbackPermission(String intface) {
+ private void writePropertiesCplusPermission(String intface) {
- println("int methodId = IoTRMIObject::getMethodId(method);");
- // Get all the different stubs
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("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("}");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("static set<int> set" + newObjectId + "Allowed;");
+ }
+ }
+
+ /**
+ * HELPER: writePropertiesCplusStub() writes the properties of the stub class
+ */
+ private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
+
+ println("IoTRMIComm *rmiComm;");
+ // Get the object Id
+ Integer objId = mapIntfaceObjId.get(intface);
+ println("int objectId = " + objId + ";");
+ println("// Synchronization variables");
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("bool retValueReceived" + methodNumId + " = false;");
+ }
}
+ println("\n");
}
/**
- * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
+ * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
*/
- private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) {
+ private void writeConstructorCplusStub(String newStubClass, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
- println("void ___initCallBack() {");
- println("bool bResult = false;");
- println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
- println("while (true) {");
- println("char* method = rmiObj->getMethodBytes();");
- 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));");
- println("skel->invokeMethod(rmiObj);");
- 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("}");
- println("}");
+ println(newStubClass + "::" + newStubClass +
+ "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult) {");
+ println("rmiComm = new IoTRMICommClient(_portSend, _portRecv, _skeletonAddress, _rev, _bResult);");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm->registerStub(objectId, " + methodNumId + ", &retValueReceived" + methodNumId + ");");
+ }
+ }
+ println("IoTRMIUtil::mapStub->insert(make_pair(objectId, this));");
println("}\n");
}
/**
- * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization of callback
+ * HELPER: writeCallbackConstructorCplusStub() writes the callback constructor of the stub class
*/
- private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
+ private void writeCallbackConstructorCplusStub(String newStubClass, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
- // Generate info sending part
- println("void ___regCB() {");
- println("int numParam = 3;");
- String method = "___initCallBack()";
- println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
- println("string retType = \"void\";");
- println("string paramCls[] = { \"int\", \"string\", \"int\" };");
- println("int rev = 0;");
- println("void* paramObj[] = { &ports[0], &address, &rev };");
- println("void* retObj = NULL;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+ println(newStubClass + "::" + newStubClass + "(IoTRMIComm* _rmiComm, int _objectId) {");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm->registerStub(objectId, " + methodNumId + ", &retValueReceived" + methodNumId + ");");
+ }
+ }
println("}\n");
}
/**
- * generateCPlusStubClasses() generate stubs based on the methods list in C++
+ * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
+ */
+ private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
+
+ println(newStubClass + "::~" + newStubClass + "() {");
+ println("if (rmiComm != NULL) {");
+ println("delete rmiComm;");
+ println("rmiComm = NULL;");
+ println("}");
+ println("}");
+ println("");
+ }
+
+
+ /**
+ * generateCPlusStubClassesHpp() generate stubs based on the methods list in C++ (.hpp file)
*/
- public void generateCPlusStubClasses() throws IOException {
+ public void generateCPlusStubClassesHpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
boolean callbackExist = !callbackClasses.isEmpty();
- if (callbackExist) // Need thread library if this has callback
- println("#include <thread>");
+ println("#include <thread>");
+ println("#include <mutex>");
+ List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
+ printIncludeStatements(stdIncludeClasses); println("");
println("#include \"" + newIntface + ".hpp\""); println("");
println("using namespace std;"); println("");
println("class " + newStubClass + " : public " + newIntface); println("{");
println("private:\n");
- writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
+ writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses, methods, intDecl);
println("public:\n");
// Add default constructor and destructor
- println(newStubClass + "() { }"); println("");
- writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
- writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
+ println(newStubClass + "();");
+ // Declarations
+ println(newStubClass + "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult);");
+ println(newStubClass + "(IoTRMIComm* _rmiComm, int _objectId);");
+ println("~" + newStubClass + "();");
// Write methods
- writeMethodCplusStub(methods, intDecl, callbackClasses);
+ writeMethodDeclCplusStub(methods, intDecl);
print("}"); println(";");
- if (callbackExist)
- writePermissionInitializationCplus(intface, newStubClass, intDecl);
println("#endif");
pw.close();
System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
/**
- * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
- */
- private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
-
- println("IoTRMICall *rmiCall;");
- // Get the object Id
- println("static int objectId;");
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- println("// Callback properties");
- println("IoTRMIObject *rmiObj;");
- 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<int> ports;\n");
- writePropertiesCplusPermission(callbackType);
- }
- println("\n");
- }
-
-
- /**
- * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
+ * writeStubExternalCFunctions() generate external functions for .so file
*/
- private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
+ public void writeStubExternalCFunctions(String newStubClass) throws IOException {
- println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {");
- println("objectId = _objectId;");
- println("rmiCall = _rmiCall;");
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
- println("th1.detach();");
- println("___regCB();");
- }
+ println("extern \"C\" void* create" + newStubClass + "(void** params) {");
+ println("// Args: int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult");
+ println("return new " + newStubClass + "(*((int*) params[0]), *((int*) params[1]), ((string*) params[2])->c_str(), " +
+ "*((int*) params[3]), (bool*) params[4]);");
+ println("}\n");
+ println("extern \"C\" void destroy" + newStubClass + "(void* t) {");
+ println(newStubClass + "* obj = (" + newStubClass + "*) t;");
+ println("delete obj;");
+ println("}\n");
+ println("extern \"C\" void init" + newStubClass + "(void* t) {");
println("}\n");
}
/**
- * generateCPlusCallbackStubClasses() generate callback stubs based on the methods list in C++
+ * generateCPlusStubClassesCpp() generate stubs based on the methods list in C++ (.cpp file)
*/
- public void generateCPlusCallbackStubClasses() throws IOException {
+ public void generateCPlusStubClassesCpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
// Open a new file to write into
String newIntface = intMeth.getKey();
- String newStubClass = newIntface + "_CallbackStub";
- FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
+ String newStubClass = newIntface + "_Stub";
+ FileWriter fw = new FileWriter(path + "/" + newStubClass + ".cpp");
pw = new PrintWriter(new BufferedWriter(fw));
+ // Write file headers
+ println("#include <iostream>");
// Find out if there are callback objects
Set<String> methods = intMeth.getValue();
DeclarationHandler decHandler = mapIntDeclHand.get(intface);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
boolean callbackExist = !callbackClasses.isEmpty();
- // Write file headers
- println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
- println("#define _" + newStubClass.toUpperCase() + "_HPP__");
- println("#include <iostream>");
- if (callbackExist)
- println("#include <thread>");
- println("#include \"" + newIntface + ".hpp\""); println("");
+ println("#include \"" + newStubClass + ".hpp\""); println("");
+ for(String str: callbackClasses) {
+ if (intface.equals(mainClass))
+ println("#include \"" + str + "_Skeleton.cpp\"\n");
+ else
+ println("#include \"" + str + "_Skeleton.hpp\"\n");
+ }
println("using namespace std;"); println("");
- println("class " + newStubClass + " : public " + newIntface); println("{");
- println("private:\n");
- writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
- println("public:\n");
// Add default constructor and destructor
- println(newStubClass + "() { }"); println("");
- writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
+ writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
+ writeCallbackConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
// Write methods
- writeMethodCplusStub(methods, intDecl, callbackClasses);
- println("};");
- if (callbackExist)
- writePermissionInitializationCplus(intface, newStubClass, intDecl);
- println("#endif");
+ writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
+ // Write external functions for .so file
+ writeStubExternalCFunctions(newStubClass);
+ // TODO: Remove this later
+ if (intface.equals(mainClass)) {
+ println("int main() {");
+ println("return 0;");
+ println("}");
+ }
pw.close();
- System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
+ System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".cpp...");
}
}
}
private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
println(intface + " *mainObj;");
- // Callback
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- String exchangeType = checkAndGetParamClass(callbackType);
- println("// Callback properties");
- println("static int objIdCnt;");
- println("vector<" + exchangeType + "*> vecCallbackObj;");
- println("IoTRMICall *rmiCall;");
- }
- println("IoTRMIObject *rmiObj;\n");
+ println("IoTRMIComm *rmiComm;");
+ println("char* methodBytes;");
+ println("int methodLen;");
+ Integer objId = mapIntfaceObjId.get(intface);
+ println("int objectId = " + objId + ";");
// Keep track of object Ids of all stubs registered to this interface
writePropertiesCplusPermission(intface);
+ println("// Synchronization variables");
+ println("bool methodReceived = false;");
+ println("bool didAlreadyInitWaitInvoke = false;");
println("\n");
}
+ /**
+ * 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);
- print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ print("set<int> " + newSkelClass + "::set" + newObjectId + "Allowed { ");
Set<String> methodIds = intMeth.getValue();
int i = 0;
for (String methodId : methodIds) {
}
+ /**
+ * HELPER: writeStructPermissionCplusSkeleton() writes permission for struct helper
+ */
+ private void writeStructPermissionCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, String intface) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+ for (Map.Entry<String,Set<String>> 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<String> methods) {
- println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
+ println(newSkelClass + "::" + newSkelClass + "(" + intface + " *_mainObj, int _portSend, int _portRecv) {");
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("rmiComm = new IoTRMICommServer(_portSend, _portRecv, &_bResult);");
+ println("IoTRMIUtil::mapSkel->insert(make_pair(_mainObj, this));");
+ println("IoTRMIUtil::mapSkelId->insert(make_pair(_mainObj, objectId));");
+ println("rmiComm->registerSkeleton(objectId, &methodReceived);");
+ writeStructPermissionCplusSkeleton(methods, intDecl, intface);
+ println("thread th1 (&" + newSkelClass + "::___waitRequestInvokeMethod, this, this);");
+ println("th1.join();");
+ println("}\n");
+ }
+
+
+ /**
+ * HELPER: writeCallbackConstructorCplusSkeleton() writes the callback constructor of the skeleton class
+ */
+ private void writeCallbackConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
+
+ println(newSkelClass + "::" + newSkelClass + "(" + intface + " *_mainObj, IoTRMIComm *_rmiComm, int _objectId) {");
+ println("bool _bResult = false;");
+ println("mainObj = _mainObj;");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
+ println("rmiComm->registerSkeleton(objectId, &methodReceived);");
+ writeStructPermissionCplusSkeleton(methods, intDecl, intface);
println("}\n");
}
*/
private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
- println("~" + newSkelClass + "() {");
- println("if (rmiObj != NULL) {");
- println("delete rmiObj;");
- println("rmiObj = NULL;");
+ println(newSkelClass + "::~" + newSkelClass + "() {");
+ println("if (rmiComm != NULL) {");
+ println("delete rmiComm;");
+ println("rmiComm = NULL;");
println("}");
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- println("if (rmiCall != NULL) {");
- println("delete rmiCall;");
- println("rmiCall = NULL;");
- println("}");
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- String exchangeType = checkAndGetParamClass(callbackType);
- println("for(" + exchangeType + "* cb : vecCallbackObj) {");
- println("delete cb;");
- println("cb = NULL;");
- println("}");
- }
println("}");
println("");
}
/**
- * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
+ * HELPER: writeMethodDeclCplusSkeleton() writes the method declaration of the skeleton class
*/
- private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
-
- // This is a callback skeleton generation
- if (callbackSkeleton)
- println("void ___regCB(IoTRMIObject* rmiObj) {");
- else
- println("void ___regCB() {");
- println("int numParam = 3;");
- println("int param1 = 0;");
- println("string param2 = \"\";");
- println("int param3 = 0;");
- println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
- println("bool bResult = false;");
- println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
- println("}\n");
- }
-
-
- /**
- * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
- */
- private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
- Set<String> callbackClasses, boolean callbackSkeleton) {
+ private void writeMethodDeclCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
+ Set<String> callbackClasses) {
for (String method : methods) {
print(", ");
}
}
+ println(");");
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
+ */
+ private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, String newSkelClass) {
+
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ String methodId = intDecl.getMethodId(method);
+ String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
+ print(methodType + " " + newSkelClass + "::" + methodId + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+
+ String origParamType = methPrmTypes.get(i);
+ String paramType = checkAndGetParamClass(methPrmTypes.get(i));
+ String methPrmType = checkAndGetCplusType(paramType);
+ String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+ print(methParamComplete);
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
println(") {");
// Now, write the body of skeleton!
writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
println("}\n");
- if (isCallbackMethod)
- writeInitCallbackCplusSkeleton(callbackSkeleton);
}
}
/**
* HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
*/
- private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+ private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, Set<String> callbackType) {
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
- String exchParamType = checkAndGetParamClass(paramType);
- // Print array if this is array or list if this is a list of callback objects
- println("int numStubs" + i + " = 0;");
- }
+ if (checkCallbackType(paramType, callbackType)) // Check if this has callback object
+ println("vector<int> numStubIdArray" + i + ";");
}
}
+ /**
+ * HELPER: writeCallbackInstantiationCplusStubGeneration() writes the instantiation of callback stubs
+ */
+ private void writeCallbackInstantiationCplusStubGeneration(String exchParamType, int counter) {
+
+ println(exchParamType + "* newStub" + counter + " = NULL;");
+ println("auto it" + counter + " = IoTRMIUtil::mapStub->find(objIdRecv" + counter + ");");
+ println("if (it" + counter + " == IoTRMIUtil::mapStub->end()) {");
+ println("newStub" + counter + " = new " + exchParamType + "_Stub(rmiComm, objIdRecv" + counter + ");");
+ println("IoTRMIUtil::mapStub->insert(make_pair(objIdRecv" + counter + ", newStub" + counter + "));");
+ println("rmiComm->setObjectIdCounter(objIdRecv" + counter + ");");
+ println("rmiComm->decrementObjectIdCounter();");
+ println("}");
+ println("else {");
+ println("newStub" + counter + " = (" + exchParamType + "_Stub*) it" + counter + "->second;");
+ println("}");
+ }
+
+
/**
* HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
*/
- private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
+ private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, Set<String> callbackType) {
// Iterate over callback objects
for (int i = 0; i < methParams.size(); i++) {
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("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("objIdCnt++;");
+ println("vector<" + exchParamType + "*> stub" + i + ";");
+ println("for (int i = 0; i < numStubIdArray" + i + ".size(); i++) {");
+ println("int objIdRecv" + i + " = numStubIdArray" + i + "[i];");
+ writeCallbackInstantiationCplusStubGeneration(exchParamType, i);
+ println("stub" + i + ".push_back(newStub" + i + ");");
println("}");
} else {
- println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
- println("vecCallbackObj.push_back(stub" + i + ");");
- println("objIdCnt++;");
+ println("int objIdRecv" + i + " = numStubIdArray" + i + "[0];");
+ writeCallbackInstantiationCplusStubGeneration(exchParamType, i);
+ println(exchParamType + "* stub" + i + " = newStub" + i + ";");
}
}
}
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
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
}
+ /**
+ * HELPER: writeMethodInputParameters() writes the parameter variables for C++ skeleton
+ */
+ private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes,
+ Set<String> callbackClasses, String methodId) {
+
+ print(methodId + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ if (callbackClasses.contains(paramType))
+ print("stub" + i);
+ else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
+ print("paramEnum" + i);
+ else if (isStructClass(getGenericType(paramType))) // Struct type
+ print("paramStruct" + i);
+ else
+ print(getSimpleIdentifier(methParams.get(i)));
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
+ */
+ private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method, boolean isCallbackMethod, Set<String> callbackType,
+ String methodId, Set<String> callbackClasses) {
+
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
+ if (isCallbackMethod)
+ writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
+ checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
+ writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method);
+ // Check if this is "void"
+ String retType = intDecl.getMethodType(method);
+ // Check if this is "void"
+ if (retType.equals("void")) {
+ writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
+ } else { // We do have a return value
+ if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type
+ print(checkAndGetCplusType(retType) + " retEnum = ");
+ else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
+ print(checkAndGetCplusType(retType) + " retStruct = ");
+ else
+ print(checkAndGetCplusType(retType) + " retVal = ");
+ writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
+ checkAndWriteEnumRetTypeCplusSkeleton(retType);
+ if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
+ writeStructReturnCplusSkeleton(getSimpleArrayType(getGenericType(retType)), retType);
+ if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type
+ println("void* retObj = &retEnumInt;");
+ else
+ if (!isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
+ println("void* retObj = &retVal;");
+ String retTypeC = checkAndGetCplusType(retType);
+ if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
+ println("rmiComm->sendReturnObj(retObj, retCls, numRetObj, localMethodBytes);");
+ else
+ println("rmiComm->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\", localMethodBytes);");
+ }
+ }
+
+
/**
* HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
*/
// Generate array of parameter types
boolean isCallbackMethod = false;
- String callbackType = null;
+ Set<String> callbackType = new HashSet<String>();
print("string paramCls[] = { ");
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
if (callbackClasses.contains(paramType)) {
isCallbackMethod = true;
- callbackType = paramType;
- print("\"int\"");
+ callbackType.add(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 = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ print("\"" + paramTypeC + "\"");
}
if (i != methParams.size() - 1) {
print(", ");
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<int> paramEnumInt" + i + ";");
} else {
+ String methPrmType = checkAndGetCplusType(methParamType);
String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
- println(methParamComplete + ";");
+ println(methParamComplete + ";");
}
}
}
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
if (callbackClasses.contains(paramType))
- print("&numStubs" + i);
- else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
+ print("&numStubIdArray" + i);
+ else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
print("¶mEnumInt" + i);
else
print("&" + getSimpleIdentifier(methParams.get(i)));
}
}
println(" };");
- println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
- if (isCallbackMethod)
- writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
- checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
- String retType = intDecl.getMethodType(method);
- // Check if this is "void"
- if (retType.equals("void")) {
- print(methodId + "(");
+ // Write the return value part
+ writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
+ callbackType, methodId, callbackClasses);
+ }
+
+
+ /**
+ * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct
+ */
+ private void writeStructMembersCplusSkeleton(String simpleType, String paramType,
+ String param, String method, InterfaceDecl intDecl, int iVar) {
+
+ // Get the struct declaration for this struct and generate initialization code
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ int methodNumId = intDecl.getMethodNumId(method);
+ String counter = "struct" + methodNumId + "Size" + iVar;
+ // Set up variables
+ 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" + 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" + iVar + 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 = 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 = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("paramCls[pos] = \"" + prmTypeC + "\";");
+ println("paramObj[pos++] = ¶m" + iVar + i + ";");
+ }
+ }
+ }
+
+
+ /**
+ * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct
+ */
+ private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method) {
+
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ String counter = "struct" + methodNumId + "Size" + i;
+ // Declaration
+ if (isArrayOrList(paramType, param)) { // An array or list
+ println("vector<" + simpleType + "> paramStruct" + i + "(" + counter + ");");
+ } else
+ println(simpleType + " paramStruct" + i + ";");
+ // Initialize members
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ 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" + 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" + i + j + ";");
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement
+ */
+ private void writeStructReturnCplusSkeleton(String simpleType, String retType) {
+
+ // Minimum retLen is 1 if this is a single struct object
+ if (isArrayOrList(retType, retType))
+ println("int retLen = retStruct.size();");
+ else // Just single struct object
+ println("int retLen = 1;");
+ println("void* retLenObj = &retLen;");
+ println("rmiComm->sendReturnObj(retLenObj, \"int\", localMethodBytes);");
+ int numMem = getNumOfMembers(simpleType);
+ println("int numRetObj = " + numMem + "*retLen;");
+ println("string retCls[numRetObj];");
+ println("void* retObj[numRetObj];");
+ println("int retPos = 0;");
+ // Get the struct declaration for this struct and generate initialization code
+ StructDecl structDecl = getStructDecl(simpleType);
+ List<String> memTypes = structDecl.getMemberTypes(simpleType);
+ List<String> members = structDecl.getMembers(simpleType);
+ if (isArrayOrList(retType, retType)) { // An array or list
+ println("for(int i = 0; i < retLen; i++) {");
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("retCls[retPos] = \"" + prmTypeC + "\";");
+ print("retObj[retPos++] = &retStruct[i].");
+ print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
+ println(";");
+ }
+ println("}");
+ } else { // Just one struct element
+ for (int i = 0; i < members.size(); i++) {
+ String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
+ println("retCls[retPos] = \"" + prmTypeC + "\";");
+ print("retObj[retPos++] = &retStruct.");
+ print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
+ println(";");
+ }
+ }
+
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton
+ */
+ private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
+
+ // Generate array of parameter objects
+ boolean isCallbackMethod = false;
+ Set<String> callbackType = new HashSet<String>();
+ print("int numParam = ");
+ writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
+ 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);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i);
+ } else {
+ String prmType = returnGenericCallbackType(methPrmTypes.get(i));
+ if (callbackClasses.contains(prmType)) {
+ isCallbackMethod = true;
+ callbackType.add(prmType);
+ println("vector<int> numStubIdArray" + i + ";");
+ println("paramCls[pos] = \"int*\";");
+ println("paramObj[pos++] = &numStubIdArray" + i + ";");
+ } else { // Generate normal classes if it's not a callback object
+ String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
+ if (isEnumClass(getGenericType(paramTypeC))) { // Check if this is enum type
+ println("vector<int> paramEnumInt" + i + ";");
+ } else {
+ String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i));
+ println(methParamComplete + ";");
+ }
+ String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+ println("paramCls[pos] = \"" + prmTypeC + "\";");
+ if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
+ println("paramObj[pos++] = ¶mEnumInt" + i + ";");
+ else
+ println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";");
+ }
+ }
+ }
+ // Write the return value part
+ writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
+ callbackType, methodId, callbackClasses);
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperDeclCplusSkeleton() writes the method helper declarations of the skeleton class
+ */
+ private void writeMethodHelperDeclCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ Set<String> uniqueMethodIds = new HashSet<String>();
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
+ String methodId = intDecl.getMethodId(method);
+ print("void ___");
+ String helperMethod = methodId;
+ if (uniqueMethodIds.contains(methodId))
+ helperMethod = helperMethod + intDecl.getMethodNumId(method);
+ else
+ uniqueMethodIds.add(methodId);
+ String retType = intDecl.getMethodType(method);
+ print(helperMethod + "(");
+ boolean begin = true;
+ for (int i = 0; i < methParams.size(); i++) { // Print size variables
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ if (!begin) // Generate comma for not the beginning variable
+ print(", ");
+ else
+ begin = false;
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int struct" + methodNumId + "Size" + i);
+ }
+ }
+ println(", " + newSkelClass + "* skel);");
+ } else {
+ String methodId = intDecl.getMethodId(method);
+ print("void ___");
+ String helperMethod = methodId;
+ if (uniqueMethodIds.contains(methodId))
+ helperMethod = helperMethod + intDecl.getMethodNumId(method);
+ else
+ uniqueMethodIds.add(methodId);
+ // Check if this is "void"
+ String retType = intDecl.getMethodType(method);
+ println(helperMethod + "(" + newSkelClass + "* skel);");
+ }
+ }
+ // Write method helper for structs
+ writeMethodHelperStructDeclSetupCplusSkeleton(methods, intDecl, newSkelClass);
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperStructDeclSetupCplusSkeleton() writes the struct method helper declaration in skeleton class
+ */
+ private void writeMethodHelperStructDeclSetupCplusSkeleton(Collection<String> methods,
+ InterfaceDecl intDecl, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ // Check for params with structs
for (int i = 0; i < methParams.size(); i++) {
- String paramType = returnGenericCallbackType(methPrmTypes.get(i));
- if (callbackClasses.contains(paramType))
- print("stub" + i);
- else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
- print("paramEnum" + i);
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int ___");
+ String helperMethod = methodNumId + "struct" + i;
+ println(helperMethod + "(" + newSkelClass + "* skel);");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodBytesCopy() writes the methodBytes copy part in C++ skeleton
+ */
+ private void writeMethodBytesCopy() {
+
+ println("char* localMethodBytes = new char[methodLen];");
+ println("memcpy(localMethodBytes, skel->methodBytes, methodLen);");
+ println("didGetMethodBytes.exchange(true);");
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
+ */
+ private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
+ Set<String> callbackClasses, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ Set<String> uniqueMethodIds = new HashSet<String>();
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
+ String methodId = intDecl.getMethodId(method);
+ print("void " + newSkelClass + "::___");
+ String helperMethod = methodId;
+ if (uniqueMethodIds.contains(methodId))
+ helperMethod = helperMethod + intDecl.getMethodNumId(method);
else
- print(getSimpleIdentifier(methParams.get(i)));
- if (i != methParams.size() - 1) {
- print(", ");
+ uniqueMethodIds.add(methodId);
+ String retType = intDecl.getMethodType(method);
+ print(helperMethod + "(");
+ boolean begin = true;
+ for (int i = 0; i < methParams.size(); i++) { // Print size variables
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ if (!begin) // Generate comma for not the beginning variable
+ print(", ");
+ else
+ begin = false;
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int struct" + methodNumId + "Size" + i);
+ }
}
+ println(", " + newSkelClass + "* skel) {");
+ writeMethodBytesCopy();
+ writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
+ println("delete[] localMethodBytes;");
+ println("}\n");
+ } else {
+ String methodId = intDecl.getMethodId(method);
+ print("void " + newSkelClass + "::___");
+ String helperMethod = methodId;
+ if (uniqueMethodIds.contains(methodId))
+ helperMethod = helperMethod + intDecl.getMethodNumId(method);
+ else
+ uniqueMethodIds.add(methodId);
+ // Check if this is "void"
+ String retType = intDecl.getMethodType(method);
+ println(helperMethod + "(" + newSkelClass + "* skel) {");
+ writeMethodBytesCopy();
+ // Now, write the helper body of skeleton!
+ writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
+ println("delete[] localMethodBytes;");
+ println("}\n");
}
- println(");");
- } else { // We do have a return value
- if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
- print(checkAndGetCplusType(retType) + " retEnum = ");
- else
- print(checkAndGetCplusType(retType) + " retVal = ");
- print(methodId + "(");
+ }
+ // Write method helper for structs
+ writeMethodHelperStructSetupCplusSkeleton(methods, intDecl, newSkelClass);
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
+ */
+ private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
+ InterfaceDecl intDecl, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ // Check for params with structs
for (int i = 0; i < methParams.size(); i++) {
- String paramType = returnGenericCallbackType(methPrmTypes.get(i));
- if (callbackClasses.contains(paramType))
- print("stub" + i);
- else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
- print("paramEnum" + i);
- else
- print(getSimpleIdentifier(methParams.get(i)));
- if (i != methParams.size() - 1) {
- print(", ");
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int " + newSkelClass + "::___");
+ String helperMethod = methodNumId + "struct" + i;
+ println(helperMethod + "(" + newSkelClass + "* skel) {");
+ // Now, write the helper body of skeleton!
+ writeMethodBytesCopy();
+ println("string paramCls[] = { \"int\" };");
+ println("int numParam = 1;");
+ println("int param0 = 0;");
+ println("void* paramObj[] = { ¶m0 };");
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
+ println("return param0;");
+ println("delete[] localMethodBytes;");
+ println("}\n");
}
}
- println(");");
- checkAndWriteEnumRetTypeCplusSkeleton(retType);
- if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
- println("void* retObj = &retEnumInt;");
- else
- println("void* retObj = &retVal;");
- String retTypeC = checkAndGetCplusType(retType);
- println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");");
}
}
/**
- * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
+ * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class
*/
- private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
+ private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection<String> methods,
+ InterfaceDecl intDecl) {
// Use this set to handle two same methodIds
- Set<String> uniqueMethodIds = new HashSet<String>();
for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
- String methodId = intDecl.getMethodId(method);
- print("void ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + intDecl.getMethodNumId(method);
- else
- uniqueMethodIds.add(methodId);
- // Check if this is "void"
- String retType = intDecl.getMethodType(method);
- println(helperMethod + "() {");
- // Now, write the helper body of skeleton!
- writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
- println("}\n");
+ // Check for params with structs
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = methPrmTypes.get(i);
+ String param = methParams.get(i);
+ String simpleType = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int ___");
+ String helperMethod = methodNumId + "struct" + i;
+ println(helperMethod + "(IoTRMIObject* rmiObj) {");
+ // Now, write the helper body of skeleton!
+ println("string paramCls[] = { \"int\" };");
+ println("int numParam = 1;");
+ println("int param0 = 0;");
+ println("void* paramObj[] = { ¶m0 };");
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
+ println("return param0;");
+ println("}\n");
+ }
+ }
}
}
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("if (_objectId == object" + newObjectId + "Id) {");
+ int newObjectId = getNewIntfaceObjectId(newIntface);
+ println("if (_objectId == objectId) {");
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("else {");
- println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
- println("exit(-1);");
println("}");
+ println("else {");
+ println("continue;");
println("}");
}
}
/**
* HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
*/
- private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
+ private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
+ boolean callbackExist, String intface, String newSkelClass) {
// Use this set to handle two same methodIds
Set<String> uniqueMethodIds = new HashSet<String>();
- println("void ___waitRequestInvokeMethod() {");
+ println("void " + newSkelClass + "::___waitRequestInvokeMethod(" + newSkelClass + "* skel) {");
// Write variables here if we have callbacks or enums or structs
+ writeCountVarStructSkeleton(methods, intDecl);
+ println("skel->didAlreadyInitWaitInvoke = true;");
println("while (true) {");
- println("rmiObj->getMethodBytes();");
- println("int _objectId = rmiObj->getObjectId();");
- println("int methodId = rmiObj->getMethodId();");
+ println("if (!methodReceived) {");
+ println("continue;");
+ println("}");
+ println("skel->methodBytes = skel->rmiComm->getMethodBytes();");
+ println("skel->methodLen = skel->rmiComm->getMethodLength();");
+ println("methodReceived = false;");
+ println("int _objectId = skel->rmiComm->getObjectId(skel->methodBytes);");
+ println("int methodId = skel->rmiComm->getMethodId(skel->methodBytes);");
// Generate permission check
writeCplusMethodPermission(intface);
println("switch (methodId) {");
for (String method : methods) {
String methodId = intDecl.getMethodId(method);
int methodNumId = intDecl.getMethodNumId(method);
- print("case " + methodNumId + ": ___");
+ println("case " + methodNumId + ": {");
+ print("thread th" + methodNumId + " (&" + newSkelClass + "::___");
String helperMethod = methodId;
if (uniqueMethodIds.contains(methodId))
helperMethod = helperMethod + methodNumId;
else
uniqueMethodIds.add(methodId);
- println(helperMethod + "(); break;");
- }
- String method = "___initCallBack()";
- // Print case -9999 (callback handler) if callback exists
- if (callbackExist) {
- int methodId = intDecl.getHelperMethodNumId(method);
- println("case " + methodId + ": ___regCB(); break;");
+ print(helperMethod + ", std::ref(skel), ");
+ boolean structExists = writeInputCountVarStructCplusSkeleton(method, intDecl);
+ if (structExists)
+ print(", ");
+ println("skel);");
+ println("th" + methodNumId + ".detach(); break;");
+ println("}");
}
+ writeMethodCallStructCplusSkeleton(methods, intDecl);
println("default: ");
println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
- println("throw exception();");
+ println("return;");
println("}");
println("}");
println("}\n");
/**
- * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
+ * generateCplusSkeletonClassHpp() generate skeletons based on the methods list in C++ (.hpp file)
*/
- public void generateCplusSkeletonClass() throws IOException {
+ public void generateCplusSkeletonClassHpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
DeclarationHandler decHandler = mapIntDeclHand.get(intface);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
List<String> methods = intDecl.getMethods();
- Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
- List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
- printIncludeStatements(allIncludeClasses); println("");
+ printIncludeStatements(stdIncludeClasses); println("");
println("using namespace std;\n");
// Find out if there are callback objects
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
// Write properties
writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
println("public:\n");
- // Write constructor
- writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist);
+ // Write constructors
+ println(newSkelClass + "();");
+ println(newSkelClass + "(" + intface + "*_mainObj, int _portSend, int _portRecv);");
+ println(newSkelClass + "(" + intface + "*_mainObj, IoTRMIComm *rmiComm, int _objectId);");
// Write deconstructor
- writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
- // Write methods
- writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
- // Write method helper
- writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
- // Write waitRequestInvokeMethod() - main loop
- writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
+ println("~" + newSkelClass + "();");
+ // Write method declarations
+ println("bool didInitWaitInvoke();");
+ writeMethodDeclCplusSkeleton(methods, intDecl, callbackClasses);
+ // Write method helper declarations
+ writeMethodHelperDeclCplusSkeleton(methods, intDecl, newSkelClass);
+ // Write waitRequestInvokeMethod() declaration - main loop
+ println("void ___waitRequestInvokeMethod(" + newSkelClass + "* skel);");
println("};");
writePermissionInitializationCplus(intface, newSkelClass, intDecl);
println("#endif");
}
}
-
- /**
- * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
- */
- private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
-
- println(intface + " *mainObj;");
- // Keep track of object Ids of all stubs registered to this interface
- println("static int objectId;");
- // Callback
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- String exchangeType = checkAndGetParamClass(callbackType);
- println("// Callback properties");
- println("IoTRMICall* rmiCall;");
- println("vector<" + exchangeType + "*> vecCallbackObj;");
- println("static int objIdCnt;");
- }
- println("\n");
- }
-
-
/**
- * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
+ * HELPER: writeReturnDidAlreadyInitWaitInvoke() writes the function to return didAlreadyInitWaitInvoke
*/
- private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) {
+ private void writeReturnDidAlreadyInitWaitInvoke(String newSkelClass) {
- println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
- println("mainObj = _mainObj;");
- println("objectId = _objectId;");
- // Callback
- if (callbackExist) {
- println("objIdCnt = 0;");
- }
+ println("bool " + newSkelClass + "::didInitWaitInvoke() {");
+ println("return didAlreadyInitWaitInvoke;");
println("}\n");
}
/**
- * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
- */
- private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist,
- Set<String> callbackClasses) {
-
- println("~" + newStubClass + "() {");
- if (callbackExist) {
- // We assume that each class only has one callback interface for now
- println("if (rmiCall != NULL) {");
- println("delete rmiCall;");
- println("rmiCall = NULL;");
- println("}");
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- String exchangeType = checkAndGetParamClass(callbackType);
- println("for(" + exchangeType + "* cb : vecCallbackObj) {");
- println("delete cb;");
- println("cb = NULL;");
- println("}");
- }
- println("}");
- println("");
- }
-
-
- /**
- * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of the callback skeleton class
- */
- private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl,
- Set<String> callbackClasses) {
-
- // Use this set to handle two same methodIds
- Set<String> uniqueMethodIds = new HashSet<String>();
- for (String method : methods) {
-
- List<String> methParams = intDecl.getMethodParams(method);
- List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
- String methodId = intDecl.getMethodId(method);
- print("void ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + intDecl.getMethodNumId(method);
- else
- uniqueMethodIds.add(methodId);
- // Check if this is "void"
- String retType = intDecl.getMethodType(method);
- println(helperMethod + "(IoTRMIObject* rmiObj) {");
- // Now, write the helper body of skeleton!
- writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
- println("}\n");
- }
- }
-
-
- /**
- * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the main loop of the skeleton class
+ * writeSkelExternalCFunctions() generate external functions for .so file
*/
- private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
- boolean callbackExist) {
+ public void writeSkelExternalCFunctions(String newSkelClass, String intface) throws IOException {
- // Use this set to handle two same methodIds
- Set<String> uniqueMethodIds = new HashSet<String>();
- println("void invokeMethod(IoTRMIObject* rmiObj) {");
- // Write variables here if we have callbacks or enums or structs
- println("int methodId = rmiObj->getMethodId();");
- // TODO: code the permission check here!
- println("switch (methodId) {");
- // Print methods and method Ids
- for (String method : methods) {
- String methodId = intDecl.getMethodId(method);
- int methodNumId = intDecl.getMethodNumId(method);
- print("case " + methodNumId + ": ___");
- String helperMethod = methodId;
- if (uniqueMethodIds.contains(methodId))
- helperMethod = helperMethod + methodNumId;
- else
- uniqueMethodIds.add(methodId);
- println(helperMethod + "(rmiObj); break;");
- }
- String method = "___initCallBack()";
- // Print case -9999 (callback handler) if callback exists
- if (callbackExist) {
- int methodId = intDecl.getHelperMethodNumId(method);
- println("case " + methodId + ": ___regCB(rmiObj); break;");
- }
- println("default: ");
- println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
- println("throw exception();");
- println("}");
+ println("extern \"C\" void* create" + newSkelClass + "(void** params) {");
+ println("// Args: *_mainObj, int _portSend, int _portRecv");
+ println("return new " + newSkelClass + "((" + intface + "*) params[0], *((int*) params[1]), *((int*) params[2]));");
+ println("}\n");
+ println("extern \"C\" void destroy" + newSkelClass + "(void* t) {");
+ println(newSkelClass + "* obj = (" + newSkelClass + "*) t;");
+ println("delete obj;");
+ println("}\n");
+ println("extern \"C\" void init" + newSkelClass + "(void* t) {");
println("}\n");
}
-
/**
- * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++
+ * generateCplusSkeletonClassCpp() generate skeletons based on the methods list in C++ (.cpp file)
*/
- public void generateCplusCallbackSkeletonClass() throws IOException {
+ public void generateCplusSkeletonClassCpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
for (String intface : mapIntfacePTH.keySet()) {
// Open a new file to write into
- String newSkelClass = intface + "_CallbackSkeleton";
- FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
+ String newSkelClass = intface + "_Skeleton";
+ FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".cpp");
pw = new PrintWriter(new BufferedWriter(fw));
// Write file headers
- println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
- println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
println("#include <iostream>");
- println("#include \"" + intface + ".hpp\"\n");
+ println("#include \"" + newSkelClass + ".hpp\"\n");
// Pass in set of methods and get import classes
DeclarationHandler decHandler = mapIntDeclHand.get(intface);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
List<String> methods = intDecl.getMethods();
- Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
- List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
- List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
- printIncludeStatements(allIncludeClasses); println("");
// Find out if there are callback objects
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
boolean callbackExist = !callbackClasses.isEmpty();
+ for(String str: callbackClasses) {
+ if (intface.equals(mainClass))
+ println("#include \"" + getStubInterface(str) + "_Stub.cpp\"\n");
+ else
+ println("#include \"" + getStubInterface(str) + "_Stub.hpp\"\n");
+ }
println("using namespace std;\n");
- // Write class header
- println("class " + newSkelClass + " : public " + intface); println("{");
- println("private:\n");
- // Write properties
- writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
- println("public:\n");
// Write constructor
- writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist);
+ writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
+ // Write callback constructor
+ writeCallbackConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
// Write deconstructor
- writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
+ writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
+ // Write didInitWaitInvoke() to return bool
+ writeReturnDidAlreadyInitWaitInvoke(newSkelClass);
// Write methods
- writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
+ writeMethodCplusSkeleton(methods, intDecl, newSkelClass);
// Write method helper
- writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
+ writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses, newSkelClass);
// Write waitRequestInvokeMethod() - main loop
- writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
- println("};");
- println("#endif");
+ writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface, newSkelClass);
+ // Write external functions for .so file
+ writeSkelExternalCFunctions(newSkelClass, intface);
+ // TODO: Remove this later
+ if (intface.equals(mainClass)) {
+ println("int main() {");
+ println("return 0;");
+ println("}");
+ }
pw.close();
- System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
+ System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".cpp...");
}
}
}
- /**
- * generateReturnStmt() generate return statement based on methType
- */
- public String generateReturnStmt(String methType) {
-
- // Generate dummy returns for now
- if (methType.equals("short")||
- methType.equals("int") ||
- methType.equals("long") ||
- methType.equals("float")||
- methType.equals("double")) {
-
- return "1";
- } else if ( methType.equals("String")) {
-
- return "\"a\"";
- } else if ( methType.equals("char") ||
- methType.equals("byte")) {
-
- return "\'a\'";
- } else if ( methType.equals("boolean")) {
-
- return "true";
- } else {
- return "null";
- }
- }
-
-
/**
* setDirectory() sets a new directory for stub files
*/
public static void printUsage() {
System.out.println();
- System.out.println("Sentinel interface and stub compiler version 1.0");
+ System.out.println("Vigilia interface and stub compiler version 1.0");
System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group.");
System.out.println("All rights reserved.");
System.out.println("Usage:");
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;
/**================
- * Helper functions
+ * Basic helper functions
**================
*/
boolean newline=true;
/**
* This function converts Java to C++ type for compilation
*/
- private String convertType(String jType) {
+ private String convertType(String type) {
- return mapPrimitives.get(jType);
+ if (mapPrimitives.containsKey(type))
+ return mapPrimitives.get(type);
+ else
+ return type;
}
+ /**
+ * A collection of methods with print-to-file functionality
+ */
private void println(String str) {
if (newline) {
int tab = tablevel;
}
- // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, or USERDEFINED
+ // Check and find object Id for new interface in mapNewIntfaceObjId (callbacks)
+ // Throw an error if the new interface is not found!
+ // Basically the compiler needs to parse the policy (and requires) files for callback class first
+ private int getNewIntfaceObjectId(String newIntface) {
+
+ int retObjId = mapNewIntfaceObjId.get(newIntface);
+ return retObjId;
+ }
+
+
+ // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
private ParamCategory getParamCategory(String paramType) {
if (mapPrimitives.containsKey(paramType)) {
// Return full class name for non-primitives to generate Java import statements
- // e.g. java.util.Set for Set, java.util.Map for Map
+ // e.g. java.util.Set for Set
private String getNonPrimitiveJavaClass(String paramNonPrimitives) {
return mapNonPrimitivesJava.get(paramNonPrimitives);
// Return full class name for non-primitives to generate Cplus include statements
- // e.g. #include <set> for Set, #include <map> for Map
+ // e.g. #include <set> for Set
private String getNonPrimitiveCplusClass(String paramNonPrimitives) {
return mapNonPrimitivesCplus.get(paramNonPrimitives);
}
+ // 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() {
importClasses.add("java.util.List");
importClasses.add("java.util.ArrayList");
importClasses.add("java.util.Arrays");
- importClasses.add("iotrmi.Java.IoTRMICall");
- importClasses.add("iotrmi.Java.IoTRMIObject");
+ importClasses.add("java.util.Map");
+ importClasses.add("java.util.HashMap");
+ importClasses.add("java.util.concurrent.atomic.AtomicBoolean");
+ importClasses.add("iotrmi.Java.IoTRMIComm");
+ importClasses.add("iotrmi.Java.IoTRMICommClient");
+ importClasses.add("iotrmi.Java.IoTRMICommServer");
+ importClasses.add("iotrmi.Java.IoTRMIUtil");
return importClasses;
}
// Add the standard list first
importClasses.add("<vector>");
importClasses.add("<set>");
- importClasses.add("\"IoTRMICall.hpp\"");
- importClasses.add("\"IoTRMIObject.hpp\"");
+ importClasses.add("\"IoTRMIComm.hpp\"");
+ importClasses.add("\"IoTRMICommClient.hpp\"");
+ importClasses.add("\"IoTRMICommServer.hpp\"");
return importClasses;
}
- // Generate a set of standard classes for import statements
+ // Combine all classes for import statements
private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
allLibClasses.add(str);
}
}
-
return allLibClasses;
}
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;
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) {
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;
List<String> methParams = intDecl.getMethodParams(method);
for (int i = 0; i < methPrmTypes.size(); i++) {
+ String genericType = getGenericType(methPrmTypes.get(i));
String simpleType = getSimpleType(methPrmTypes.get(i));
String param = methParams.get(i);
if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
- } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
+ //} else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.USERDEFINED) {
// For original interface, we need it exchanged... not for stub interfaces
if (needExchange) {
- includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
- includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
+ //includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
+ includeClasses.add("\"" + exchangeParamType(getSimpleArrayType(genericType)) + ".hpp\"");
} else {
- includeClasses.add("\"" + simpleType + ".hpp\"");
- includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
+ //includeClasses.add("\"" + simpleType + ".hpp\"");
+ includeClasses.add("\"" + getSimpleArrayType(genericType) + ".hpp\"");
}
- } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) {
- includeClasses.add("\"" + simpleType + ".hpp\"");
- } else if (param.contains("[]")) {
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.ENUM) {
+ includeClasses.add("\"" + genericType + ".hpp\"");
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.STRUCT) {
+ includeClasses.add("\"" + genericType + ".hpp\"");
+ }
+ if (param.contains("[]")) {
// Check if this is array for C++; translate into vector
includeClasses.add("<vector>");
}
}
+ // Print import statements into file
private void printImportStatements(Collection<String> importClasses) {
for(String cls : importClasses) {
}
+ // Print include statements into file
private void printIncludeStatements(Collection<String> includeClasses) {
for(String cls : includeClasses) {
}
+ // Checks and gets type in C++
private String checkAndGetCplusType(String paramType) {
if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) {
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);
} 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 + "*";
} else
// Just return it as is if it's not non-primitives
return paramType;
- //return checkAndGetParamClass(paramType, true);
}
}
+ // 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 = getEnumCplusClsType(paramType);
+ if (!paramTypeRet.equals(paramType))
+ // Just return if it is an enum type
+ // Type will still be the same if it's not an enum type
+ return paramTypeRet;
+
+ // Check for array declaration
+ if (param.contains("[]")) {
+ paramTypeRet = getSimpleArrayType(paramType) + "*";
+ } else if (paramType.contains("<") && paramType.contains(">")) {
+ // Just return it as is if it's not an array
+ String type = paramType.split("<")[1].split(">")[0];
+ paramTypeRet = "vector<" + getGenericType(type) + ">";
+ } else
+ paramTypeRet = paramType;
+
+ return paramTypeRet;
+ }
+
+
// Detect array declaration, e.g. int A[],
// then generate type "int[]"
private String checkAndGetArray(String paramType, String param) {
}
- // Is array? For return type we put the return type as input parameter
+ // Is array?
+ // For return type we use retType as input parameter
private boolean isArray(String param) {
// Check for array declaration
// 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;
}
} 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");
}
}
comp.generateJavaLocalInterfaces();
comp.generateJavaInterfaces();
comp.generateJavaStubClasses();
- comp.generateJavaCallbackStubClasses();
comp.generateJavaSkeletonClass();
- comp.generateJavaCallbackSkeletonClass();
comp.generateEnumCplus();
comp.generateStructCplus();
comp.generateCplusLocalInterfaces();
comp.generateCPlusInterfaces();
- comp.generateCPlusStubClasses();
- comp.generateCPlusCallbackStubClasses();
- comp.generateCplusSkeletonClass();
- comp.generateCplusCallbackSkeletonClass();
+ comp.generateCPlusStubClassesHpp();
+ comp.generateCPlusStubClassesCpp();
+ comp.generateCplusSkeletonClassHpp();
+ comp.generateCplusSkeletonClassCpp();
} else {
// Check other options
while(i < args.length) {
// 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();
comp.generateJavaLocalInterfaces();
comp.generateJavaInterfaces();
comp.generateJavaStubClasses();
- comp.generateJavaCallbackStubClasses();
comp.generateJavaSkeletonClass();
- comp.generateJavaCallbackSkeletonClass();
} else {
comp.generateEnumCplus();
comp.generateStructCplus();
comp.generateCplusLocalInterfaces();
comp.generateCPlusInterfaces();
- comp.generateCPlusStubClasses();
- comp.generateCPlusCallbackStubClasses();
- comp.generateCplusSkeletonClass();
- comp.generateCplusCallbackSkeletonClass();
+ comp.generateCPlusStubClassesHpp();
+ comp.generateCPlusStubClassesCpp();
+ comp.generateCplusSkeletonClassHpp();
+ comp.generateCplusSkeletonClassCpp();
}
}
i = i + 2;
} 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");
}
}
}
-
-