Adjusting the compiler to generate stubs and skeletons with the correct package and...
[iot2.git] / iotjava / iotpolicy / IoTCompiler.java
index a5825a9141d835f9b9cae0424bc342417dda5765..d3db3f82a18065164fdcd698390e8831d35118f9 100644 (file)
@@ -49,6 +49,7 @@ public class IoTCompiler {
        private Map<String,DeclarationHandler> mapIntDeclHand;
        private Map<String,Map<String,Set<String>>> mapInt2NewInts;
        private Map<String,String> mapInt2NewIntName;
+       private Map<String,String> mapInt2Drv;
        // Data structure to store our types (primitives and non-primitives) for compilation
        private Map<String,String> mapPrimitives;
        private Map<String,String> mapNonPrimitivesJava;
@@ -63,7 +64,6 @@ public class IoTCompiler {
        private static int portCount = 0;
        private static int countObjId = 1;                      // Always increment object Id for a new stub/skeleton
        private String mainClass;
-       private String driverClass;
        private String controllerClass;
 
 
@@ -94,6 +94,7 @@ public class IoTCompiler {
                mapIntDeclHand = new HashMap<String,DeclarationHandler>();
                mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
                mapInt2NewIntName = new HashMap<String,String>();
+               mapInt2Drv = new HashMap<String,String>();
                mapIntfaceObjId = new HashMap<String,Integer>();
                mapNewIntfaceObjId = new HashMap<String,Integer>();
                mapPrimitives = new HashMap<String,String>();
@@ -107,7 +108,6 @@ public class IoTCompiler {
                dir = OUTPUT_DIRECTORY;
                subdir = null;
                mainClass = null;
-               driverClass = null;
                controllerClass = null;
        }
 
@@ -115,9 +115,17 @@ public class IoTCompiler {
        /**
         * setDriverClass() sets the name of the driver class.
         */
-       public void setDriverClass(String _driverClass) {
+       public void setDriverClass(String _driverClass, String _intface) {
                
-               driverClass = _driverClass;
+               mapInt2Drv.put(_driverClass, _intface);
+       }
+       
+       /**
+        * getDriverClass() sets the name of the driver class.
+        */
+       public String getDriverClass(String _intface) {
+               
+               return mapInt2Drv.get(_intface);
        }
 
 
@@ -1152,12 +1160,13 @@ public class IoTCompiler {
                                List<String> stdImportClasses = getStandardJavaImportClasses();
                                List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
                                // Find out if there are callback objects
-                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+                               Set<String> callbackClasses = getCallbackClasses(methods, intDecl);                     
                                boolean callbackExist = !callbackClasses.isEmpty();
-                               if (callbackExist)
-                                       println("package " + controllerClass + ";\n");
+                               // Check if this interface is a callback class
+                               if(isCallbackClass(intface))
+                                       println("package " + CODE_PREFIX + "." + mapInt2Drv.get(intface) + ";\n");
                                else
-                                   println("package " + CODE_PREFIX + "." + driverClass + ";\n");
+                                       println("package " + controllerClass + ";\n");
                                printImportStatements(allImportClasses); 
                                println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
                                // Write class header
@@ -2270,10 +2279,10 @@ public class IoTCompiler {
                        // Find out if there are callback objects
                        Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
                        boolean callbackExist = !callbackClasses.isEmpty();
-                       if (callbackExist)
-                   println("package " + CODE_PREFIX + "." + driverClass + ";\n");
-               else
-                       println("package " + controllerClass + ";\n");
+                       if(isCallbackClass(intface))
+                               println("package " + controllerClass + ";\n");
+                       else
+                               println("package " + CODE_PREFIX + "." + mapInt2Drv.get(intface) + ";\n");
                        printImportStatements(allImportClasses);
                        println("\nimport " + INTERFACE_PACKAGE + ".*;\n");
                        // Write class header
@@ -4904,6 +4913,45 @@ public class IoTCompiler {
                }
                return callbackClasses;
        }
+       
+
+       // Check if this is a callback class
+       private boolean isCallbackClass(String className) {
+
+               Set<String> intfaceSet = mapIntDeclHand.keySet();
+               for(String intface : intfaceSet) {
+
+                       DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+                       InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+                       Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+                       for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+                               Set<String> methods = intMeth.getValue();
+                               for (String method : methods) {
+
+                                       List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+                                       List<String> methParams = intDecl.getMethodParams(method);
+                                       for (int i = 0; i < methPrmTypes.size(); i++) {
+
+                                               String type = methPrmTypes.get(i);
+                                               if (getParamCategory(type) == ParamCategory.USERDEFINED) {
+                                                       // Final check to see if this is the searched class
+                                                       if (type.equals(className))
+                                                               return true;
+                                               } else if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
+                                               // Can be a List<...> of callback objects ...
+                                                       String genericType = getTypeOfGeneric(type)[0];
+                                                       if (getParamCategory(type) == ParamCategory.USERDEFINED) {
+                                                               if (type.equals(className))
+                                                                       return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return false;
+       }
 
 
        // Print import statements into file
@@ -5219,43 +5267,36 @@ public class IoTCompiler {
 
                        IoTCompiler comp = new IoTCompiler();
                        int i = 0;
-                       boolean driverDefined = false;
+                       //boolean driverDefined = false;
                        boolean controllerDefined = false;
                        do {
-                           // Look for "-drv" and "-cont"
-                           // These two need to be defined to complete the stub/skeleton generation
-                           //  with the appropriate headers
-                               if (args[i].equals("-drv")) {
-                                       comp.setDriverClass(args[i+1]);
-                                       driverDefined = true;
-                               } else if (args[i].equals("-cont")) {
-                                       System.out.println("DEBUG: Controller: " + args[i+1]);
+                               if (!controllerDefined && args[i].equals("-cont")) {
                                        comp.setControllerClass(args[i+1]);
                                        controllerDefined = true;
-                               } else {
-                                   // 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.setDataStructures(intface, pnPol, pnReq);
-                                   comp.getMethodsForIntface(intface);
+                                       i = i + 2;
                                }
+                           // 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.setDataStructures(intface, pnPol, pnReq);
+                           comp.getMethodsForIntface(intface);
                                i = i + 2;
+                               if (args[i].equals("-drv")) {
+                                       comp.setDriverClass(intface, args[i+1]);
+                                       i = i + 2;
+                               } else
+                                       throw new Error("IoTCompiler: ERROR - driver class name is needed for the interface: " + intface + "\n");
                        // 1) Check if this is the last option before "-java" or "-cplus"
                        // 2) Check if this is really the last option
                        } while(!args[i].equals("-java") &&
                                        !args[i].equals("-cplus") &&
                                        (i < args.length));
-
-                       // Generate error if we haven't seen -drv and -cont at this point
-                       if (!driverDefined || !controllerDefined) {
-                               String error = "IoTCompiler: ERROR - please provide arguments -drv and -cont " +
-                                               "to specify both driver and controller class names.\n" +
-                                               "Note: The two options have to come before -java and -cplus.\n";
-                               throw new Error(error);
-                       }
+                       // Controller class name needs to be defined at least once
+                       if (!controllerDefined)
+                               throw new Error("IoTCompiler: ERROR - controller class name has not been specified!\n");
 
                        // Generate everything if we don't see "-java" or "-cplus"
                        if (i == args.length) {
@@ -5316,3 +5357,4 @@ public class IoTCompiler {
 }
 
 
+