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;
10 import java.util.ArrayList;
12 /** Class ParseTreeHandler handles the parse tree generated by the
13 * parser (and lexer) from the policy file.
14 * This class accepts the AST in the form of ParseNode and
15 * ParseNodeVector class objects.
16 * It gives interfaces to extract the 2 types of policy file:
17 * 1) Interface and capabilities definition
18 * 2) Generated interface list ("requires" statements)
20 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
24 public final class ParseTreeHandler {
29 private ParseNode pnPol; // Policy: interface and capabilities
30 private ParseNode pnReq; // Policy: "requires" statements
31 private InterfaceDecl intDecl;
32 private CapabilityDecl capDecl;
33 private RequiresDecl reqDecl;
39 public ParseTreeHandler() {
43 intDecl = new InterfaceDecl();
44 capDecl = new CapabilityDecl();
45 reqDecl = new RequiresDecl();
49 public ParseTreeHandler(String _intFace, ParseNode _pnPol, ParseNode _pnReq) {
53 intDecl = new InterfaceDecl(_intFace);
54 capDecl = new CapabilityDecl(_intFace);
55 reqDecl = new RequiresDecl(_intFace);
60 * processInterfaceDecl() processes interface declaration part
62 public void processInterfaceDecl() {
64 ParseNodeVector pnv = pnPol.getChildren();
65 ParseNode pnRoot = pnv.elementAt(0);
66 ParseNodeVector pnvGen2 = pnRoot.getChildren();
67 if (pnvGen2.size() == 0) {
68 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
70 ParseNode pnGen2 = pnvGen2.elementAt(1);
71 ParseNodeVector pnvGen3 = pnGen2.getChildren();
72 for(int i = 0; i < pnvGen3.size(); i++) { // Loop on methods
74 ParseNode pnGen3 = pnvGen3.elementAt(i);
75 ParseNodeVector pnvGen4 = pnGen3.getChildren();
76 // Method type, identifier, and param node
77 ParseNode pnGen4_type = pnvGen4.elementAt(0);
78 ParseNode pnGen4_ident = pnvGen4.elementAt(1);
79 ParseNode pnGen4_params = pnvGen4.elementAt(2);
80 ParseNodeVector pnvGen5 = pnGen4_params.getChildren();
81 // First loop - create a key without spaces, e.g. MethodA(intA,SpeakerB)
82 String methodKey = pnGen4_ident.getLiteral().toString() + "(";
83 List<String> paramTypes = new ArrayList<String>();
84 List<String> params = new ArrayList<String>();
85 for(int j = 0; j < pnvGen5.size(); j++) { // Loop on params
87 ParseNode pnGen5 = pnvGen5.elementAt(j);
88 ParseNodeVector pnvGen6 = pnGen5.getChildren();
89 // Param type and identifier
90 ParseNode pnGen6_type = pnvGen6.elementAt(0);
91 ParseNode pnGen6_ident = pnvGen6.elementAt(1);
92 methodKey = methodKey + pnGen6_type.getLiteral().toString();
93 methodKey = methodKey + pnGen6_ident.getLiteral().toString();
94 // Keep the parameters temporarily
95 paramTypes.add(pnGen6_type.getLiteral().toString());
96 params.add(pnGen6_ident.getLiteral().toString());
97 // Don't add comma for the last parameter
98 if (j != pnvGen5.size() - 1) {
99 methodKey = methodKey + ",";
102 methodKey = methodKey + ")";
103 // Add a new method (signature key, identifier, and type)
104 intDecl.addNewMethod(methodKey, pnGen4_ident.getLiteral().toString(),
105 pnGen4_type.getLiteral().toString());
106 // Second loop - add the method parameters
107 for(int j = 0; j < params.size(); j++) {
108 intDecl.addMethodParam(methodKey, params.get(j), paramTypes.get(j));
115 * processCapabilityDecl() processes capability declaration part
117 public void processCapabilityDecl() {
119 // Get the root - capability list (element 1)
120 ParseNodeVector pnv = pnPol.getChildren();
121 ParseNode pnRoot = pnv.elementAt(0);
122 ParseNodeVector pnvGen2 = pnRoot.getChildren();
123 // Get the third child of root for "capab_list"
124 ParseNode pnGen2 = pnvGen2.elementAt(2);
125 ParseNodeVector pnvGen3 = pnGen2.getChildren();
126 if (pnvGen3.size() == 0) {
127 throw new Error("ParseTreeHandler: Capability declaration is missing! Please check your policy file...");
129 // Iterate over the list of capabilities
130 for(int i = 0; i < pnvGen3.size(); i++) {
132 ParseNode pnGen3 = pnvGen3.elementAt(i);
133 // Get the next level child for capabilities
134 ParseNodeVector pnvGen4 = pnGen3.getChildren();
135 // Get the capability name, e.g. ImageCapture for Camera.ImageCapture
136 ParseNode pnGen4_capab = pnvGen4.elementAt(0);
137 // Add new capability
138 capDecl.addNewCapability(pnGen4_capab.getLiteral().toString());
139 // Get the capability contents, i.e. descriptions and methods
140 ParseNode pnGen4_capab_cont = pnvGen4.elementAt(1);
141 ParseNodeVector pnvGen5 = pnGen4_capab_cont.getChildren();
142 // Iterate over the list of capability contents
143 for(int j = 0; j < pnvGen5.size(); j++) {
145 ParseNode pnGen5 = pnvGen5.elementAt(j);
146 ParseNodeVector pnvGen6 = pnGen5.getChildren();
147 ParseNode pnGen6 = pnvGen6.elementAt(0);
148 // Check the label and separate between description (capab_desc)
149 // and method name (capab_ident)
150 String label = pnGen6.getLabel().toString();
151 if (label.equals("capab_desc")) {
152 capDecl.addNewDescription(pnGen4_capab.getLiteral().toString(),
153 pnGen6.getLiteral().toString());
154 } else if (label.equals("capab_meth")) {
155 capDecl.addNewMethod(pnGen4_capab.getLiteral().toString(),
156 pnGen6.getLiteral().toString().replaceAll("\\s+",""));
158 throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
166 * processRequiresDecl() processes "requires" declaration part
168 public void processRequiresDecl() {
170 // Get the root - requires list (element 2)
171 ParseNodeVector pnv = pnReq.getChildren();
172 ParseNode pnRoot = pnv.elementAt(0);
173 // Get the second child of root for "reqlist"
174 ParseNodeVector pnvGen2 = pnRoot.getChildren();
175 if (pnvGen2.size() == 0) {
176 throw new Error("ParseTreeHandler: 'Requires' declaration is missing! Please check your policy file...");
178 // Iterate over the list of requires statements
179 for(int i = 0; i < pnvGen2.size(); i++) {
181 ParseNode pnGen2 = pnvGen2.elementAt(i);
182 ParseNodeVector pnvGen3 = pnGen2.getChildren();
183 // Get the new interface that we want to generate
184 ParseNode pnGen3_intface = pnvGen3.elementAt(2);
185 reqDecl.addNewIntface(pnGen3_intface.getLiteral().toString());
186 // Get capability list at element 1
187 ParseNode pnGen3_capab_list = pnvGen3.elementAt(1);
188 ParseNodeVector pnvGen4 = pnGen3_capab_list.getChildren();
189 // Browse through capabilities
190 for (int j = 0; j < pnvGen4.size(); j++) {
191 ParseNode pnGen4 = pnvGen4.elementAt(j);
192 reqDecl.addNewCapability(pnGen3_intface.getLiteral().toString(),
193 pnGen4.getLiteral().toString());
200 * getInterfaceDecl() returns InterfaceDecl object
202 public InterfaceDecl getInterfaceDecl() {
209 * getCapabilityDecl() returns CapabilityDecl object
211 public CapabilityDecl getCapabilityDecl() {
218 * getRequiresDecl() returns RequiresDecl object
220 public RequiresDecl getRequiresDecl() {
227 * getOrigIntface() returns the original interface in policy, e.g. Camera
229 * The ParseNode object should be the one returned from <Parser>.parse().value
231 public static String getOrigIntface(ParseNode pn) {
233 // Get the root: just keyword "interface"
234 ParseNodeVector pnv = pn.getChildren();
235 ParseNode pnRoot = pnv.elementAt(0);
236 // Get the child: intface_ident = original interface identifier, e.g. Camera
237 ParseNodeVector pnvGen2 = pnRoot.getChildren();
238 if (pnvGen2.size() == 0) {
239 throw new Error("ParseTreeHandler: Interface declaration is missing! Please check your policy file...");
242 ParseNode pnGen2 = pnvGen2.elementAt(0);
243 // Confirm that this is "intface_ident"
244 if (pnGen2.getLabel().equals("intface_ident")) {
245 if (pnGen2.getLiteral() != null) {
246 return pnGen2.getLiteral().toString();
248 throw new Error("ParseTreeHandler: No interface name found! Please fix policy file!");
250 throw new Error("ParseTreeHandler: Label 'intface_ident' is not found! Instead, '" + pnGen2.getLabel() + "' was found...");