Adjusting runtime system back after paper evaluation - putting back RMI port and...
[iot2.git] / iotjava / iotruntime / master / SetInstrumenter.java
1 package iotruntime.master;
2
3 import iotruntime.slave.IoTSet;
4
5 import iotinstaller.MySQLInterface;
6 import iotinstaller.TableProperty;
7 import iotinstaller.TableSet;
8
9 import java.sql.*;
10 import java.util.Set;
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.Map;
14 import java.util.Properties;
15
16 import java.util.Arrays;
17
18 import java.lang.Class;
19 import java.lang.Integer;
20 import java.lang.reflect.*;
21
22 /** Class SetInstrumenter helps instrument the bytecode.
23  *  This class should extract information from the database
24  *  Input is the name of the device/entity extracted from the
25  *  generic Set class in the bytecode, e.g. IoTSet<ProximitySensor>.
26  *  Upon extracting information, this class can be used to create
27  *  an IoTSet object that contains a list of objects from
28  *  the Set declaration.
29  *
30  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
31  * @version     1.0
32  * @since       2015-12-01
33  */
34 public final class SetInstrumenter {
35
36         /**
37          * SetInstrumenter class properties
38          */
39         private String[][] arrSet;
40         private HashMap<String, String> hmEntryTypes;
41         private TableSet tbl;
42         private int iRows;
43         private int iCols;
44         private String strSetEntityName;
45         private boolean bVerbose;
46
47         /**
48          * SetInstrumenter class constants
49          */
50         private static final String STR_PACKAGE_PREFIX = "iotcode.";
51         private static final String STR_FIELD_ID_NAME = "ID";
52
53         /**
54          * Class constructor
55          *
56          * @param strSetEntName     String that contains the IoTSet entity name in the DB, e.g. ProximitySensor
57          * @param strQueryFileName  String name for SQL query config file
58          * @param strObjectID       String ID to select the right device ID in IoTDeviceAddress table
59          * @param _bVerbose                     Verboseness of runtime output
60          */
61         public SetInstrumenter(String strSetEntName, String strQueryFileName, String strObjectID, boolean _bVerbose) {
62
63                 strSetEntityName = strSetEntName;
64                 tbl = new TableSet(strSetEntName, _bVerbose);
65                 tbl.setTableSetFromQueryFile(strQueryFileName, strObjectID);
66                 tbl.selectSetEntry();
67                 arrSet = tbl.getDBTable();
68                 hmEntryTypes = tbl.getEntryTypes();
69                 iRows = tbl.getNumOfRows();
70                 iCols = 0;
71                 bVerbose = _bVerbose;
72                 RuntimeOutput.print("SetInstrumentation: Creating a Set for " + strSetEntityName, bVerbose);
73         }
74
75
76         /**
77          * A method to give the object/table name
78          *
79          * @return String
80          */
81         public String getObjTableName() {
82
83                 return strSetEntityName;
84
85         }
86
87         /**
88          * A method to give the number of columns
89          *
90          * @param  iIndex  integer index
91          * @return int
92          */
93         public int numberOfCols(int iIndex) {
94
95                 iCols = tbl.getNumOfCols(iIndex);
96                 return iCols;
97         }
98
99         /**
100          * A method to give the number of rows
101          *
102          * @return int
103          */
104         public int numberOfRows() {
105
106                 return iRows;
107
108         }
109
110         /**
111          * A method to return the field object ID from entry pointed by certain index
112          *
113          * @param  iIndex  integer index
114          * @return String
115          */
116         public String fieldObjectID(int iIndex) {
117
118                 // Get the value of that field
119                 String[] arrObjectID = tbl.getFieldObjectIDs();
120                 String strID = arrObjectID[iIndex];
121
122                 RuntimeOutput.print("RelationInstrumentation: Extracting field object ID from value..", bVerbose);
123
124                 return strID;
125         }
126
127         /**
128          * A method to return the entry type name from an entry pointed by its ID
129          *
130          * @param  sID     device/entry ID
131          * @return String
132          */
133         public String fieldEntryType(String sID) {
134
135                 // Get the entry type
136                 String strEntryType = hmEntryTypes.get(sID);
137
138                 RuntimeOutput.print("RelationInstrumentation: Extracting entry type from entry..", bVerbose);
139
140                 return strEntryType;
141         }
142
143         /**
144          * A method to return the field values of certain index
145          *
146          * @param  iIndex  integer index
147          * @return Object[]
148          */
149         public Object[] fieldValues(int iIndex) {
150
151                 iCols = tbl.getNumOfCols(iIndex);
152                 // Get the right entry based on iIndex
153                 String[] arrSetEntry = arrSet[iIndex];
154                 Object[] arrFieldValues = new Object[iCols];
155
156                 for(int i=0; i<iCols; i++) {
157                         // MySQL column starts from 1, NOT 0
158                         arrFieldValues[i] = getObjectConverted(arrSetEntry[i], getClassName(tbl.getFieldType(i+1, iIndex)).getName());
159                 }
160
161                 RuntimeOutput.print("SetInstrumentation: Extracting field values..", bVerbose);
162
163                 return arrFieldValues;
164         }
165
166         /**
167          * A method to return the field classes of certain index
168          *
169          * @param  iIndex  integer index
170          * @return Class[]
171          */
172         public Class[] fieldClasses(int iIndex) {
173
174                 iCols = tbl.getNumOfCols(iIndex);
175                 // Get the right entry set based on iIndex
176                 RuntimeOutput.print("SetInstrumentation: Extracting table " + strSetEntityName + ".", bVerbose);
177                 Class[] arrFieldClasses = new Class[iCols];
178
179                 for(int i=0; i<iCols; i++) {
180                         // MySQL column starts from 1, NOT 0
181                         arrFieldClasses[i] = getClassName(tbl.getFieldType(i+1, iIndex));
182                 }
183
184                 RuntimeOutput.print("SetInstrumentation: Extracting field classes from field types..", bVerbose);
185                 return arrFieldClasses;
186         }
187
188         /**
189          * A helper function that gives the Class object of a particular DB data type
190          *
191          * @param  strDataType  String MySQL data type
192          * @return              Class
193          */
194         public Class getClassName(String strDataType) {
195
196                 if (strDataType.equals("VARCHAR")) {
197                         return String.class;
198                 } else if (strDataType.equals("INT")) {
199                         return int.class;
200                 } else {
201                         return null;
202                 }
203         }
204
205         /**
206          * A helper function that returns an Object in the right format
207          * <p>
208          * We give it input from the elements of the HashSet where we
209          * populate all the DB information for a certain Object
210          *
211          * @param  obj           Object to be converted
212          * @param  strClassType  String Java Class type
213          * @return               Object
214          */
215         public Object getObjectConverted(Object obj, String strClassType) {
216
217                 if (strClassType.equals("java.lang.String")) {
218                         // We use String "true" or "false" as booleans in MySQL
219                         String strObj = (String) obj;
220                         if (strObj.equals("true") || strObj.equals("false")) {
221                         // Check if this is a boolean
222                                 return Boolean.parseBoolean(strObj);
223                         } else {
224                         // Return just the string if it's not a boolean
225                                 return strObj;
226                         }
227                 } else if (strClassType.equals("int")) {
228                         return Integer.parseInt((String) obj);
229                 } else {
230                         return null;
231                 }
232         }
233 }