Separating policy file into main policy and generated interfaces; fixing lexer, parse...
[iot2.git] / iotjava / iotpolicy / tree / ParseTreeHandler.java
index 69a36c264ca18e4aa7bba379edac37ff500921c6..c5d0be7cba407ffbdb91dd001bf8ab26b11da5b8 100644 (file)
@@ -6,13 +6,16 @@ import java.io.*;
 import iotpolicy.tree.ParseNodeVector;
 import iotpolicy.tree.ParseNode;
 
+import java.util.List;
+import java.util.ArrayList;
+
 /** Class ParseTreeHandler handles the parse tree generated by the 
  *  parser (and lexer) from the policy file. 
- *  This class accepts the AST in the form of XMLElement class object.
- *  It gives interfaces to extract the 3 sections of a policy file:
- *  1) Interface
- *  2) Capability list
- *  3) Generated interface list
+ *  This class accepts the AST in the form of ParseNode and
+ *  ParseNodeVector class objects.
+ *  It gives interfaces to extract the 2 types of policy file:
+ *  1) Interface and capabilities definition
+ *  2) Generated interface list ("requires" statements)
  *
  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
  * @version     1.0
@@ -23,7 +26,8 @@ public final class ParseTreeHandler {
        /**
         * Class properties
         */
-       private ParseNode pn;
+       private ParseNode pnPol;                // Policy: interface and capabilities
+       private ParseNode pnReq;                // Policy: "requires" statements
        private InterfaceDecl intDecl;
        private CapabilityDecl capDecl;
        private RequiresDecl reqDecl;
