package iotpolicy; import java_cup.runtime.ComplexSymbolFactory; import java_cup.runtime.ScannerBuffer; import java.io.*; 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; import iotpolicy.parser.Lexer; 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, * RequiresDecl, ParseTreeHandler, etc. * * @author Rahmadi Trimananda * @version 1.0 * @since 2016-09-22 */ public class IoTCompiler { /** * Class properties */ // 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 Map mapPrimitives; private Map mapNonPrimitivesJava; private Map mapNonPrimitivesCplus; private PrintWriter pw; private String dir; private String subdir; /** * Class constants */ 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. NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc. USERDEFINED // Non-supported type by default; assumed as driver classes } /** * Class constructors */ public IoTCompiler() { mapIntfacePTH = new HashMap(); mapIntDeclHand = new HashMap(); mapInt2NewInts = 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; } /** * setParseTree() sets parse tree based on policy files. *

* It also generates parse tree (ParseTreeHandler) and * copies useful information from parse tree into * InterfaceDecl, CapabilityDecl, and RequiresDecl * data structures. * Additionally, the data structure handles are * returned from tree-parsing for further process. * */ public void setParseTree(String origInt, ParseNode pnPol, ParseNode pnReq) { 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(); CapabilityDecl capDecl = ptHandler.getCapabilityDecl(); decHandler.addCapabilityDecl(origInt, capDecl); ptHandler.processRequiresDecl(); RequiresDecl reqDecl = ptHandler.getRequiresDecl(); decHandler.addRequiresDecl(origInt, reqDecl); mapIntfacePTH.put(origInt, ptHandler); mapIntDeclHand.put(origInt, decHandler); } /** * getMethodsForIntface() reads for methods in the data structure *

* It is going to give list of methods for a certain interface * based on the declaration of capabilities. */ 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) { // Initialize a set of methods Set setMethods = new HashSet(); // Get list of capabilities, e.g. ImageCapture, VideoRecording, etc. List listCapab = reqDecl.getCapabList(strInt); 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) { // Add methods into setMethods // This is to also handle redundancies (say two capabilities // share the same methods) setMethods.add(strMeth); } } // Add interface and methods information into map mapNewIntMethods.put(strInt, setMethods); } // Map the map of interface-methods to the original interface mapInt2NewInts.put(origInt, mapNewIntMethods); } /** * 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 generateJavaLocalInterfaces() throws IOException { // Create a new directory createDirectory(dir); for (String intface : mapIntfacePTH.keySet()) { // Open a new file to write into FileWriter fw = new FileWriter(dir + "/" + intface + ".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 methods = intDecl.getMethods(); Set importClasses = getImportClasses(methods, intDecl); 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..."); } } /** * generateCplusLocalInterfaces() writes the local interfaces 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 generateCplusLocalInterfaces() throws IOException { // Create a new directory createDirectory(dir); for (String intface : mapIntfacePTH.keySet()) { // Open a new file to write into 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 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 " + 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 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..."); } } } /** * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++ *

* For C++ we use virtual classe as interface */ public void generateCPlusInterfaces() throws IOException { // 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;"); } print("}"); println(";"); pw.close(); System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp..."); } } } /** * generateJavaStubClasses() generate stubs based on the methods list in Java */ public void generateJavaStubClasses() throws IOException { // 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 + ".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..."); } } } /** * generateCPlusStubClasses() generate stubs based on the methods list in C++ */ public void generateCPlusStubClasses() throws IOException { // 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("return " + retStmt + ";"); } println("}"); println(""); } print("}"); println(";"); pw.close(); System.out.println("IoTCompiler: Generated stub class " + newIntface + ".hpp..."); } } } /** * 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") || methType.equals("byte")) { return "\"a\""; } else if ( methType.equals("char")) { return "\'a\'"; } else if ( methType.equals("boolean")) { return "true"; } else { return "null"; } } /** * setDirectory() sets a new directory for stub files */ public void setDirectory(String _subdir) { subdir = _subdir; } /** * printUsage() prints the usage of this compiler */ public static void printUsage() { System.out.println(); System.out.println("Sentinel 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:"); 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"); System.out.println(); } /** * 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; private void print(String str) { if (newline) { int tab=tablevel; if (str.equals("}")) tab--; for(int i=0; i for Set, #include for Map private String getNonPrimitiveCplusClass(String paramNonPrimitives) { return mapNonPrimitivesCplus.get(paramNonPrimitives); } // Get simple types, e.g. HashSet for HashSet<...> // Basically strip off the "<...>" private String getSimpleType(String paramType) { // Check if this is generics if(paramType.contains("<")) { String[] type = paramType.split("<"); return type[0]; } else return paramType; } // Generate a set of classes for import statements private Set getImportClasses(Collection methods, InterfaceDecl intDecl) { Set importClasses = new HashSet(); for (String method : methods) { List methPrmTypes = intDecl.getMethodParamTypes(method); for (String paramType : methPrmTypes) { String simpleType = getSimpleType(paramType); if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) { importClasses.add(getNonPrimitiveJavaClass(simpleType)); } } } return importClasses; } // Generate a set of classes for include statements private Set getIncludeClasses(Collection methods, InterfaceDecl intDecl) { Set includeClasses = new HashSet(); for (String method : methods) { List methPrmTypes = intDecl.getMethodParamTypes(method); for (String paramType : methPrmTypes) { String simpleType = getSimpleType(paramType); if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) { includeClasses.add(getNonPrimitiveCplusClass(simpleType)); } } } return includeClasses; } private void printImportStatements(Set importClasses) { for(String cls : importClasses) { println("import " + cls + ";"); } } private void printIncludeStatements(Set includeClasses) { for(String cls : includeClasses) { println("#include <" + cls + ">"); } } // Get the C++ version of a non-primitive type // e.g. set for Set and map for Map // Input nonPrimitiveType has to be generics in format private String[] getTypeOfGeneric(String nonPrimitiveType) { // Handle <, >, and , for 2-type generic/template String[] substr = nonPrimitiveType.split("<")[1].split(">")[0].split(","); return substr; } private String checkAndGetCplusType(String paramType) { if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) { return convertType(paramType); } else if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) { // Check for generic/template format if (paramType.contains("<") && paramType.contains(">")) { String genericClass = getSimpleType(paramType); String[] genericType = getTypeOfGeneric(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]) + ">"; return cplusTemplate; } else return getNonPrimitiveCplusClass(paramType); } else // Just return it as is if it's not non-primitives return paramType; } // Get simple types, e.g. HashSet for HashSet<...> // Basically strip off the "<...>" private String checkAndGetParamClass(String paramType) { // Check if this is generics if(getParamCategory(paramType) == ParamCategory.USERDEFINED) { 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 { // 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[i]); // Parse "requires" policy file ParseNode pnReq = IoTCompiler.parseFile(args[i+1]); // Get interface name 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.generateJavaLocalInterfaces(); comp.generateJavaInterfaces(); comp.generateJavaStubClasses(); } else { comp.generateCplusLocalInterfaces(); comp.generateCPlusInterfaces(); comp.generateCPlusStubClasses(); } } 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!"); } } }