Fixing a bug in ExtractorScript.py: consuming too many tokens.
[smartthings-infrastructure.git] / Extractor / ExtractorScript.py
1 import os
2 readyToReturn = 0
3 ToReturn = ""
4 eventMap = []
5 app1Capabilities = []
6 app2Capabilities = []
7
8 def GetToken(f):
9         global readyToReturn
10         global ToReturn
11         Skip = ['\n', '\t', ' ']
12         Special = ["(", "\"", ":", ",", "{", "}", ")", "/", "*"]
13         S = ""
14         if (readyToReturn):
15                 readyToReturn = 0
16                 return ToReturn
17         ToReturn = ""
18         c = f.read(1)
19         while(True):
20                 if (c in Special):
21                         if (S != ""):
22                                 readyToReturn = 1
23                                 ToReturn = c
24                                 return S
25                         else:
26                                 return c
27                 elif (c in Skip):
28                         if (S != ""):
29                                 return S        
30                         else:
31                                 c = f.read(1)
32                                 continue
33                 S += c
34                 c = f.read(1)
35                 if not c:
36                         return "EOF"
37
38 def ExtractFunctions(F, appName):
39         global eventMap
40         Temp = GetToken(F)
41         while (Temp != "EOF"):
42                 if (Temp == "def" or Temp == "private"):
43                         Temp = GetToken(F)
44                         NameofFunc = Temp
45                         if (GetToken(F) != "="): #We have a function to create object for
46                                 if (appName == "App1"):
47                                         extractedFunctionsApp1.write("//Global Object for functions in subscribe method!\n")    
48                                         extractedFunctionsApp1.write("def %s = this.&" % NameofFunc)
49                                         extractedFunctionsApp1.write("%s\n" % NameofFunc)
50                                 else:
51                                         extractedFunctionsApp2.write("//Global Object for functions in subscribe method!\n")    
52                                         extractedFunctionsApp2.write("def %s = this.&" % NameofFunc)
53                                         extractedFunctionsApp2.write("%s\n" % NameofFunc)
54                 
55                 #Check subscribed events
56                 if (Temp == "subscribe"):
57                         counter = 0
58                         while (counter < 5 and Temp != "\""):
59                                 Temp = GetToken(F)
60                                 counter = counter + 1
61                         Temp = GetToken(F)
62                         #If counter >= 5 that means it is not found, so it must be appTouch
63                         if (counter >= 5):
64                                 Temp = "Touched"
65                         if Temp not in eventMap:
66                                 eventMap.append(Temp)
67
68                 #Check and analyze capabilities for physical interaction
69                 AnalyzeCapabilities(Temp, appName)
70
71                 Temp = GetToken(F)
72         
73         #Warn if there is a potential for physical interaction
74         AnalyzePhysicalInteraction(app1Capabilities, app2Capabilities)
75         AnalyzePhysicalInteraction(app2Capabilities, app1Capabilities)
76
77                 
78
79 def AnalyzeCapabilities(Temp, appName):
80                         #Illuminance related
81         if (Temp == "capability.switch" or
82                         Temp == "capability.switchLevel" or
83                         Temp == "capability.illuminanceMeasurement" or
84                         #Motion related
85                         Temp == "capability.motionSensor" or
86                         #Water related
87                         Temp == "capability.valve" or
88                         Temp == "capability.waterSensor" or
89                         #Sound related
90                         Temp == "capability.musicPlayer" or
91                         Temp == "capability.alarm" or
92                         Temp == "capability.speechSynthesis" or
93                         Temp == "capability.soundSensor"):
94                 if (appName == "App1"):
95                         app1Capabilities.append(Temp)
96                 else:
97                         app2Capabilities.append(Temp)
98                         
99 def AnalyzePhysicalInteraction(app1Capab, app2Capab):
100         #Light
101         if ("capability.illuminanceMeasurement" in app1Capab) and ("capability.switch" in app2Capab or 
102                         "capability.switchLevel" in app2Capab):
103                 print ("\nWARNING: Potential PHYSICAL CONFLICT (light) detected between App1 and App2!\n")
104         #Motion
105         if ("capability.motionSensor" in app1Capab):
106                 print ("\nWARNING: Potential PHYSICAL CONFLICT (motion) detected between App1 and App2!\n")             
107         #Water
108         if ("capability.waterSensor" in app1Capab) and ("capability.valve" in app2Capab or 
109                         "capability.switch" in app2Capab):
110                 print ("\nWARNING: Potential PHYSICAL CONFLICT (water) detected between App1 and App2!\n")
111         #Sound
112         if ("capability.soundSensor" in app1Capab) and ("capability.musicPlayer" in app2Capab or 
113                         "capability.alarm" in app2Capab or "capability.speechSynthesis" in app2Capab):
114                 print ("\nWARNING: Potential PHYSICAL CONFLICT (sound) detected between App1 and App2!\n")
115
116 def ExtractEvents(extractedEvents):
117         global eventMap
118         extractedEvents.write("Random random = new Random(42)\n")
119         extractedEvents.write("counter = 1000\n")
120         extractedEvents.write("while(counter > 0) {\n")
121         extractedEvents.write("\tdef eventNumber = random.nextInt(%d)\n" % (len(eventMap) - 1))
122         extractedEvents.write("\tswitch(eventNumber) {\n")
123         eventCounter = 0;
124         for i in range(len(eventMap)):
125                 extractedEvents.write("\t\tcase %d:\n" % eventCounter)
126                 if eventMap[i] == "lock":
127                         event = open("eventSimulator/lockEvent.groovy", "r")
128                         for line in event:
129                                 extractedEvents.write(line)
130                         event.close()
131                 elif eventMap[i] == "unlock":
132                         event = open("eventSimulator/unlockEvent.groovy", "r")
133                         for line in event:
134                                 extractedEvents.write(line)
135                         event.close()
136                 elif eventMap[i] == "contact.open":
137                         event = open("eventSimulator/contactOpenEvent.groovy", "r")
138                         for line in event:
139                                 extractedEvents.write(line)
140                         event.close()
141                 elif eventMap[i] == "contact.closed":
142                         event = open("eventSimulator/contactClosedEvent.groovy", "r")
143                         for line in event:
144                                 extractedEvents.write(line)
145                         event.close()
146                 elif eventMap[i] == "switch.on":
147                         event = open("eventSimulator/switchOnEvent.groovy", "r")
148                         for line in event:
149                                 extractedEvents.write(line)
150                         event.close()
151                 elif eventMap[i] == "switch.off":
152                         event = open("eventSimulator/switchOffEvent.groovy", "r")
153                         for line in event:
154                                 extractedEvents.write(line)
155                         event.close()
156                 elif eventMap[i] == "nfcTouch":
157                         event = open("eventSimulator/nfcTouchEvent.groovy", "r")
158                         for line in event:
159                                 extractedEvents.write(line)
160                         event.close()
161                 elif eventMap[i] == "Touched":
162                         event = open("eventSimulator/appTouchEvent.groovy", "r")
163                         for line in event:
164                                 extractedEvents.write(line)
165                         event.close()
166                 elif eventMap[i] == "button":
167                         #Write two events subsequently
168                         event = open("eventSimulator/buttonPushedEvent.groovy", "r")
169                         for line in event:
170                                 extractedEvents.write(line)
171                         event.close()
172                         extractedEvents.write("\t\t\tbreak\n")
173                         eventCounter = eventCounter + 1
174                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
175                         event = open("eventSimulator/buttonHeldEvent.groovy", "r")
176                         for line in event:
177                                 extractedEvents.write(line)
178                         event.close()
179                 elif eventMap[i] == "presence":
180                         #Write two events subsequently
181                         event = open("eventSimulator/presencePresentEvent.groovy", "r")
182                         for line in event:
183                                 extractedEvents.write(line)
184                         event.close()
185                         extractedEvents.write("\t\t\tbreak\n")
186                         eventCounter = eventCounter + 1
187                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
188                         event = open("eventSimulator/presenceLeftEvent.groovy", "r")
189                         for line in event:
190                                 extractedEvents.write(line)
191                         event.close()
192                 elif eventMap[i] == "doorState":
193                         #Write two events subsequently
194                         event = open("eventSimulator/doorOpenEvent.groovy", "r")
195                         for line in event:
196                                 extractedEvents.write(line)
197                         event.close()
198                         extractedEvents.write("\t\t\tbreak\n")
199                         eventCounter = eventCounter + 1
200                         extractedEvents.write("\t\tcase %d:\n" % eventCounter)
201                         event = open("eventSimulator/doorClosedEvent.groovy", "r")
202                         for line in event:
203                                 extractedEvents.write(line)
204                         event.close()
205                 eventCounter = eventCounter + 1
206
207                 ###TODO: Add more events later
208                 extractedEvents.write("\n\t\t\tbreak\n")
209         extractedEvents.write("\t}\n")
210         extractedEvents.write("\tcounter--\n")
211         extractedEvents.write("}\n")
212                 
213 #Extract objects to call functions from App1
214 F1 = open("Extractor/App1/App1.groovy", "r")
215 extractedFunctionsApp1 = open("Extractor/App1/extractedFunctionsApp1.groovy", "w+")
216 ExtractFunctions(F1, "App1")
217 F1.close()
218
219 #Extract objects to call functions from App2
220 F2 = open("Extractor/App2/App2.groovy", "r")
221 extractedFunctionsApp2 = open("Extractor/App2/extractedFunctionsApp2.groovy", "w+")
222 ExtractFunctions(F2, "App2")
223 F2.close()
224
225 #Prepare eventSimulator file while parsing the App1 and App2 files
226 extractedEvents = open("eventSimulator/eventSimulator.groovy", "w+")
227 ExtractEvents(extractedEvents)
228 extractedEvents.close()
229
230 #Save the extracted methods and app1 in a same file to extract information
231 extractorFile = open("Extractor/extractorFile.groovy", "w+")
232 Extractor = open("Extractor/Extractor.groovy", "r")
233 F1 = open("Extractor/App1/App1.groovy", "r")
234
235 extractorFile.write("////////////////////\n")
236 extractorFile.write("@Field App\n")
237 extractorFile.write("App = \"App1\"")
238 extractorFile.write("\n")
239 for line in Extractor:
240         extractorFile.write(line)
241 extractorFile.write("\n\n")
242 for line in F1:
243         extractorFile.write(line)
244 extractorFile.close()
245 Extractor.close()
246 F1.close()
247 #Run the file to extract the objects
248 os.system("groovy Extractor/extractorFile.groovy")
249
250
251 #Save the extracted methods and app2 in a same file to extract information
252 extractorFile = open("Extractor/extractorFile.groovy", "w+")
253 Extractor = open("Extractor/Extractor.groovy", "r")
254 F2 = open("Extractor/App2/App2.groovy", "r")
255
256 extractorFile.write("////////////////////\n")
257 extractorFile.write("@Field App\n")
258 extractorFile.write("App = \"App2\"")
259 extractorFile.write("\n")
260 for line in Extractor:
261         extractorFile.write(line)
262 extractorFile.write("\n\n")
263 for line in F2:
264         extractorFile.write(line)
265 #Run the file to extract the objects
266 extractorFile.close()
267 Extractor.close()
268 F2.close()
269 os.system("groovy Extractor/extractorFile.groovy")
270
271
272
273