From: rtrimana Date: Fri, 30 Sep 2016 22:40:26 +0000 (-0700) Subject: Fixing program structure; now accepting multiple policy files; cross-checking referen... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=077106e62391686836096f2bd04145fe64af80ac;p=iot2.git Fixing program structure; now accepting multiple policy files; cross-checking references in multiple policy files for USERDEFINED types to generate type-checked input parameters; better command line input --- diff --git a/config/iotpolicy/camerapolicy.pol b/config/iotpolicy/camerapolicy.pol index ac99558..7565bca 100644 --- a/config/iotpolicy/camerapolicy.pol +++ b/config/iotpolicy/camerapolicy.pol @@ -6,7 +6,7 @@ public interface Camera { public String MethodC(String E, Map F); public float MethodD(Set G, float H); public boolean MethodE(String I, boolean J); - public void MethodF(int K); + public void MethodF(LightBulb K); capability ImageCapture { description = "The quick brown fox jumps over the smart dog"; diff --git a/iotjava/Makefile b/iotjava/Makefile index 6b19677..9854cc8 100644 --- a/iotjava/Makefile +++ b/iotjava/Makefile @@ -19,7 +19,7 @@ compiler: PHONY += run run: - cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler camerapolicy.pol camerarequires.pol -java Java -cplus Cplus + cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler camerapolicy.pol camerarequires.pol lightbulbpolicy.pol lightbulbrequires.pol -cplus Cplus -java Java PHONY += doc doc: iotruntime iotinstaller diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index e79bea6..acd0a62 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,13 @@ 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; + /** Class IoTCompiler is the main interface/stub compiler for * files generation. This class calls helper classes * such as Parser, Lexer, InterfaceDecl, CapabilityDecl, @@ -34,13 +38,11 @@ public class IoTCompiler { /** * Class properties */ - 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; @@ -156,30 +158,9 @@ public class IoTCompiler { */ public IoTCompiler() { - ptHandler = new ParseTreeHandler(); - intDecl = null; - capDecl = null; - capDecl = 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); - pw = null; - dir = OUTPUT_DIRECTORY; - subdir = null; - } - - - public IoTCompiler(String _intface, ParseNode _pnPol, ParseNode _pnReq) { - - ptHandler = new ParseTreeHandler(_intface, _pnPol, _pnReq); - intDecl = null; - capDecl = null; - reqDecl = null; - mapCapabMethods = new HashMap>(); + mapIntfacePTH = new HashMap(); + mapIntDeclHand = new HashMap(); + mapInt2NewInts = new HashMap>>(); mapPrimitives = new HashMap(); arraysToMap(mapPrimitives, primitives, primitivesCplus); mapNonPrimitivesJava = new HashMap(); @@ -193,9 +174,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. @@ -203,16 +184,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); } @@ -222,11 +211,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) { @@ -237,6 +230,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) { @@ -247,143 +241,65 @@ 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); +/* for (String origint : mapInt2NewInts.keySet()) { - /** - * generateJavaLocalInterface() 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 generateJavaLocalInterface(String _intface) throws IOException { + System.out.println("Original Interface: " + origint); + Map> mapNewInt = mapInt2NewInts.get(origint); + for (String intf : mapNewInt.keySet()) { - // Create a new directory - createDirectory(dir); - // Open a new file to write into - String intface = _intface; - 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) { + System.out.println("\tNew Interface: " + intf); + Set methods = mapNewInt.get(intf); + for (String meth : 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(", "); + System.out.println("\t\tMethod: " + meth); } } - println(");"); - } - println("}"); - pw.close(); - System.out.println("IoTCompiler: Generated local interface " + intface + ".java..."); + }*/ } /** - * generateCplusLocalInterface() 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 generateCplusLocalInterface(String _intface) throws IOException { + public void generateJavaLocalInterfaces() throws IOException { // Create a new directory createDirectory(dir); - // Open a new file to write into - String intface = _intface; - 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)); + print(paramType + " " + methParams.get(i)); // Check if this is the last element (don't print a comma) if (i != methParams.size() - 1) { print(", "); @@ -393,48 +309,54 @@ 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(); + 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)); + 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(", "); @@ -445,116 +367,233 @@ 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++) { + 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 = 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(", "); + } } + 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)); + print(methPrmType + " " + 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)); - 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..."); } } @@ -589,7 +628,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) { @@ -607,9 +646,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"); @@ -630,8 +671,8 @@ public class IoTCompiler { Parser parse = new Parser(lexer,csf); pn = (ParseNode) parse.parse().value; } catch (Exception e) { - System.out.println("IoTCompiler: ERROR parsing policy file!"); e.printStackTrace(); + throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file); } return pn; @@ -713,12 +754,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; } @@ -776,7 +820,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) { @@ -794,7 +838,7 @@ 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) { @@ -872,65 +916,106 @@ public class IoTCompiler { // Check if this is generics if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { - // TODO: replace this with the proper stub interface name - return paramType + "Remote"; + return exchangeParamType(paramType); } else return paramType; } + // 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) { + + // 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."); + } + } + + public static void main(String[] args) throws Exception { - // Runtime options - if (args.length > 1) { - // Display help - if ((args[0].equals("--help") || - (args[0].equals("-h")))) { - IoTCompiler.printUsage(); - } else { + // 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 - ParseNode pnPol = IoTCompiler.parseFile(args[0]); + ParseNode pnPol = IoTCompiler.parseFile(args[i]); // Parse "requires" policy file - ParseNode pnReq = IoTCompiler.parseFile(args[1]); + ParseNode pnReq = IoTCompiler.parseFile(args[i+1]); // Get interface name String intface = ParseTreeHandler.getOrigIntface(pnPol); - 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(intface); - comp.generateJavaInterfaces(); - comp.generateJavaStubClasses(); - comp.generateCplusLocalInterface(intface); - comp.generateCPlusInterfaces(); - comp.generateCPlusStubClasses(); - } else { - // Check other options - int i = 2; - while(i < args.length) { - // Check whether is provided - if ((i + 1) < args.length) { + 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(intface); + comp.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); - } else if (args[i].equals("-cplus")) { - comp.generateCplusLocalInterface(intface); + } 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!"); } diff --git a/iotjava/iotpolicy/tree/CapabilityDecl.java b/iotjava/iotpolicy/tree/CapabilityDecl.java index e9c694a..a55f30a 100644 --- a/iotjava/iotpolicy/tree/CapabilityDecl.java +++ b/iotjava/iotpolicy/tree/CapabilityDecl.java @@ -10,12 +10,7 @@ import java.util.List; * @version 1.0 * @since 2016-09-20 */ -public class CapabilityDecl { - - /** - * Class properties - */ - private String origInt; +public class CapabilityDecl extends Declaration { /** * A "capability" statement: @@ -28,6 +23,10 @@ public class CapabilityDecl { * In this data structure we will record its capability name, i.e. ImageCapture * and its descriptions and methods. */ + + /** + * Class properties + */ private List listCapabs; // list of capabilities private List> listDescs; // list of descriptions private List> listMethods; // list of methods @@ -37,7 +36,7 @@ public class CapabilityDecl { */ public CapabilityDecl() { - origInt = null; + super(); listCapabs = new ArrayList(); listDescs = new ArrayList>(); listMethods = new ArrayList>(); @@ -46,7 +45,7 @@ public class CapabilityDecl { public CapabilityDecl(String _origInt) { - origInt = _origInt; + super(_origInt); listCapabs = new ArrayList(); listDescs = new ArrayList>(); listMethods = new ArrayList>(); diff --git a/iotjava/iotpolicy/tree/InterfaceDecl.java b/iotjava/iotpolicy/tree/InterfaceDecl.java index 51da7b7..15893e3 100644 --- a/iotjava/iotpolicy/tree/InterfaceDecl.java +++ b/iotjava/iotpolicy/tree/InterfaceDecl.java @@ -14,12 +14,7 @@ import java.util.Set; * @version 1.0 * @since 2016-09-20 */ -public class InterfaceDecl { - - /** - * Class properties - */ - private String origInt; +public class InterfaceDecl extends Declaration { /** * A "interface" statement: @@ -34,6 +29,10 @@ public class InterfaceDecl { * In this data structure we will record its interface name, i.e. Camera * its method names and the parameters for each method. */ + + /** + * Class properties + */ private List listMethods; // Method signature (no spaces), e.g. MethodA(intA,SpeakerB) private List listMethodIds; // Method identifiers, e.g. MethodA private List listMethodTypes; // Method types, e.g. void @@ -45,7 +44,7 @@ public class InterfaceDecl { */ public InterfaceDecl() { - origInt = null; + super(); listMethods = new ArrayList(); listMethodIds = new ArrayList(); listMethodTypes = new ArrayList(); @@ -56,7 +55,7 @@ public class InterfaceDecl { public InterfaceDecl(String _origInt) { - origInt = _origInt; + super(_origInt); listMethods = new ArrayList(); listMethodIds = new ArrayList(); listMethodTypes = new ArrayList(); diff --git a/iotjava/iotpolicy/tree/RequiresDecl.java b/iotjava/iotpolicy/tree/RequiresDecl.java index 5a92155..4170155 100644 --- a/iotjava/iotpolicy/tree/RequiresDecl.java +++ b/iotjava/iotpolicy/tree/RequiresDecl.java @@ -15,12 +15,7 @@ import java.util.Set; * @version 1.0 * @since 2016-09-20 */ -public class RequiresDecl { - - /** - * Class properties - */ - private String origInt; +public class RequiresDecl extends Declaration { /** * A "requires" statement: @@ -29,6 +24,10 @@ public class RequiresDecl { * In this data structure we will record its new interface name, i.e. CameraWithCaptureAndData * and its required capabilities, i.e. VideoRecording and ImageCapture. */ + + /** + * Class properties + */ private Map> mapRequires; /** @@ -36,14 +35,14 @@ public class RequiresDecl { */ public RequiresDecl() { - origInt = null; + super(); mapRequires = new HashMap>(); } public RequiresDecl(String _origInt) { - origInt = _origInt; + super(_origInt); mapRequires = new HashMap>(); }