X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=iotjava%2Fiotpolicy%2FIoTCompiler.java;h=4450f1d3c74a7e39b0a00069a92c158e9bb266cc;hb=2a853e3c4ad334c03378e28c771e32b4a4dbc758;hp=1107451282761cd3ab917065bb457b4163b4b79b;hpb=de12bab65360671de45c0cd5a2b1eff5450a3649;p=iot2.git diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index 1107451..4450f1d 100644 --- a/iotjava/iotpolicy/IoTCompiler.java +++ b/iotjava/iotpolicy/IoTCompiler.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,10 +17,15 @@ import iotpolicy.parser.Parser; import iotpolicy.tree.ParseNode; import iotpolicy.tree.ParseNodeVector; import iotpolicy.tree.ParseTreeHandler; +import iotpolicy.tree.Declaration; +import iotpolicy.tree.DeclarationHandler; import iotpolicy.tree.CapabilityDecl; import iotpolicy.tree.InterfaceDecl; import iotpolicy.tree.RequiresDecl; +import iotrmi.Java.IoTRMITypes; + + /** Class IoTCompiler is the main interface/stub compiler for * files generation. This class calls helper classes * such as Parser, Lexer, InterfaceDecl, CapabilityDecl, @@ -34,14 +40,11 @@ public class IoTCompiler { /** * Class properties */ - private String origInt; - private ParseTreeHandler ptHandler; - private InterfaceDecl intDecl; - private CapabilityDecl capDecl; - private RequiresDecl reqDecl; - private Map> mapCapabMethods; + // Maps multiple interfaces to multiple objects of ParseTreeHandler + private Map mapIntfacePTH; + private Map mapIntDeclHand; + private Map>> mapInt2NewInts; // Data structure to store our types (primitives and non-primitives) for compilation - //private Set setPrimitives; private Map mapPrimitives; private Map mapNonPrimitivesJava; private Map mapNonPrimitivesCplus; @@ -54,97 +57,6 @@ public class IoTCompiler { */ private final static String OUTPUT_DIRECTORY = "output_files"; - /** - * Primitive data types - */ - private final static String[] primitives = new String[] { - - "byte", - "Byte", - "short", - "Short", - "int", - "Integer", - "long", - "Long", - "float", - "Float", - "double", - "Double", - "boolean", - "Boolean", - "char", - "Character", - "string", - "String", - "void" - }; - - /** - * Primitive data types in C++ to map the primitives list - */ - private final static String[] primitivesCplus = new String[] { - - "char", - "char", - "short", - "short", - "int", - "int", - "long", - "long", - "float", - "float", - "double", - "double", - "bool", - "bool", - "char", - "char", - "string", - "string", - "void" - }; - - /** - * Non-primitive data types supported by this compiler - */ - private final static String[] nonPrimitives = new String[] { - - "Set", - "HashSet", - "Map", - "HashMap", - "List", - "ArrayList" - }; - - /** - * Non-primitive Java libraries based on the list above - */ - private final static String[] nonPrimitiveJavaLibs = new String[] { - - "java.util.Set", - "java.util.HashSet", - "java.util.Map", - "java.util.HashMap", - "java.util.List", - "java.util.ArrayList" - }; - - /** - * Non-primitive C++ libraries based on the list above - */ - private final static String[] nonPrimitiveCplusLibs = new String[] { - - "set", - "unordered_set", - "map", - "unordered_map", - "list", - "list" - }; - private enum ParamCategory { PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc. @@ -157,38 +69,15 @@ public class IoTCompiler { */ public IoTCompiler() { - origInt = null; - ptHandler = new ParseTreeHandler(); - intDecl = null; - capDecl = null; - capDecl = null; - mapCapabMethods = new HashMap>(); + mapIntfacePTH = new HashMap(); + mapIntDeclHand = new HashMap(); + mapInt2NewInts = new HashMap>>(); mapPrimitives = new HashMap(); - arraysToMap(mapPrimitives, primitives, primitivesCplus); + arraysToMap(mapPrimitives, IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus); mapNonPrimitivesJava = new HashMap(); - arraysToMap(mapNonPrimitivesJava, nonPrimitives, nonPrimitiveJavaLibs); + arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs); mapNonPrimitivesCplus = new HashMap(); - arraysToMap(mapNonPrimitivesCplus, nonPrimitives, nonPrimitiveCplusLibs); - pw = null; - dir = OUTPUT_DIRECTORY; - subdir = null; - } - - - public IoTCompiler(String _origInt, ParseNode _pnPol, ParseNode _pnReq) { - - origInt = _origInt; - ptHandler = new ParseTreeHandler(_origInt, _pnPol, _pnReq); - intDecl = null; - capDecl = null; - reqDecl = null; - mapCapabMethods = new HashMap>(); - mapPrimitives = new HashMap(); - arraysToMap(mapPrimitives, primitives, primitivesCplus); - mapNonPrimitivesJava = new HashMap(); - arraysToMap(mapNonPrimitivesJava, nonPrimitives, nonPrimitiveJavaLibs); - mapNonPrimitivesCplus = new HashMap(); - arraysToMap(mapNonPrimitivesCplus, nonPrimitives, nonPrimitiveCplusLibs); + arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus); pw = null; dir = OUTPUT_DIRECTORY; subdir = null; @@ -196,9 +85,9 @@ public class IoTCompiler { /** - * parsePolicyFile() parses policy file + * setParseTree() sets parse tree based on policy files. *