@@ -34,16 +38,18 @@ public final class ParseTreeHandler {
         */
        public ParseTreeHandler() {
 
-               pn = null;
+               pnPol = null;
+               pnReq = null;
                intDecl = new InterfaceDecl();
                capDecl = new CapabilityDecl();
                reqDecl = new RequiresDecl();
        }
 
 
-       public ParseTreeHandler(String _intFace, ParseNode _pn) {
+       public ParseTreeHandler(String _intFace, ParseNode _pnPol, ParseNode _pnReq) {
 
-               pn = _pn;
+               pnPol = _pnPol;
+               pnReq = _pnReq;
                intDecl = new InterfaceDecl(_intFace);
                capDecl = new CapabilityDecl(_intFace);
                reqDecl = new RequiresDecl(_intFace);
@@ -55,47 +61,52 @@ public final class ParseTreeHandler {
         */
        public void processInterfaceDecl() {
 
-               // Get the root - interface list (element 0)
-               ParseNodeVector pnv = pn.getChildren();
+               ParseNodeVector pnv = pnPol.getChildren();
                ParseNode pnRoot = pnv.elementAt(0);
-               // Get the second child of root for "method_list"
                ParseNodeVector pnvGen2 = pnRoot.getChildren();
                if (pnvGen2.size() == 0) {
                        throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
                }
                ParseNode pnGen2 = pnvGen2.elementAt(1);
-               // Get the next level child for methods
                ParseNodeVector pnvGen3 = pnGen2.getChildren();
-               // Loop and extract methods
-               for(int i = 0; i < pnvGen3.size(); i++) {
+               for(int i = 0; i < pnvGen3.size(); i++) { // Loop on methods
 
-                       // Get the level where label is "method"
                        ParseNode pnGen3 = pnvGen3.elementAt(i);
-                       // Get the next level child - method info
                        ParseNodeVector pnvGen4 = pnGen3.getChildren();
-                       // Method type
+                       // Method type, identifier, and param node
                        ParseNode pnGen4_type = pnvGen4.elementAt(0);
-                       // Method identifier
                        ParseNode pnGen4_ident  = pnvGen4.elementAt(1);
-                       // Add a new method (type and identifier)
-                       intDecl.addNewMethod(pnGen4_ident.getLiteral().toString(), 
-                               pnGen4_type.getLiteral().toString());
-                       // Get the next level child - method params
                        ParseNode pnGen4_params  = pnvGen4.elementAt(2);
                        ParseNodeVector pnvGen5 = pnGen4_params.getChildren();
-                       for(int j = 0; j < pnvGen5.size(); j++) {
+                       // First loop - create a key without spaces, e.g. MethodA(intA,SpeakerB)
+                       String methodKey = pnGen4_ident.getLiteral().toString() + "(";
+                       List<String> paramTypes = new ArrayList<String>();
+                       List<String> params = new ArrayList<String>();
+                       for(int j = 0; j < pnvGen5.size(); j++) { // Loop on params
 
                                ParseNode pnGen5 = pnvGen5.elementAt(j);
                                ParseNodeVector pnvGen6 = pnGen5.getChildren();
-                               // Param type
+                               // Param type and identifier
                                ParseNode pnGen6_type = pnvGen6.elementAt(0);
-                               // Param identifier
                                ParseNode pnGen6_ident = pnvGen6.elementAt(1);
-                               // Add a new method param (type and identifier)
-                               intDecl.addMethodParam(pnGen4_ident.getLiteral().toString(),
-                                       pnGen6_ident.getLiteral().toString(), pnGen6_type.getLiteral().toString());
+                               methodKey = methodKey + pnGen6_type.getLiteral().toString();
+                               methodKey = methodKey + pnGen6_ident.getLiteral().toString();
+                               // Keep the parameters temporarily
+                               paramTypes.add(pnGen6_type.getLiteral().toString());
+                               params.add(pnGen6_ident.getLiteral().toString());
+                               // Don't add comma for the last parameter
+                               if (j != pnvGen5.size() - 1) {
+                                       methodKey = methodKey + ",";
+                               }
+                       }
+                       methodKey = methodKey + ")";
+                       // Add a new method (signature key, identifier, and type)
+                       intDecl.addNewMethod(methodKey, pnGen4_ident.getLiteral().toString(), 
+                               pnGen4_type.getLiteral().toString());
+                       // Second loop - add the method parameters
+                       for(int j = 0; j < params.size(); j++) {
+                               intDecl.addMethodParam(methodKey, params.get(j), paramTypes.get(j));
                        }
-                       //System.out.println();
                }
        }
 
@@ -106,41 +117,43 @@ public final class ParseTreeHandler {
        public void processCapabilityDecl() {
 
                // Get the root - capability list (element 1)
-               ParseNodeVector pnv = pn.getChildren();
-               ParseNode pnRoot = pnv.elementAt(1);
-               // Get the second child of root for "capab_list"
+               ParseNodeVector pnv = pnPol.getChildren();
+               ParseNode pnRoot = pnv.elementAt(0);
                ParseNodeVector pnvGen2 = pnRoot.getChildren();
-               if (pnvGen2.size() == 0) {
+               // Get the third child of root for "capab_list"
+               ParseNode pnGen2 = pnvGen2.elementAt(2);
+               ParseNodeVector pnvGen3 = pnGen2.getChildren();
+               if (pnvGen3.size() == 0) {
                        throw new Error("ParseTreeHandler: Capability declaration is missing! Please check your policy file...");
                }
                // Iterate over the list of capabilities
-               for(int i = 0; i < pnvGen2.size(); i++) {
+               for(int i = 0; i < pnvGen3.size(); i++) {
 
-                       ParseNode pnGen2 = pnvGen2.elementAt(i);
+                       ParseNode pnGen3 = pnvGen3.elementAt(i);
                        // Get the next level child for capabilities
-                       ParseNodeVector pnvGen3 = pnGen2.getChildren();
+                       ParseNodeVector pnvGen4 = pnGen3.getChildren();
                        // Get the capability name, e.g. ImageCapture for Camera.ImageCapture
-                       ParseNode pnGen3_capab = pnvGen3.elementAt(1);
+                       ParseNode pnGen4_capab = pnvGen4.elementAt(0);
                        // Add new capability
-                       capDecl.addNewCapability(pnGen3_capab.getLiteral().toString());
+                       capDecl.addNewCapability(pnGen4_capab.getLiteral().toString());
                        // Get the capability contents, i.e. descriptions and methods
-                       ParseNode pnGen3_capab_cont = pnvGen3.elementAt(2);
-                       ParseNodeVector pnvGen4 = pnGen3_capab_cont.getChildren();
+                       ParseNode pnGen4_capab_cont = pnvGen4.elementAt(1);
+                       ParseNodeVector pnvGen5 = pnGen4_capab_cont.getChildren();
                        // Iterate over the list of capability contents
-                       for(int j = 0; j < pnvGen4.size(); j++) {
+                       for(int j = 0; j < pnvGen5.size(); j++) {
 
-                               ParseNode pnGen4 = pnvGen4.elementAt(j);
-                               ParseNodeVector pnvGen5 = pnGen4.getChildren();
-                               ParseNode pnGen5 = pnvGen5.elementAt(0);
+                               ParseNode pnGen5 = pnvGen5.elementAt(j);
+                               ParseNodeVector pnvGen6 = pnGen5.getChildren();
+                               ParseNode pnGen6 = pnvGen6.elementAt(0);
                                // Check the label and separate between description (capab_desc)
                                // and method name (capab_ident)
-                               String label = pnGen5.getLabel().toString();
+                               String label = pnGen6.getLabel().toString();
                                if (label.equals("capab_desc")) {
-                                       capDecl.addNewDescription(pnGen3_capab.getLiteral().toString(),
-                                               pnGen5.getLiteral().toString());
-                               } else if (label.equals("capab_ident")) {
-                                       capDecl.addNewMethod(pnGen3_capab.getLiteral().toString(),
-                                               pnGen5.getLiteral().toString());                                
+                                       capDecl.addNewDescription(pnGen4_capab.getLiteral().toString(),
+                                               pnGen6.getLiteral().toString());
+                               } else if (label.equals("capab_meth")) {
+                                       capDecl.addNewMethod(pnGen4_capab.getLiteral().toString(),
+                                               pnGen6.getLiteral().toString().replaceAll("\\s+",""));
                                } else
                                        throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
 
@@ -155,9 +168,9 @@ public final class ParseTreeHandler {
        public void processRequiresDecl() {
 
                // Get the root - requires list (element 2)
-               ParseNodeVector pnv = pn.getChildren();
-               ParseNode pnRoot = pnv.elementAt(2);
-               // Get the second child of root for "capab_list"
+               ParseNodeVector pnv = pnReq.getChildren();
+               ParseNode pnRoot = pnv.elementAt(0);
+               // Get the second child of root for "reqlist"
                ParseNodeVector pnvGen2 = pnRoot.getChildren();
                if (pnvGen2.size() == 0) {
                        throw new Error("ParseTreeHandler: 'Requires' declaration is missing! Please check your policy file...");
@@ -225,6 +238,7 @@ public final class ParseTreeHandler {
                if (pnvGen2.size() == 0) {
                        throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
                }
+               // Get "intface_def"
                ParseNode pnGen2 = pnvGen2.elementAt(0);
                // Confirm that this is "intface_ident"
                if (pnGen2.getLabel().equals("intface_ident")) {
@@ -235,23 +249,4 @@ public final class ParseTreeHandler {
                } else
                        throw new Error("ParseTreeHandler: Label 'intface_ident' is not found! Instead, '" + pnGen2.getLabel() + "' was found...");
        }
-
-
-/*     public static void main(String[] args) throws Exception {
-
-               // initialize the symbol factory
-               ComplexSymbolFactory csf = new ComplexSymbolFactory();
-               // create a buffering scanner wrapper
-               ScannerBuffer lexer = new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csf));
-               // start parsing
-               Parser p = new Parser(lexer,csf);
-               ParseNode pn = (ParseNode) p.parse().value;
-
-               String intFace = ParseTreeHandler.getOrigIntface(pn);
-               System.out.println("Original interface name: " + intFace);
-               ParseTreeHandler pth = new ParseTreeHandler(intFace, pn);
-               pth.processInterfaceDecl();
-               pth.processCapabilityDecl();
-               pth.processRequiresDecl();
-       }*/
 }