1 package iotpolicy.tree;
3 import java_cup.runtime.ComplexSymbolFactory;
4 import java_cup.runtime.ScannerBuffer;
6 import iotpolicy.tree.ParseNodeVector;
7 import iotpolicy.tree.ParseNode;
9 /** Class ParseTreeHandler handles the parse tree generated by the
10 * parser (and lexer) from the policy file.
11 * This class accepts the AST in the form of XMLElement class object.
12 * It gives interfaces to extract the 3 sections of a policy file:
15 * 3) Generated interface list
17 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
21 public final class ParseTreeHandler {
27 private InterfaceDecl intDecl;
28 private CapabilityDecl capDecl;
29 private RequiresDecl reqDecl;
35 public ParseTreeHandler() {
38 intDecl = new InterfaceDecl();
39 capDecl = new CapabilityDecl();
40 reqDecl = new RequiresDecl();
44 public ParseTreeHandler(String _intFace, ParseNode _pn) {
47 intDecl = new InterfaceDecl(_intFace);
48 capDecl = new CapabilityDecl(_intFace);
49 reqDecl = new RequiresDecl(_intFace);
54 * processInterfaceDecl() processes interface declaration part
56 public void processInterfaceDecl() {
58 // Get the root - interface list (element 0)
59 ParseNodeVector pnv = pn.getChildren();
60 ParseNode pnRoot = pnv.elementAt(0);
61 // Get the second child of root for "method_list"
62 ParseNodeVector pnvGen2 = pnRoot.getChildren();
63 if (pnvGen2.size() == 0) {
64 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
66 ParseNode pnGen2 = pnvGen2.elementAt(1);
67 // Get the next level child for methods
68 ParseNodeVector pnvGen3 = pnGen2.getChildren();
69 // Loop and extract methods
70 for(int i = 0; i < pnvGen3.size(); i++) {
72 // Get the level where label is "method"
73 ParseNode pnGen3 = pnvGen3.elementAt(i);
74 // Get the next level child - method info
75 ParseNodeVector pnvGen4 = pnGen3.getChildren();
77 ParseNode pnGen4_type = pnvGen4.elementAt(0);
79 ParseNode pnGen4_ident = pnvGen4.elementAt(1);
80 // Add a new method (type and identifier)
81 intDecl.addNewMethod(pnGen4_ident.getLiteral().toString(),
82 pnGen4_type.getLiteral().toString());
83 // Get the next level child - method params
84 ParseNode pnGen4_params = pnvGen4.elementAt(2);
85 ParseNodeVector pnvGen5 = pnGen4_params.getChildren();
86 for(int j = 0; j < pnvGen5.size(); j++) {
88 ParseNode pnGen5 = pnvGen5.elementAt(j);
89 ParseNodeVector pnvGen6 = pnGen5.getChildren();
91 ParseNode pnGen6_type = pnvGen6.elementAt(0);
93 ParseNode pnGen6_ident = pnvGen6.elementAt(1);
94 // Add a new method param (type and identifier)
95 intDecl.addMethodParam(pnGen4_ident.getLiteral().toString(),
96 pnGen6_ident.getLiteral().toString(), pnGen6_type.getLiteral().toString());
98 //System.out.println();
104 * processCapabilityDecl() processes capability declaration part
106 public void processCapabilityDecl() {
108 // Get the root - capability list (element 1)
109 ParseNodeVector pnv = pn.getChildren();
110 ParseNode pnRoot = pnv.elementAt(1);
111 // Get the second child of root for "capab_list"
112 ParseNodeVector pnvGen2 = pnRoot.getChildren();
113 if (pnvGen2.size() == 0) {
114 throw new Error("ParseTreeHandler: Capability declaration is missing! Please check your policy file...");
116 // Iterate over the list of capabilities
117 for(int i = 0; i < pnvGen2.size(); i++) {
119 ParseNode pnGen2 = pnvGen2.elementAt(i);
120 // Get the next level child for capabilities
121 ParseNodeVector pnvGen3 = pnGen2.getChildren();
122 // Get the capability name, e.g. ImageCapture for Camera.ImageCapture
123 ParseNode pnGen3_capab = pnvGen3.elementAt(1);
124 // Add new capability
125 capDecl.addNewCapability(pnGen3_capab.getLiteral().toString());
126 // Get the capability contents, i.e. descriptions and methods
127 ParseNode pnGen3_capab_cont = pnvGen3.elementAt(2);
128 ParseNodeVector pnvGen4 = pnGen3_capab_cont.getChildren();
129 // Iterate over the list of capability contents
130 for(int j = 0; j < pnvGen4.size(); j++) {
132 ParseNode pnGen4 = pnvGen4.elementAt(j);
133 ParseNodeVector pnvGen5 = pnGen4.getChildren();
134 ParseNode pnGen5 = pnvGen5.elementAt(0);
135 // Check the label and separate between description (capab_desc)
136 // and method name (capab_ident)
137 String label = pnGen5.getLabel().toString();
138 if (label.equals("capab_desc")) {
139 capDecl.addNewDescription(pnGen3_capab.getLiteral().toString(),
140 pnGen5.getLiteral().toString());
141 } else if (label.equals("capab_ident")) {
142 capDecl.addNewMethod(pnGen3_capab.getLiteral().toString(),
143 pnGen5.getLiteral().toString());
145 throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
153 * processRequiresDecl() processes "requires" declaration part
155 public void processRequiresDecl() {
157 // Get the root - requires list (element 2)
158 ParseNodeVector pnv = pn.getChildren();
159 ParseNode pnRoot = pnv.elementAt(2);
160 // Get the second child of root for "capab_list"
161 ParseNodeVector pnvGen2 = pnRoot.getChildren();
162 if (pnvGen2.size() == 0) {
163 throw new Error("ParseTreeHandler: 'Requires' declaration is missing! Please check your policy file...");
165 // Iterate over the list of requires statements
166 for(int i = 0; i < pnvGen2.size(); i++) {
168 ParseNode pnGen2 = pnvGen2.elementAt(i);
169 ParseNodeVector pnvGen3 = pnGen2.getChildren();
170 // Get the new interface that we want to generate
171 ParseNode pnGen3_intface = pnvGen3.elementAt(2);
172 reqDecl.addNewIntface(pnGen3_intface.getLiteral().toString());
173 // Get capability list at element 1
174 ParseNode pnGen3_capab_list = pnvGen3.elementAt(1);
175 ParseNodeVector pnvGen4 = pnGen3_capab_list.getChildren();
176 // Browse through capabilities
177 for (int j = 0; j < pnvGen4.size(); j++) {
178 ParseNode pnGen4 = pnvGen4.elementAt(j);
179 reqDecl.addNewCapability(pnGen3_intface.getLiteral().toString(),
180 pnGen4.getLiteral().toString());
187 * getInterfaceDecl() returns InterfaceDecl object
189 public InterfaceDecl getInterfaceDecl() {
196 * getCapabilityDecl() returns CapabilityDecl object
198 public CapabilityDecl getCapabilityDecl() {
205 * getRequiresDecl() returns RequiresDecl object
207 public RequiresDecl getRequiresDecl() {
214 * getOrigIntface() returns the original interface in policy, e.g. Camera
216 * The ParseNode object should be the one returned from <Parser>.parse().value
218 public static String getOrigIntface(ParseNode pn) {
220 // Get the root: just keyword "interface"
221 ParseNodeVector pnv = pn.getChildren();
222 ParseNode pnRoot = pnv.elementAt(0);
223 // Get the child: intface_ident = original interface identifier, e.g. Camera
224 ParseNodeVector pnvGen2 = pnRoot.getChildren();
225 if (pnvGen2.size() == 0) {
226 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
228 ParseNode pnGen2 = pnvGen2.elementAt(0);
229 // Confirm that this is "intface_ident"
230 if (pnGen2.getLabel().equals("intface_ident")) {
231 if (pnGen2.getLiteral() != null) {
232 return pnGen2.getLiteral().toString();
234 throw new Error("ParseTreeHandler: No interface name found! Please fix policy file!");
236 throw new Error("ParseTreeHandler: Label 'intface_ident' is not found! Instead, '" + pnGen2.getLabel() + "' was found...");
240 /* public static void main(String[] args) throws Exception {
242 // initialize the symbol factory
243 ComplexSymbolFactory csf = new ComplexSymbolFactory();
244 // create a buffering scanner wrapper
245 ScannerBuffer lexer = new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csf));
247 Parser p = new Parser(lexer,csf);
248 ParseNode pn = (ParseNode) p.parse().value;
250 String intFace = ParseTreeHandler.getOrigIntface(pn);
251 System.out.println("Original interface name: " + intFace);
252 ParseTreeHandler pth = new ParseTreeHandler(intFace, pn);
253 pth.processInterfaceDecl();
254 pth.processCapabilityDecl();
255 pth.processRequiresDecl();