--- /dev/null
+package iotpolicy.tree;
+
+import java_cup.runtime.ComplexSymbolFactory;
+import java_cup.runtime.ScannerBuffer;
+import java.io.*;
+import iotpolicy.tree.ParseNodeVector;
+import iotpolicy.tree.ParseNode;
+
+/** 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
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-09-20
+ */
+public final class ParseTreeHandler {
+
+ /**
+ * Class properties
+ */
+ private ParseNode pn;
+ private InterfaceDecl intDecl;
+ private CapabilityDecl capDecl;
+ private RequiresDecl reqDecl;
+
+
+ /**
+ * Class constructors
+ */
+ public ParseTreeHandler() {
+
+ pn = null;
+ intDecl = new InterfaceDecl();
+ capDecl = new CapabilityDecl();
+ reqDecl = new RequiresDecl();
+ }
+
+
+ public ParseTreeHandler(String _intFace, ParseNode _pn) {
+
+ pn = _pn;
+ intDecl = new InterfaceDecl(_intFace);
+ capDecl = new CapabilityDecl(_intFace);
+ reqDecl = new RequiresDecl(_intFace);
+ }
+
+
+ /**
+ * processInterfaceDecl() processes interface declaration part
+ */
+ public void processInterfaceDecl() {
+
+ // Get the root - interface list (element 0)
+ ParseNodeVector pnv = pn.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++) {
+
+ // 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
+ 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++) {
+
+ ParseNode pnGen5 = pnvGen5.elementAt(j);
+ ParseNodeVector pnvGen6 = pnGen5.getChildren();
+ // Param type
+ 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());
+ }
+ //System.out.println();
+ }
+ }
+
+
+ /**
+ * processCapabilityDecl() processes capability declaration part
+ */
+ 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 pnvGen2 = pnRoot.getChildren();
+ if (pnvGen2.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++) {
+
+ ParseNode pnGen2 = pnvGen2.elementAt(i);
+ // Get the next level child for capabilities
+ ParseNodeVector pnvGen3 = pnGen2.getChildren();
+ // Get the capability name, e.g. ImageCapture for Camera.ImageCapture
+ ParseNode pnGen3_capab = pnvGen3.elementAt(1);
+ // Add new capability
+ capDecl.addNewCapability(pnGen3_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();
+ // Iterate over the list of capability contents
+ for(int j = 0; j < pnvGen4.size(); j++) {
+
+ ParseNode pnGen4 = pnvGen4.elementAt(j);
+ ParseNodeVector pnvGen5 = pnGen4.getChildren();
+ ParseNode pnGen5 = pnvGen5.elementAt(0);
+ // Check the label and separate between description (capab_desc)
+ // and method name (capab_ident)
+ String label = pnGen5.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());
+ } else
+ throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
+
+ }
+ }
+ }
+
+
+ /**
+ * processRequiresDecl() processes "requires" declaration part
+ */
+ 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 pnvGen2 = pnRoot.getChildren();
+ if (pnvGen2.size() == 0) {
+ throw new Error("ParseTreeHandler: 'Requires' declaration is missing! Please check your policy file...");
+ }
+ // Iterate over the list of requires statements
+ for(int i = 0; i < pnvGen2.size(); i++) {
+
+ ParseNode pnGen2 = pnvGen2.elementAt(i);
+ ParseNodeVector pnvGen3 = pnGen2.getChildren();
+ // Get the new interface that we want to generate
+ ParseNode pnGen3_intface = pnvGen3.elementAt(2);
+ reqDecl.addNewIntface(pnGen3_intface.getLiteral().toString());
+ // Get capability list at element 1
+ ParseNode pnGen3_capab_list = pnvGen3.elementAt(1);
+ ParseNodeVector pnvGen4 = pnGen3_capab_list.getChildren();
+ // Browse through capabilities
+ for (int j = 0; j < pnvGen4.size(); j++) {
+ ParseNode pnGen4 = pnvGen4.elementAt(j);
+ reqDecl.addNewCapability(pnGen3_intface.getLiteral().toString(),
+ pnGen4.getLiteral().toString());
+ }
+ }
+ }
+
+
+ /**
+ * getInterfaceDecl() returns InterfaceDecl object
+ */
+ public InterfaceDecl getInterfaceDecl() {
+
+ return intDecl;
+ }
+
+
+ /**
+ * getCapabilityDecl() returns CapabilityDecl object
+ */
+ public CapabilityDecl getCapabilityDecl() {
+
+ return capDecl;
+ }
+
+
+ /**
+ * getRequiresDecl() returns RequiresDecl object
+ */
+ public RequiresDecl getRequiresDecl() {
+
+ return reqDecl;
+ }
+
+
+ /**
+ * getOrigIntface() returns the original interface in policy, e.g. Camera
+ * <p>
+ * The ParseNode object should be the one returned from <Parser>.parse().value
+ */
+ public static String getOrigIntface(ParseNode pn) {
+
+ // Get the root: just keyword "interface"
+ ParseNodeVector pnv = pn.getChildren();
+ ParseNode pnRoot = pnv.elementAt(0);
+ // Get the child: intface_ident = original interface identifier, e.g. Camera
+ 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(0);
+ // Confirm that this is "intface_ident"
+ if (pnGen2.getLabel().equals("intface_ident")) {
+ if (pnGen2.getLiteral() != null) {
+ return pnGen2.getLiteral().toString();
+ } else
+ throw new Error("ParseTreeHandler: No interface name found! Please fix policy file!");
+ } 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();
+ }*/
+}