- * It also generates parse tree and + * It also generates parse tree (ParseTreeHandler) and * copies useful information from parse tree into * InterfaceDecl, CapabilityDecl, and RequiresDecl * data structures. @@ -206,16 +95,24 @@ public class IoTCompiler { * returned from tree-parsing for further process. * */ - public void parsePolicyFile() { + public void setParseTree(String origInt, ParseNode pnPol, ParseNode pnReq) { - ptHandler.processInterfaceDecl(); - intDecl = ptHandler.getInterfaceDecl(); + ParseTreeHandler ptHandler = new ParseTreeHandler(origInt, pnPol, pnReq); + DeclarationHandler decHandler = new DeclarationHandler(); + // Process ParseNode and generate Declaration objects + ptHandler.processInterfaceDecl(); + InterfaceDecl intDecl = ptHandler.getInterfaceDecl(); + decHandler.addInterfaceDecl(origInt, intDecl); ptHandler.processCapabilityDecl(); - capDecl = ptHandler.getCapabilityDecl(); - + CapabilityDecl capDecl = ptHandler.getCapabilityDecl(); + decHandler.addCapabilityDecl(origInt, capDecl); ptHandler.processRequiresDecl(); - reqDecl = ptHandler.getRequiresDecl(); + RequiresDecl reqDecl = ptHandler.getRequiresDecl(); + decHandler.addRequiresDecl(origInt, reqDecl); + + mapIntfacePTH.put(origInt, ptHandler); + mapIntDeclHand.put(origInt, decHandler); } @@ -225,11 +122,15 @@ public class IoTCompiler { * It is going to give list of methods for a certain interface * based on the declaration of capabilities. */ - public void getMethodsForIntface() { + public void getMethodsForIntface(String origInt) { + ParseTreeHandler ptHandler = mapIntfacePTH.get(origInt); + Map> mapNewIntMethods = new HashMap>(); // Get set of new interfaces, e.g. CameraWithCaptureAndData // Generate this new interface with all the methods it needs // from different capabilities it declares + DeclarationHandler decHandler = mapIntDeclHand.get(origInt); + RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(origInt); Set setIntfaces = reqDecl.getInterfaces(); for (String strInt : setIntfaces) { @@ -240,6 +141,7 @@ public class IoTCompiler { for (String strCap : listCapab) { // Get list of methods for each capability + CapabilityDecl capDecl = (CapabilityDecl) decHandler.getCapabilityDecl(origInt); List listCapabMeth = capDecl.getMethods(strCap); for (String strMeth : listCapabMeth) { @@ -250,143 +152,50 @@ public class IoTCompiler { } } // Add interface and methods information into map - mapCapabMethods.put(strInt, setMethods); + mapNewIntMethods.put(strInt, setMethods); } + // Map the map of interface-methods to the original interface + mapInt2NewInts.put(origInt, mapNewIntMethods); } /** - * generateJavaLocalInterface() writes the local interface to provide type-checking + * generateJavaLocalInterface() writes the local interface and provides type-checking. *

* It needs to rewrite and exchange USERDEFINED types in input parameters of stub * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording. * The local interface has to be the input parameter for the stub and the stub * interface has to be the input parameter for the local class. */ - public void generateJavaLocalInterface() throws IOException { + public void generateJavaLocalInterfaces() throws IOException { // Create a new directory createDirectory(dir); - // Open a new file to write into - String intface = origInt; - FileWriter fw = new FileWriter(dir + "/" + intface + ".java"); - pw = new PrintWriter(new BufferedWriter(fw)); - // Pass in set of methods and get import classes - List methods = intDecl.getMethods(); - Set importClasses = getImportClasses(methods); - printImportStatements(importClasses); - // Write interface header - println(""); - println("public interface " + intface + " {"); - // Write methods - for (String method : methods) { - - List methParams = intDecl.getMethodParams(method); - List methPrmTypes = intDecl.getMethodParamTypes(method); - print("public " + 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)); - print(paramType + " " + methParams.get(i)); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); - } - } - println(");"); - } - println("}"); - pw.close(); - System.out.println("IoTCompiler: Generated local interface " + intface + ".java..."); - } - - - /** - * generateCplusLocalInterface() writes the local interface to provide type-checking - *

- * It needs to rewrite and exchange USERDEFINED types in input parameters of stub - * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording. - * The local interface has to be the input parameter for the stub and the stub - * interface has to be the input parameter for the local class. - */ - public void generateCplusLocalInterface() throws IOException { - - // Create a new directory - createDirectory(dir); - // Open a new file to write into - String intface = origInt; - FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp"); - pw = new PrintWriter(new BufferedWriter(fw)); - // Write file headers - println("#include "); - // Pass in set of methods and get import classes - List methods = intDecl.getMethods(); - Set includeClasses = getIncludeClasses(methods); - printIncludeStatements(includeClasses); - println(""); - println("using namespace std;"); - println(""); - println("class " + intface); - println("{"); - println("public:"); - // Write methods - for (String method : methods) { - - List methParams = intDecl.getMethodParams(method); - List methPrmTypes = intDecl.getMethodParamTypes(method); - print("virtual " + convertType(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); - print(paramType + " " + methParams.get(i)); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); - } - } - println(") = 0;"); - } - print("}"); - println(";"); - pw.close(); - System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp..."); - } - - - /** - * generateJavaInterfaces() generate stub interfaces based on the methods list in Java - */ - public void generateJavaInterfaces() throws IOException { - - // Create a new directory - createDirectories(dir, subdir); - for (Map.Entry> intMeth : mapCapabMethods.entrySet()) { - + for (String intface : mapIntfacePTH.keySet()) { // Open a new file to write into - String newIntface = intMeth.getKey(); - FileWriter fw = new FileWriter(dir + "/" + subdir + "/" + newIntface + ".java"); + FileWriter fw = new FileWriter(dir + "/" + intface + ".java"); pw = new PrintWriter(new BufferedWriter(fw)); // Pass in set of methods and get import classes - Set importClasses = getImportClasses(intMeth.getValue()); + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); + List methods = intDecl.getMethods(); + Set importClasses = getImportClasses(methods, intDecl); printImportStatements(importClasses); // Write interface header println(""); - println("public interface " + newIntface + " {"); - List meths = intDecl.getMethods(); + println("public interface " + intface + " {"); // Write methods - for (String method : intMeth.getValue()) { + for (String method : methods) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); print("public " + intDecl.getMethodType(method) + " " + intDecl.getMethodId(method) + "("); for (int i = 0; i < methParams.size(); i++) { - print(methPrmTypes.get(i) + " " + methParams.get(i)); + // Check for params with driver class types and exchange it + // with its remote interface + String paramType = checkAndGetParamClass(methPrmTypes.get(i), false); + print(paramType + " " + methParams.get(i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -396,48 +205,60 @@ public class IoTCompiler { } println("}"); pw.close(); - System.out.println("IoTCompiler: Generated interface " + newIntface + ".java..."); + System.out.println("IoTCompiler: Generated local interface " + intface + ".java..."); } } /** - * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++ + * generateCplusLocalInterfaces() writes the local interfaces and provides type-checking. *

- * For C++ we use virtual classe as interface + * It needs to rewrite and exchange USERDEFINED types in input parameters of stub + * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording. + * The local interface has to be the input parameter for the stub and the stub + * interface has to be the input parameter for the local class. */ - public void generateCPlusInterfaces() throws IOException { + public void generateCplusLocalInterfaces() throws IOException { // Create a new directory - createDirectories(dir, subdir); - for (Map.Entry> intMeth : mapCapabMethods.entrySet()) { - + createDirectory(dir); + for (String intface : mapIntfacePTH.keySet()) { // Open a new file to write into - String newIntface = intMeth.getKey(); - FileWriter fw = new FileWriter(dir + "/" + subdir + "/" + newIntface + ".hpp"); + FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp"); pw = new PrintWriter(new BufferedWriter(fw)); // Write file headers println("#include "); - // Pass in set of methods and get import classes - Set includeClasses = getIncludeClasses(intMeth.getValue()); + // Pass in set of methods and get include classes + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); + List methods = intDecl.getMethods(); + + // DEBUGGG + Set includeClasses = getIncludeClasses(methods, intDecl); + printIncludeStatements(includeClasses); println(""); println("using namespace std;"); println(""); - println("class " + newIntface); + println("class " + intface); println("{"); println("public:"); // Write methods - for (String method : intMeth.getValue()) { + for (String method : methods) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); print("virtual " + convertType(intDecl.getMethodType(method)) + " " + intDecl.getMethodId(method) + "("); for (int i = 0; i < methParams.size(); i++) { - - String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); - print(methPrmType + " " + methParams.get(i)); + // Check for params with driver class types and exchange it + // with its remote interface + String paramType = checkAndGetParamClass(methPrmTypes.get(i), true); + paramType = checkAndGetCplusType(paramType); + // Check for arrays - translate into vector in C++ + String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i)); + //print(paramType + " " + param); + print(paramComplete); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -448,116 +269,236 @@ public class IoTCompiler { print("}"); println(";"); pw.close(); - System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp..."); + System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp..."); } } /** - * generateJavaStubClasses() generate stubs based on the methods list in Java + * generateJavaInterfaces() generate stub interfaces based on the methods list in Java */ - public void generateJavaStubClasses() throws IOException { + public void generateJavaInterfaces() throws IOException { // Create a new directory - createDirectories(dir, subdir); - for (Map.Entry> intMeth : mapCapabMethods.entrySet()) { + String path = createDirectories(dir, subdir); + for (String intface : mapIntfacePTH.keySet()) { + + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + + // Open a new file to write into + String newIntface = intMeth.getKey(); + FileWriter fw = new FileWriter(path + "/" + newIntface + ".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 importClasses = getImportClasses(intMeth.getValue(), intDecl); + printImportStatements(importClasses); + // Write interface header + println(""); + println("public interface " + newIntface + " {"); + List meths = intDecl.getMethods(); + // Write methods + for (String method : intMeth.getValue()) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + print("public " + intDecl.getMethodType(method) + " " + + intDecl.getMethodId(method) + "("); + for (int i = 0; i < methParams.size(); i++) { + String paramType = checkAndGetParamClass(methPrmTypes.get(i), false); + print(paramType + " " + methParams.get(i)); + //print(methPrmTypes.get(i) + " " + methParams.get(i)); + // Check if this is the last element (don't print a comma) + if (i != methParams.size() - 1) { + print(", "); + } + } + println(");"); + } + println("}"); + pw.close(); + System.out.println("IoTCompiler: Generated interface " + newIntface + ".java..."); + } + } + } - // Open a new file to write into - String newIntface = intMeth.getKey(); - String newStubClass = newIntface + "_Stub"; - FileWriter fw = new FileWriter(dir + "/" + subdir + "/" + newStubClass + ".java"); - pw = new PrintWriter(new BufferedWriter(fw)); - // Pass in set of methods and get import classes - Set importClasses = getImportClasses(intMeth.getValue()); - printImportStatements(importClasses); - // Write interface header - println(""); - println("public class " + newStubClass + " implements " + newIntface + " {"); - println(""); - // Write methods - for (String method : intMeth.getValue()) { - List methParams = intDecl.getMethodParams(method); - List methPrmTypes = intDecl.getMethodParamTypes(method); - print("public " + intDecl.getMethodType(method) + " " + - intDecl.getMethodId(method) + "("); - for (int i = 0; i < methParams.size(); i++) { + /** + * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++ + *

+ * For C++ we use virtual classe as interface + */ + public void generateCPlusInterfaces() throws IOException { - print(methPrmTypes.get(i) + " " + methParams.get(i)); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + // Create a new directory + String path = createDirectories(dir, subdir); + for (String intface : mapIntfacePTH.keySet()) { + + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + + // Open a new file to write into + String newIntface = intMeth.getKey(); + FileWriter fw = new FileWriter(path + "/" + newIntface + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); + // Write file headers + println("#include "); + // Pass in set of methods and get import classes + Set includeClasses = getIncludeClasses(intMeth.getValue(), intDecl); + printIncludeStatements(includeClasses); + println(""); + println("using namespace std;"); + println(""); + println("class " + newIntface); + println("{"); + println("public:"); + // Write methods + for (String method : intMeth.getValue()) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + print("virtual " + convertType(intDecl.getMethodType(method)) + " " + + intDecl.getMethodId(method) + "("); + for (int i = 0; i < methParams.size(); i++) { + String methPrmType = checkAndGetParamClass(methPrmTypes.get(i), true); + methPrmType = checkAndGetCplusType(methPrmType); + 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(") = 0;"); } - println(") {"); - // Check if this is not "void" - if (!intDecl.getMethodType(method).equals("void")) { - String retStmt = generateReturnStmt(intDecl.getMethodType(method)); - println("return " + retStmt + ";"); - } - println("}"); println(""); + print("}"); + println(";"); + pw.close(); + System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp..."); } - println("}"); - pw.close(); - System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java..."); } } /** - * generateCPlusStubClasses() generate stubs based on the methods list in C++ + * generateJavaStubClasses() generate stubs based on the methods list in Java */ - public void generateCPlusStubClasses() throws IOException { + public void generateJavaStubClasses() throws IOException { // Create a new directory - createDirectories(dir, subdir); - for (Map.Entry> intMeth : mapCapabMethods.entrySet()) { + String path = createDirectories(dir, subdir); + for (String intface : mapIntfacePTH.keySet()) { + + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + + // Open a new file to write into + String newIntface = intMeth.getKey(); + String newStubClass = newIntface + "_Stub"; + 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 importClasses = getImportClasses(intMeth.getValue(), intDecl); + printImportStatements(importClasses); + // Write interface header + println(""); + println("public class " + newStubClass + " implements " + newIntface + " {"); + println(""); + // Write methods + for (String method : intMeth.getValue()) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + print("public " + intDecl.getMethodType(method) + " " + + intDecl.getMethodId(method) + "("); + for (int i = 0; i < methParams.size(); i++) { + + print(methPrmTypes.get(i) + " " + methParams.get(i)); + // Check if this is the last element (don't print a comma) + if (i != methParams.size() - 1) { + print(", "); + } + } + println(") {"); + // Check if this is not "void" + if (!intDecl.getMethodType(method).equals("void")) { + String retStmt = generateReturnStmt(intDecl.getMethodType(method)); + println("return " + retStmt + ";"); + } + println("}"); println(""); + } + println("}"); + pw.close(); + System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java..."); + } + } + } - // Open a new file to write into - String newIntface = intMeth.getKey(); - String newStubClass = newIntface + "_Stub"; - FileWriter fw = new FileWriter(dir + "/" + subdir + "/" + newStubClass + ".hpp"); - pw = new PrintWriter(new BufferedWriter(fw)); - // Write file headers - println("#include "); - println("#include \"" + newIntface + ".hpp\""); println(""); - println("using namespace std;"); println(""); - println("class " + newStubClass + " : public " + newIntface); - println("{"); - println("public:"); println(""); - // Add default constructor and destructor - println(newStubClass + "() { }"); println(""); - println("~" + newStubClass + "() { }"); println(""); - // Write methods - for (String method : intMeth.getValue()) { - List methParams = intDecl.getMethodParams(method); - List methPrmTypes = intDecl.getMethodParamTypes(method); - print(convertType(intDecl.getMethodType(method)) + " " + - intDecl.getMethodId(method) + "("); - for (int i = 0; i < methParams.size(); i++) { + /** + * generateCPlusStubClasses() generate stubs based on the methods list in C++ + */ + public void generateCPlusStubClasses() throws IOException { - String methPrmType = checkAndGetCplusType(methPrmTypes.get(i)); - print(methPrmType + " " + methParams.get(i)); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + // Create a new directory + String path = createDirectories(dir, subdir); + for (String intface : mapIntfacePTH.keySet()) { + + Map> mapNewIntMethods = mapInt2NewInts.get(intface); + for (Map.Entry> intMeth : mapNewIntMethods.entrySet()) { + // Open a new file to write into + String newIntface = intMeth.getKey(); + String newStubClass = newIntface + "_Stub"; + FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp"); + pw = new PrintWriter(new BufferedWriter(fw)); + // Write file headers + println("#include "); + println("#include \"" + newIntface + ".hpp\""); println(""); + println("using namespace std;"); println(""); + println("class " + newStubClass + " : public " + newIntface); println("{"); + println("public:"); println(""); + // Add default constructor and destructor + println(newStubClass + "() { }"); println(""); + println("~" + newStubClass + "() { }"); println(""); + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface); + // Write methods + for (String method : intMeth.getValue()) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + print(convertType(intDecl.getMethodType(method)) + " " + + intDecl.getMethodId(method) + "("); + 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(") { "); - // Check if this is not "void" - if (!intDecl.getMethodType(method).equals("void")) { - String retStmt = generateReturnStmt(intDecl.getMethodType(method)); - if (retStmt.equals("null")) { // null = NULL in C++ - retStmt = "NULL"; + println(") { "); + // Check if this is not "void" + if (!intDecl.getMethodType(method).equals("void")) { + String retStmt = generateReturnStmt(intDecl.getMethodType(method)); + if (retStmt.equals("null")) { // null = NULL in C++ + retStmt = "NULL"; + } + println("return " + retStmt + ";"); } - println("return " + retStmt + ";"); + println("}"); println(""); } - println("}"); println(""); + print("}"); println(";"); + pw.close(); + System.out.println("IoTCompiler: Generated stub class " + newIntface + ".hpp..."); } - print("}"); println(";"); - pw.close(); - System.out.println("IoTCompiler: Generated stub class " + newIntface + ".hpp..."); } } @@ -575,11 +516,11 @@ public class IoTCompiler { methType.equals("double")) { return "1"; - } else if ( methType.equals("String") || - methType.equals("byte")) { + } else if ( methType.equals("String")) { return "\"a\""; - } else if ( methType.equals("char")) { + } else if ( methType.equals("char") || + methType.equals("byte")) { return "\'a\'"; } else if ( methType.equals("boolean")) { @@ -592,7 +533,7 @@ public class IoTCompiler { /** - * setDirectory() set a new directory for stub files + * setDirectory() sets a new directory for stub files */ public void setDirectory(String _subdir) { @@ -610,9 +551,11 @@ public class IoTCompiler { System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group."); System.out.println("All rights reserved."); System.out.println("Usage:"); - System.out.println("\tjava IoTCompiler --help / -h\t\t\t\t\tDisplay this help texts"); - System.out.println("\tjava IoTCompiler \t\tGenerate both Java and C++ stub files"); - System.out.println("\tjava IoTCompiler [options]"); + System.out.println("\tjava IoTCompiler -help / --help / -h\n"); + System.out.println("\t\tDisplay this help texts\n\n"); + System.out.println("\tjava IoTCompiler [ ]"); + System.out.println("\tjava IoTCompiler [ ] [options]\n"); + System.out.println("\t\tTake one or more pairs of main-req policy files, and generate Java and/or C++ files\n"); System.out.println("Options:"); System.out.println("\t-java\t\tGenerate Java stub files"); System.out.println("\t-cplus\t\tGenerate C++ stub files"); @@ -620,9 +563,30 @@ public class IoTCompiler { } - /**================================================ - * Helper functions to write stub codes into files - **================================================ + /** + * parseFile() prepares Lexer and Parser objects, then parses the file + */ + public static ParseNode parseFile(String file) { + + ParseNode pn = null; + try { + ComplexSymbolFactory csf = new ComplexSymbolFactory(); + ScannerBuffer lexer = + new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(file)),csf)); + Parser parse = new Parser(lexer,csf); + pn = (ParseNode) parse.parse().value; + } catch (Exception e) { + e.printStackTrace(); + throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file); + } + + return pn; + } + + + /**================ + * Helper functions + **================ */ boolean newline=true; int tablevel=0; @@ -695,12 +659,15 @@ public class IoTCompiler { // Create a directory and possibly a sub directory - private void createDirectories(String dir, String subdir) { + private String createDirectories(String dir, String subdir) { - createDirectory(dir); + String path = dir; + createDirectory(path); if (subdir != null) { - createDirectory(dir + "/" + subdir); + path = path + "/" + subdir; + createDirectory(path); } + return path; } @@ -758,7 +725,7 @@ public class IoTCompiler { // Generate a set of classes for import statements - private Set getImportClasses(Collection methods) { + private Set getImportClasses(Collection methods, InterfaceDecl intDecl) { Set importClasses = new HashSet(); for (String method : methods) { @@ -776,17 +743,24 @@ public class IoTCompiler { // Generate a set of classes for include statements - private Set getIncludeClasses(Collection methods) { + private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl) { Set includeClasses = new HashSet(); for (String method : methods) { List methPrmTypes = intDecl.getMethodParamTypes(method); - for (String paramType : methPrmTypes) { + List methParams = intDecl.getMethodParams(method); + for (int i = 0; i < methPrmTypes.size(); i++) { - String simpleType = getSimpleType(paramType); + String simpleType = getSimpleType(methPrmTypes.get(i)); + String param = methParams.get(i); if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) { - includeClasses.add(getNonPrimitiveCplusClass(simpleType)); + includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">"); + } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) { + includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\""); + } else if (param.contains("[]")) { + // Check if this is array for C++; translate into vector + includeClasses.add(""); } } } @@ -805,7 +779,7 @@ public class IoTCompiler { private void printIncludeStatements(Set includeClasses) { for(String cls : includeClasses) { - println("#include <" + cls + ">"); + println("#include " + cls); } } @@ -848,80 +822,136 @@ public class IoTCompiler { } + // Detect array declaration, e.g. int A[], + // then generate "int A[]" in C++ as "vector A" + private String checkAndGetCplusArray(String paramType, String param) { + + String paramComplete = null; + // Check for array declaration + if (param.contains("[]")) { + paramComplete = "vector<" + paramType + "> " + param.replace("[]",""); + } else + // Just return it as is if it's not an array + paramComplete = paramType + " " + param; + + return paramComplete; + } + + // Get simple types, e.g. HashSet for HashSet<...> // Basically strip off the "<...>" - private String checkAndGetParamClass(String paramType) { + private String checkAndGetParamClass(String paramType, boolean needPtr) { // Check if this is generics if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { - // TODO: replace this with the proper stub interface name - return paramType + "Remote"; + // If true then return with pointer (C++) + if (needPtr) + return exchangeParamType(paramType) + "*"; + else // Java, so no pointer needed + return exchangeParamType(paramType); } else return paramType; } - public static void main(String[] args) throws Exception { + // Returns the other interface for type-checking purposes for USERDEFINED + // classes based on the information provided in multiple policy files + // e.g. return CameraWithXXX instead of Camera + private String exchangeParamType(String intface) { - // Runtime options - if (args.length != 0) { - // Display help - if ((args[0].equals("--help") || - (args[0].equals("-h")))) { - IoTCompiler.printUsage(); + // Param type that's passed is the interface name we need to look for + // in the map of interfaces, based on available policy files. + DeclarationHandler decHandler = mapIntDeclHand.get(intface); + if (decHandler != null) { + // We've found the required interface policy files + RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(intface); + Set setExchInt = reqDecl.getInterfaces(); + if (setExchInt.size() == 1) { + Iterator iter = setExchInt.iterator(); + return (String) iter.next(); } 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!"); + } + } else { + // NULL value - this means policy files missing + throw new Error("IoTCompiler: Parameter type lookup failed for " + intface + + "... Please provide the necessary policy files for user-defined types." + + " 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++)."); + } + } + + + public static void main(String[] args) throws Exception { + + // If there is no argument or just "--help" or "-h", then invoke printUsage() + if ((args[0].equals("-help") || + args[0].equals("--help")|| + args[0].equals("-h")) || + (args.length == 0)) { + + IoTCompiler.printUsage(); + + } else if (args.length > 1) { + + IoTCompiler comp = new IoTCompiler(); + int i = 0; + do { // Parse main policy file - ComplexSymbolFactory csfPol = new ComplexSymbolFactory(); - ScannerBuffer lexerPol = - new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csfPol)); - Parser parsePol = new Parser(lexerPol,csfPol); - ParseNode pnPol = (ParseNode) parsePol.parse().value; + ParseNode pnPol = IoTCompiler.parseFile(args[i]); // Parse "requires" policy file - ComplexSymbolFactory csfReq = new ComplexSymbolFactory(); - ScannerBuffer lexerReq = - new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[1])),csfReq)); - Parser parseReq = new Parser(lexerReq,csfReq); - ParseNode pnReq = (ParseNode) parseReq.parse().value; + ParseNode pnReq = IoTCompiler.parseFile(args[i+1]); // Get interface name - String intFace = ParseTreeHandler.getOrigIntface(pnPol); - //System.out.println("IoTCompiler: Original interface: " + intFace); - IoTCompiler comp = new IoTCompiler(intFace, pnPol, pnReq); - // Generate all policy files if just policy file is provided - comp.parsePolicyFile(); - comp.getMethodsForIntface(); - if (args.length == 2) { - comp.generateJavaLocalInterface(); - comp.generateJavaInterfaces(); - comp.generateJavaStubClasses(); - comp.generateCplusLocalInterface(); - comp.generateCPlusInterfaces(); - comp.generateCPlusStubClasses(); - } else { - // Check other options - int i = 2; - while(i < args.length) { - // Check whether is provided - if ((i + 1) < args.length) { + String intface = ParseTreeHandler.getOrigIntface(pnPol); + comp.setParseTree(intface, pnPol, pnReq); + comp.getMethodsForIntface(intface); + i = i + 2; + // 1) Check if this is the last option before "-java" or "-cplus" + // 2) Check if this is really the last option (no "-java" or "-cplus") + } while(!args[i].equals("-java") && + !args[i].equals("-cplus") && + (i < args.length)); + + // Generate everything if we don't see "-java" or "-cplus" + if (i == args.length) { + comp.generateJavaLocalInterfaces(); + comp.generateJavaInterfaces(); + comp.generateJavaStubClasses(); + comp.generateCplusLocalInterfaces(); + comp.generateCPlusInterfaces(); + comp.generateCPlusStubClasses(); + } 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]); + } else { + if (i + 1 < args.length) { comp.setDirectory(args[i+1]); } else throw new Error("IoTCompiler: ERROR - please provide after option: " + args[i]); + if (args[i].equals("-java")) { - comp.generateJavaLocalInterface(); + comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); - } else if (args[i].equals("-cplus")) { - comp.generateCplusLocalInterface(); + } else { + comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); - } else - throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]); - i = i + 2; + } } + i = i + 2; } } - } else { - // Need at least the policy file name + // 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!"); }