+ /**
+ * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
+ */
+ private void writePropertiesCplusSkeleton(String intface) {
+
+ println(intface + " *mainObj;");
+ //println("private int ports;");
+ //println("private IoTRMICall rmiCall;");
+ println("IoTRMIObject *rmiObj;\n");
+ // Keep track of object Ids of all stubs registered to this interface
+ 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 + ";\t//" + newIntface);
+ }
+ // TODO: CALLBACKS!
+ // TODO: code the set of allowed functions here
+ println("\n");
+ }
+
+
+ /**
+ * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
+ */
+ private void writeConstructorCplusSkeleton(String newSkelClass, String intface) {
+
+ println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
+ println("bool _bResult = false;");
+ println("mainObj = _mainObj;");
+ println("rmiObj = new IoTRMIObject(_port, &_bResult);");
+ //println("set0Allowed = Arrays.asList(object0Permission);");
+ //println("___waitRequestInvokeMethod();");
+ println("}\n");
+ }
+
+
+ /**
+ * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
+ */
+ private void writeDeconstructorCplusSkeleton(String newSkelClass) {
+
+ println("~" + newSkelClass + "() {");
+ println("if (rmiObj != NULL) {");
+ println("delete rmiObj;");
+ println("rmiObj = NULL;");
+ println("}");
+ println("}");
+ println("");
+ // Check if this is callback!!! and print "delete rmiObj and vecCBObj"
+ }
+
+
+ /**
+ * HELPER: writeStdMethodBodyCplusSkeleton() writes the standard method body in the skeleton class
+ */
+ private void writeStdMethodBodyCplusSkeleton(List<String> methParams, String methodId, String methodType) {
+
+ if (methodType.equals("void"))
+ print("mainObj->" + methodId + "(");
+ else
+ print("return mainObj->" + methodId + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+
+ print(getSimpleIdentifier(methParams.get(i)));
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ }
+
+
+ /**
+ * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
+ */
+ private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+
+ 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 + " " + methodId + "(");
+ for (int i = 0; i < methParams.size(); 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(") {");
+ // Now, write the body of skeleton!
+ writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
+ println("}\n");
+ }
+ }
+
+
+ /**
+ * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
+ */
+ private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
+ List<String> methPrmTypes, String method, String methodId) {
+
+ // Generate array of parameter types
+ print("string paramCls[] = { ");
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
+ String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
+ print("\"" + paramType + "\"");
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(" };");
+ println("int numParam = " + methParams.size() + ";");
+ // Generate parameters
+ for (int i = 0; i < methParams.size(); i++) {
+ String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
+ String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+ println(methParamComplete + ";");
+ }
+ // Generate array of parameter objects
+ print("void* paramObj[] = { ");
+ for (int i = 0; i < methParams.size(); i++) {
+ print("&" + getSimpleIdentifier(methParams.get(i)));
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(" };");
+ println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
+ String retType = intDecl.getMethodType(method);
+ // Check if this is "void"
+ if (retType.equals("void")) {
+ print(methodId + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+ print(getSimpleIdentifier(methParams.get(i)));
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ } else { // We do have a return value
+ print(checkAndGetCplusType(retType) + " retVal = " + methodId + "(");
+ for (int i = 0; i < methParams.size(); i++) {
+ print(getSimpleIdentifier(methParams.get(i)));
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ println("void* retObj = &retVal;");
+ String retTypeC = checkAndGetCplusType(retType);
+ println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusArrayType(retTypeC) + "\");");
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
+ */
+ private void writeMethodHelperCplusSkeleton(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);
+ println("}\n");
+ }
+ }
+
+
+ /**
+ * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
+ */
+ private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl) {
+
+ // Use this set to handle two same methodIds
+ Set<String> uniqueMethodIds = new HashSet<String>();
+ println("void ___waitRequestInvokeMethod() {");
+ // Write variables here if we have callbacks or enums or structs
+ println("while (true) {");
+ println("rmiObj->getMethodBytes();");
+ println("int _objectId = rmiObj->getObjectId();");
+ 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 + "(); break;");
+ }
+ println("default: ");
+ println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
+ println("throw exception();");
+ println("}");
+ println("}");
+ println("}\n");
+ }
+
+
+ /**
+ * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
+ */
+ public void generateCplusSkeletonClass() throws IOException {
+
+ // Create a new directory
+ createDirectory(dir);
+ for (String intface : mapIntfacePTH.keySet()) {
+ // Open a new file to write into
+ String newSkelClass = intface + "_Skeleton";
+ FileWriter fw = new FileWriter(dir + "/" + newSkelClass + ".hpp");
+ 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");
+ // 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);
+ List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
+ List<String> allIncludeClasses = getAllImportClasses(stdIncludeClasses, includeClasses);
+ printIncludeStatements(allIncludeClasses); println("");
+ println("using namespace std;\n");
+ // Write class header
+ println("class " + newSkelClass + " : public " + intface); println("{");
+ println("private:\n");
+ // Write properties
+ writePropertiesCplusSkeleton(intface);
+ println("public:\n");
+ // Write constructor
+ writeConstructorCplusSkeleton(newSkelClass, intface);
+ // Write deconstructor
+ writeDeconstructorCplusSkeleton(newSkelClass);
+ // Write methods
+ writeMethodCplusSkeleton(methods, intDecl);
+ // Write method helper
+ writeMethodHelperCplusSkeleton(methods, intDecl);
+ // Write waitRequestInvokeMethod() - main loop
+ writeCplusWaitRequestInvokeMethod(methods, intDecl);
+ println("};");
+ println("#endif");
+ pw.close();
+ System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
+ }
+ }
+
+