Removing IoTRMITypes.java from the outer directory
[iot2.git] / iotjava / iotpolicy / tree / ParseTreeHandler.java
1 package iotpolicy.tree;
2
3 import java_cup.runtime.ComplexSymbolFactory;
4 import java_cup.runtime.ScannerBuffer;
5 import java.io.*;
6 import iotpolicy.tree.ParseNodeVector;
7 import iotpolicy.tree.ParseNode;
8
9 import java.util.List;
10 import java.util.ArrayList;
11
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)
19  *
20  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
21  * @version     1.0
22  * @since       2016-09-20
23  */
24 public final class ParseTreeHandler {
25
26         /**
27          * Class properties
28          */
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;
34
35
36         /**
37          * Class constructors
38          */
39         public ParseTreeHandler() {
40
41                 pnPol = null;
42                 pnReq = null;
43                 intDecl = new InterfaceDecl();
44                 capDecl = new CapabilityDecl();
45                 reqDecl = new RequiresDecl();
46         }
47
48
49         public ParseTreeHandler(String _intFace, ParseNode _pnPol, ParseNode _pnReq) {
50
51                 pnPol = _pnPol;
52                 pnReq = _pnReq;
53                 intDecl = new InterfaceDecl(_intFace);
54                 capDecl = new CapabilityDecl(_intFace);
55                 reqDecl = new RequiresDecl(_intFace);
56         }
57
58
59         /**
60          * processInterfaceDecl() processes interface declaration part
61          */
62         public void processInterfaceDecl() {
63
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...");
69                 }
70                 ParseNode pnGen2 = pnvGen2.elementAt(1);
71                 ParseNodeVector pnvGen3 = pnGen2.getChildren();
72                 for(int i = 0; i < pnvGen3.size(); i++) { // Loop on methods
73
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
86
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 + ",";
100                                 }
101                         }
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));
109                         }
110                 }
111         }
112
113
114         /**
115          * processCapabilityDecl() processes capability declaration part
116          */
117         public void processCapabilityDecl() {
118
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...");
128                 }
129                 // Iterate over the list of capabilities
130                 for(int i = 0; i < pnvGen3.size(); i++) {
131
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++) {
144
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+",""));
157                                 } else
158                                         throw new Error("ParseTreeHandler: Unknown label '" + label + "' while operating on parse tree!");
159
160                         }
161                 }
162         }
163
164
165         /**
166          * processRequiresDecl() processes "requires" declaration part
167          */
168         public void processRequiresDecl() {
169
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...");
177                 }
178                 // Iterate over the list of requires statements
179                 for(int i = 0; i < pnvGen2.size(); i++) {
180
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());
194                         }
195                 }
196         }
197
198
199         /**
200          * getInterfaceDecl() returns InterfaceDecl object
201          */
202         public InterfaceDecl getInterfaceDecl() {
203
204                 return intDecl;
205         }
206
207
208         /**
209          * getCapabilityDecl() returns CapabilityDecl object
210          */
211         public CapabilityDecl getCapabilityDecl() {
212
213                 return capDecl;
214         }
215
216
217         /**
218          * getRequiresDecl() returns RequiresDecl object
219          */
220         public RequiresDecl getRequiresDecl() {
221
222                 return reqDecl;
223         }
224
225
226         /**
227          * getOrigIntface() returns the original interface in policy, e.g. Camera
228          * <p>
229          * The ParseNode object should be the one returned from <Parser>.parse().value
230          */
231         public static String getOrigIntface(ParseNode pn) {
232
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...");
240                 }
241                 // Get "intface_def"
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();
247                         } else
248                                 throw new Error("ParseTreeHandler: No interface name found! Please fix policy file!");
249                 } else
250                         throw new Error("ParseTreeHandler: Label 'intface_ident' is not found! Instead, '" + pnGen2.getLabel() + "' was found...");
251         }
252 }