Changeset 1819 for trunk/autoquest-plugin-android/src
- Timestamp:
- 11/11/14 13:38:39 (10 years ago)
- Location:
- trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest
- Files:
-
- 5 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/ANDROIDPlugin.java
r1788 r1819 30 30 */ 31 31 public class ANDROIDPlugin implements AutoQUESTPlugin { 32 33 32 33 /** 34 34 * <p> 35 35 * The command packages of this plug-in. -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/AndroidLogParser.java
r1815 r1819 52 52 /** 53 53 * <p> 54 * This class provides functionality to parse XML log files generated by the 55 * AndroidMonitor of AutoQUEST. The result of parsing a file is a collection of 56 * event sequences. 54 * This class provides functionality to parse XML log files generated by the AndroidMonitor of 55 * AutoQUEST. The result of parsing a file is a collection of event sequences. 57 56 * </p> 58 57 * … … 62 61 public class AndroidLogParser extends DefaultHandler { 63 62 64 /* 65 * (non-Javadoc) 66 * 67 * int java.lang.Object.hashCode() is used in the Androidmonitor Long is 68 * used to internally handle and compare the number. e.g. 69 * currentGUIElementHash != null 70 */ 71 /** 72 * <p> 73 * Internal handle to the id of the event that is currently being parsed. 74 * </p> 75 */ 76 private String currentEventId = null; 77 78 /** 79 * <p> 80 * Internal handle to the parameters of the event currently being parsed. 81 * </p> 82 */ 83 private Map<String, String> currentEventParameters; 84 85 /** 86 * <p> 87 * Internal handle to the source of the event that is currently being 88 * parsed. 89 * </p> 90 */ 91 private Long currentEventSource; 92 93 /** 94 * <p> 95 * Internal handle to the timestamp of the event that is currently being 96 * parsed. 97 */ 98 private Long currentEventTimestamp = -1l; 99 100 /** 101 * 102 * <p> 103 * Internal handle to the hashcode of the GUI element, that is currently 104 * parsed. 105 * </p> 106 */ 107 private Long currentGUIElementHash = null; 108 109 /** 110 * <p> 111 * Internal handle to the parsed GUI structure, stored in a GUIElementTree 112 * </p> 113 */ 114 private GUIElementTree<Long> currentGUIElementTree; 115 116 /** 117 * <p> 118 * Internal handle to the specification currently parsed for a GUI element 119 * </p> 120 */ 121 private ANDROIDGUIElementSpec currentGUIElementSpec; 122 123 /** 124 * 125 * <p> 126 * Internal handle to the hashcode of the parent of the GUI element, that is 127 * currently parsed. 128 * </p> 129 */ 130 private Long currentParentHash; 131 132 /** 133 * <p> 134 * Internal handle to the event sequence that is currently being parsed. 135 * </p> 136 */ 137 private List<Event> currentSequence; 138 139 /** 63 /* 64 * (non-Javadoc) 65 * 66 * int java.lang.Object.hashCode() is used in the Androidmonitor Long is used to internally 67 * handle and compare the number. e.g. currentGUIElementHash != null 68 */ 69 /** 70 * <p> 71 * Internal handle to the id of the event that is currently being parsed. 72 * </p> 73 */ 74 private String currentEventId = null; 75 76 /** 77 * <p> 78 * Internal handle to the parameters of the event currently being parsed. 79 * </p> 80 */ 81 private Map<String, String> currentEventParameters; 82 83 /** 84 * <p> 85 * Internal handle to the source of the event that is currently being parsed. 86 * </p> 87 */ 88 private Long currentEventSource; 89 90 /** 91 * <p> 92 * Internal handle to the timestamp of the event that is currently being parsed. 93 */ 94 private Long currentEventTimestamp = -1l; 95 96 /** 97 * 98 * <p> 99 * Internal handle to the hashcode of the GUI element, that is currently parsed. 100 * </p> 101 */ 102 private Long currentGUIElementHash = null; 103 104 /** 105 * <p> 106 * Internal handle to the parsed GUI structure, stored in a GUIElementTree 107 * </p> 108 */ 109 private GUIElementTree<Long> currentGUIElementTree; 110 111 /** 112 * <p> 113 * Internal handle to the specification currently parsed for a GUI element 114 * </p> 115 */ 116 private ANDROIDGUIElementSpec currentGUIElementSpec; 117 118 /** 119 * 120 * <p> 121 * Internal handle to the hashcode of the parent of the GUI element, that is currently parsed. 122 * </p> 123 */ 124 private Long currentParentHash; 125 126 /** 127 * <p> 128 * Internal handle to the event sequence that is currently being parsed. 129 * </p> 130 */ 131 private List<Event> currentSequence; 132 133 /** 140 134 * <p> 141 135 * internal handle to the class ancestors 142 136 * </p> 143 137 */ 144 private List<String> currentTypeHierarchy; 145 146 /** 147 * <p> 148 * Map that holds events that had no registered target GUI element during 149 * parsing. Keys are the IDs of the unregistered targets. 150 * </p> 151 */ 152 // private Map<Long, List<Event>> eventsWithoutTargets; 153 154 /** 155 * <p> 156 * Collection of event sequences that is contained in the log file, which is 157 * parsed. 158 * </p> 159 */ 160 private Collection<List<Event>> sequences; 161 162 /** 138 private List<String> currentTypeHierarchy; 139 140 /** 141 * <p> 142 * Map that holds events that had no registered target GUI element during parsing. Keys are the 143 * IDs of the unregistered targets. 144 * </p> 145 */ 146 // private Map<Long, List<Event>> eventsWithoutTargets; 147 148 /** 149 * <p> 150 * Collection of event sequences that is contained in the log file, which is parsed. 151 * </p> 152 */ 153 private Collection<List<Event>> sequences; 154 155 /** 163 156 * 164 157 */ 165 private Boolean showSteps = false; 166 167 /** 168 * <p> 169 * Constructor. Creates a new AndroidLogParser. 170 * </p> 171 */ 172 public AndroidLogParser() { 173 sequences = new LinkedList<List<Event>>(); 174 currentSequence = null; 175 } 176 177 // TODO create a constructor which creates a new AndroidLogParser with a 178 // specific event filter. 179 180 /** 181 * <p> 182 * Parses a log file written by the JFCMonitor and creates a collection of 183 * event sequences. 184 * </p> 185 * 186 * @param filename 187 * name and path of the log file 188 */ 189 public void parseFile(String filename) { 190 if (filename == null) { 191 throw new IllegalArgumentException("filename must not be null"); 192 } 193 194 parseFile(new File(filename)); 195 } 196 197 /** 198 * <p> 199 * Parses a log file written by the JFCMonitor and creates a collection of 200 * event sequences. 201 * </p> 202 * 203 * @param file 204 * name and path of the log file 205 */ 206 public void parseFile(File file) { 207 if (file == null) { 208 throw new IllegalArgumentException("file must not be null"); 209 } 210 211 SAXParserFactory spf = SAXParserFactory.newInstance(); 212 // set true to validate that the file is well defined 213 spf.setValidating(true); 214 215 SAXParser saxParser = null; 216 InputSource inputSource = null; 217 try { 218 saxParser = spf.newSAXParser(); 219 inputSource = new InputSource(new InputStreamReader( 220 new FileInputStream(file), "UTF-8")); 221 } catch (UnsupportedEncodingException e) { 222 Console.printerr("Error parsing file + " + file.getName()); 223 Console.logException(e); 224 return; 225 } catch (ParserConfigurationException e) { 226 Console.printerr("Error parsing file + " + file.getName()); 227 Console.logException(e); 228 return; 229 } catch (SAXException e) { 230 Console.printerr("Error parsing file + " + file.getName()); 231 Console.logException(e); 232 return; 233 } catch (FileNotFoundException e) { 234 Console.printerr("Error parsing file + " + file.getName()); 235 Console.logException(e); 236 return; 237 } 238 239 if (inputSource != null) { 240 inputSource.setSystemId("file://" + file.getAbsolutePath()); 241 try { 242 // called a second time to be sure that no error happens 243 if (saxParser == null) { 244 throw new RuntimeException("SAXParser creation failed"); 245 } 246 saxParser.parse(inputSource, this); 247 } catch (SAXParseException e) { 248 Console.printerrln("Failure parsing file in line " 249 + e.getLineNumber() + ", column " + e.getColumnNumber() 250 + "."); 251 Console.logException(e); 252 return; 253 } catch (SAXException e) { 254 Console.printerr("Error parsing file + " + file.getName()); 255 Console.logException(e); 256 return; 257 } catch (IOException e) { 258 Console.printerr("Error parsing file + " + file.getName()); 259 Console.logException(e); 260 return; 261 } 262 } 263 } 264 265 /** 266 * <p> 267 * Returns the collection of event sequences that is obtained from parsing 268 * log files. 269 * </p> 270 * 271 * @return collection of event sequences 272 */ 273 public Collection<List<Event>> getSequences() { 274 return sequences; 275 } 276 277 /** 278 * <p> 279 * Returns the GUI model that is obtained from parsing log files. 280 * </p> 281 * 282 * @return GUIModel 283 */ 284 public GUIModel getGuiModel() { 285 return currentGUIElementTree.getGUIModel(); 286 } 287 288 /* 289 * (non-Javadoc) 290 * 291 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, 292 * java.lang.String, java.lang.String, org.xml.sax.Attributes) 293 */ 294 public void startElement(String uri, String localName, String qName, 295 Attributes atts) throws SAXException { 296 showSteps("start element: " + qName, true); 297 if (qName.equals("sessions")) { 298 currentSequence = new LinkedList<Event>(); 299 if (currentGUIElementTree == null) { 300 currentGUIElementTree = new GUIElementTree<Long>(); 301 } 302 303 } 304 305 if (qName.equals("component")) { 306 currentGUIElementHash = Long.parseLong(atts.getValue("hash")); 307 currentGUIElementSpec = new ANDROIDGUIElementSpec(); 308 currentGUIElementSpec.setHashCode((int) currentGUIElementHash 309 .longValue()); 310 311 } else if (qName.equals("event")) { 312 currentEventId = atts.getValue("id"); 313 currentEventParameters = new HashMap<String, String>(); 314 315 } else if (qName.equals("param")) { 316 if (currentGUIElementHash != null) { 317 if ("class".equals(atts.getValue("name"))) { 318 currentGUIElementSpec.setType(atts.getValue("value")); 319 } else if ("path".equals(atts.getValue("name"))) { 320 currentGUIElementSpec.setPath(atts.getValue("value")); 321 } else if ("id".equals(atts.getValue("name"))) { 322 currentGUIElementSpec.setIndex(Integer.parseInt(atts 323 .getValue("value"))); 324 } else if ("parent".equals(atts.getValue("name"))) { 325 currentParentHash = Long.parseLong(atts.getValue("value")); 326 } 327 } else if (currentEventId != null) { 328 if ("source".equals(atts.getValue("name"))) { 329 currentEventSource = Long.parseLong(atts.getValue("value")); 330 } 331 if ("timestamp".equals(atts.getValue("name"))) { 332 currentEventTimestamp = Long.parseLong(atts 333 .getValue("value")); 334 } 335 currentEventParameters.put(atts.getValue("name"), 336 atts.getValue("value")); 337 } 338 } 339 else if (qName.equals("ancestor")) { 158 private Boolean showSteps = false; 159 160 /** 161 * <p> 162 * Constructor. Creates a new AndroidLogParser. 163 * </p> 164 */ 165 public AndroidLogParser() { 166 sequences = new LinkedList<List<Event>>(); 167 currentSequence = null; 168 } 169 170 // TODO create a constructor which creates a new AndroidLogParser with a 171 // specific event filter. 172 173 /** 174 * <p> 175 * Parses a log file written by the JFCMonitor and creates a collection of event sequences. 176 * </p> 177 * 178 * @param filename 179 * name and path of the log file 180 */ 181 public void parseFile(String filename) { 182 if (filename == null) { 183 throw new IllegalArgumentException("filename must not be null"); 184 } 185 186 parseFile(new File(filename)); 187 } 188 189 /** 190 * <p> 191 * Parses a log file written by the JFCMonitor and creates a collection of event sequences. 192 * </p> 193 * 194 * @param file 195 * name and path of the log file 196 */ 197 public void parseFile(File file) { 198 if (file == null) { 199 throw new IllegalArgumentException("file must not be null"); 200 } 201 202 SAXParserFactory spf = SAXParserFactory.newInstance(); 203 // set true to validate that the file is well defined 204 spf.setValidating(true); 205 206 SAXParser saxParser = null; 207 InputSource inputSource = null; 208 try { 209 saxParser = spf.newSAXParser(); 210 inputSource = 211 new InputSource(new InputStreamReader(new FileInputStream(file), "UTF-8")); 212 } 213 catch (UnsupportedEncodingException e) { 214 Console.printerr("Error parsing file + " + file.getName()); 215 Console.logException(e); 216 return; 217 } 218 catch (ParserConfigurationException e) { 219 Console.printerr("Error parsing file + " + file.getName()); 220 Console.logException(e); 221 return; 222 } 223 catch (SAXException e) { 224 Console.printerr("Error parsing file + " + file.getName()); 225 Console.logException(e); 226 return; 227 } 228 catch (FileNotFoundException e) { 229 Console.printerr("Error parsing file + " + file.getName()); 230 Console.logException(e); 231 return; 232 } 233 234 if (inputSource != null) { 235 inputSource.setSystemId("file://" + file.getAbsolutePath()); 236 try { 237 // called a second time to be sure that no error happens 238 if (saxParser == null) { 239 throw new RuntimeException("SAXParser creation failed"); 240 } 241 saxParser.parse(inputSource, this); 242 } 243 catch (SAXParseException e) { 244 Console.printerrln("Failure parsing file in line " + e.getLineNumber() + 245 ", column " + e.getColumnNumber() + "."); 246 Console.logException(e); 247 return; 248 } 249 catch (SAXException e) { 250 Console.printerr("Error parsing file + " + file.getName()); 251 Console.logException(e); 252 return; 253 } 254 catch (IOException e) { 255 Console.printerr("Error parsing file + " + file.getName()); 256 Console.logException(e); 257 return; 258 } 259 } 260 } 261 262 /** 263 * <p> 264 * Returns the collection of event sequences that is obtained from parsing log files. 265 * </p> 266 * 267 * @return collection of event sequences 268 */ 269 public Collection<List<Event>> getSequences() { 270 return sequences; 271 } 272 273 /** 274 * <p> 275 * Returns the GUI model that is obtained from parsing log files. 276 * </p> 277 * 278 * @return GUIModel 279 */ 280 public GUIModel getGuiModel() { 281 return currentGUIElementTree.getGUIModel(); 282 } 283 284 /* 285 * (non-Javadoc) 286 * 287 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, 288 * java.lang.String, org.xml.sax.Attributes) 289 */ 290 public void startElement(String uri, String localName, String qName, Attributes atts) 291 throws SAXException 292 { 293 showSteps("start element: " + qName, true); 294 if (qName.equals("sessions")) { 295 currentSequence = new LinkedList<Event>(); 296 if (currentGUIElementTree == null) { 297 currentGUIElementTree = new GUIElementTree<Long>(); 298 } 299 300 } 301 302 if (qName.equals("component")) { 303 currentGUIElementHash = Long.parseLong(atts.getValue("hash")); 304 currentGUIElementSpec = new ANDROIDGUIElementSpec(); 305 currentGUIElementSpec.setHashCode((int) currentGUIElementHash.longValue()); 306 307 } 308 else if (qName.equals("event")) { 309 currentEventId = atts.getValue("id"); 310 currentEventParameters = new HashMap<String, String>(); 311 312 } 313 else if (qName.equals("param")) { 314 if (currentGUIElementHash != null) { 315 if ("class".equals(atts.getValue("name"))) { 316 currentGUIElementSpec.setType(atts.getValue("value")); 317 } 318 else if ("path".equals(atts.getValue("name"))) { 319 currentGUIElementSpec.setPath(atts.getValue("value")); 320 } 321 else if ("id".equals(atts.getValue("name"))) { 322 currentGUIElementSpec.setIndex(Integer.parseInt(atts.getValue("value"))); 323 } 324 else if ("parent".equals(atts.getValue("name"))) { 325 currentParentHash = Long.parseLong(atts.getValue("value")); 326 } 327 } 328 else if (currentEventId != null) { 329 if ("source".equals(atts.getValue("name"))) { 330 currentEventSource = Long.parseLong(atts.getValue("value")); 331 } 332 if ("timestamp".equals(atts.getValue("name"))) { 333 currentEventTimestamp = Long.parseLong(atts.getValue("value")); 334 } 335 currentEventParameters.put(atts.getValue("name"), atts.getValue("value")); 336 } 337 } 338 else if (qName.equals("ancestor")) { 340 339 currentTypeHierarchy.add(atts.getValue("name")); 341 340 } … … 343 342 currentTypeHierarchy = new LinkedList<String>(); 344 343 } 345 } 346 347 /* 348 * (non-Javadoc) 349 * 350 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, 351 * java.lang.String, java.lang.String) 352 */ 353 @Override 354 public void endElement(String uri, String localName, String qName) 355 throws SAXException { 356 357 showSteps("end element: " + qName, true); 358 359 if (qName.equals("sessions")) { 360 if (currentSequence != null) { 361 sequences.add(currentSequence); 362 } 363 } 364 else if (qName.equals("ancestors")) { 344 } 345 346 /* 347 * (non-Javadoc) 348 * 349 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, 350 * java.lang.String) 351 */ 352 @Override 353 public void endElement(String uri, String localName, String qName) throws SAXException { 354 355 showSteps("end element: " + qName, true); 356 357 if (qName.equals("sessions")) { 358 if (currentSequence != null) { 359 sequences.add(currentSequence); 360 } 361 } 362 else if (qName.equals("ancestors")) { 365 363 currentGUIElementSpec.setTypeHierarchy(currentTypeHierarchy); 366 364 } 367 else if (qName.equals("component") && currentGUIElementHash != null) { 368 try { 369 currentGUIElementTree.add(currentGUIElementHash, 370 currentParentHash, currentGUIElementSpec); 371 } catch (GUIModelException e) { 372 throw new SAXException( 373 "could not handle GUI element with hash " 374 + currentGUIElementHash + ": " + e.getMessage(), 375 e); 376 } 377 currentGUIElementHash = null; 378 currentParentHash = null; 379 currentTypeHierarchy = null; 380 } 381 else if (currentEventId != null && qName.equals("event")) { 382 383 IGUIElement currentGUIElement; 384 currentGUIElement = currentGUIElementTree.find(currentEventSource); 385 Event event; 386 387 // up to now only onClick events are implemented and each 388 // onclick event is processed as a mouse click 389 if (currentGUIElement == null) { 390 391 } else { 392 393 event = new Event(instantiateInteraction(currentEventId, 394 currentEventParameters), currentGUIElement); 395 ANDROIDGUIElement currentEventTarget = (ANDROIDGUIElement) event 396 .getTarget(); 397 currentEventTarget.markUsed(); 398 event.setTimestamp(currentEventTimestamp); 399 currentSequence.add(event); 400 } 401 currentEventParameters = null; 402 currentEventId = null; 403 currentEventTimestamp = -1l; 404 } 405 } 406 407 /** 408 * <p> 409 * depending on the event id and the event parameters, this method 410 * instantiates the concrete interaction, that took place, i.e. the event 411 * type 412 * </p> 413 * 414 * @param eventId 415 * the id of the event 416 * @param eventParameters 417 * the parameters provided for the event 418 * 419 * @return as described 420 * 421 * @throws SAXException 422 * thrown if the provided event id is unknown 423 */ 424 private IInteraction instantiateInteraction(String event, 425 Map<String, String> eventParameters) throws SAXException { 426 427 switch (event) { 428 case "onClick": 429 430 float x = Float.parseFloat(currentEventParameters.get("X")); 431 float y = Float.parseFloat(currentEventParameters.get("Y")); 432 433 return new TouchSingle(x,y); 434 435 case "text": 436 return new CharacterTyped(currentEventParameters.get("message")); 437 438 default: 439 throw new SAXException("unhandled event id " + event); 440 } 441 442 } 443 444 private void showSteps(String message, Boolean ln) { 445 if (showSteps) { 446 if (ln) { 447 Console.traceln(Level.INFO, message); 448 } else { 449 Console.trace(Level.INFO, message); 450 } 451 452 } 453 } 454 455 public void setShowSteps(Boolean showSteps) { 456 this.showSteps = showSteps; 457 } 365 else if (qName.equals("component") && currentGUIElementHash != null) { 366 try { 367 currentGUIElementTree.add(currentGUIElementHash, currentParentHash, 368 currentGUIElementSpec); 369 } 370 catch (GUIModelException e) { 371 throw new SAXException("could not handle GUI element with hash " + 372 currentGUIElementHash + ": " + e.getMessage(), e); 373 } 374 currentGUIElementHash = null; 375 currentParentHash = null; 376 currentTypeHierarchy = null; 377 } 378 else if (currentEventId != null && qName.equals("event")) { 379 380 IGUIElement currentGUIElement; 381 currentGUIElement = currentGUIElementTree.find(currentEventSource); 382 Event event; 383 384 // up to now only onClick events are implemented and each 385 // onclick event is processed as a mouse click 386 if (currentGUIElement == null) { 387 388 } 389 else { 390 391 event = 392 new Event(instantiateInteraction(currentEventId, currentEventParameters), 393 currentGUIElement); 394 ANDROIDGUIElement currentEventTarget = (ANDROIDGUIElement) event.getTarget(); 395 currentEventTarget.markUsed(); 396 event.setTimestamp(currentEventTimestamp); 397 currentSequence.add(event); 398 } 399 currentEventParameters = null; 400 currentEventId = null; 401 currentEventTimestamp = -1l; 402 } 403 } 404 405 /** 406 * <p> 407 * depending on the event id and the event parameters, this method instantiates the concrete 408 * interaction, that took place, i.e. the event type 409 * </p> 410 * 411 * @param eventId 412 * the id of the event 413 * @param eventParameters 414 * the parameters provided for the event 415 * 416 * @return as described 417 * 418 * @throws SAXException 419 * thrown if the provided event id is unknown 420 */ 421 private IInteraction instantiateInteraction(String event, Map<String, String> eventParameters) 422 throws SAXException 423 { 424 425 switch (event) 426 { 427 case "onClick": 428 429 float x = Float.parseFloat(currentEventParameters.get("X")); 430 float y = Float.parseFloat(currentEventParameters.get("Y")); 431 432 return new TouchSingle(x, y); 433 434 case "text": 435 return new CharacterTyped(currentEventParameters.get("message")); 436 437 default: 438 throw new SAXException("unhandled event id " + event); 439 } 440 441 } 442 443 private void showSteps(String message, Boolean ln) { 444 if (showSteps) { 445 if (ln) { 446 Console.traceln(Level.INFO, message); 447 } 448 else { 449 Console.trace(Level.INFO, message); 450 } 451 452 } 453 } 454 455 public void setShowSteps(Boolean showSteps) { 456 this.showSteps = showSteps; 457 } 458 458 459 459 } -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/commands/CMDparseAndroid.java
r1783 r1819 17 17 import java.util.Collection; 18 18 import java.util.List; 19 import java.util.logging.Level; 19 20 20 21 import de.ugoe.cs.autoquest.CommandHelpers; … … 36 37 public class CMDparseAndroid implements Command { 37 38 38 39 /* 39 40 * (non-Javadoc) 40 41 * 41 42 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 42 43 */ 43 44 45 46 44 @Override 45 public void run(List<Object> parameters) { 46 String filename; 47 String sequencesName = "sequences"; 47 48 48 try { 49 filename = (String) parameters.get(0); 50 if (parameters.size() >= 2) { 51 sequencesName = (String) parameters.get(1); 52 } 53 } catch (Exception e) { 54 throw new IllegalArgumentException(); 55 } 49 try { 50 filename = (String) parameters.get(0); 51 if (parameters.size() >= 2) { 52 sequencesName = (String) parameters.get(1); 53 } 54 } 55 catch (Exception e) { 56 throw new IllegalArgumentException(); 57 } 56 58 57 59 AndroidLogParser parser = new AndroidLogParser(); 58 60 59 60 61 } catch (Exception e) { 62 Console.printerrln("Could not parse " + filename + ": " 63 64 65 61 try { 62 parser.parseFile(filename); 63 } 64 catch (Exception e) { 65 Console.printerrln("Could not parse " + filename + ": " + e.getMessage()); 66 return; 67 } 66 68 67 69 Collection<List<Event>> sequences = parser.getSequences(); 68 70 69 71 GUIModel targets = parser.getGuiModel(); 70 72 71 72 73 73 if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) { 74 CommandHelpers.dataOverwritten(sequencesName); 75 } 74 76 75 if (GlobalDataContainer.getInstance().addData( 76 sequencesName + "_targets", targets)) { 77 CommandHelpers.dataOverwritten(sequencesName + "_targets"); 78 } 79 77 if (GlobalDataContainer.getInstance().addData(sequencesName + "_targets", targets)) { 78 CommandHelpers.dataOverwritten(sequencesName + "_targets"); 79 } 80 Console.traceln(Level.INFO, "parse done"); 81 } 80 82 81 83 /* 82 84 * (non-Javadoc) 83 85 * 84 86 * @see de.ugoe.cs.util.console.Command#help() 85 87 */ 86 87 88 89 90 88 @Override 89 public String help() { 90 91 return "parseAndroid <filename> {<sequencesName>}"; 92 } 91 93 92 94 } -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/commands/CMDparseDirAndroid.java
r1783 r1819 31 31 * <p> 32 32 * Command that tries to parse all files in a folder as if they were log files generated by the 33 * Androidmonitor. The result is one set of sequences for all files (not one set of sequences for each34 * file!).33 * Androidmonitor. The result is one set of sequences for all files (not one set of sequences for 34 * each file!). 35 35 * </p> 36 36 * … … 38 38 * @version 1.0 39 39 */ 40 public class CMDparseDirAndroid implements Command {40 public class CMDparseDirAndroid implements Command { 41 41 42 42 /* 43 43 * (non-Javadoc) 44 44 * 45 45 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 46 46 */ 47 48 49 47 @Override 48 public void run(List<Object> parameters) { 49 String path; 50 50 String sequencesName = "sequences"; 51 51 … … 59 59 throw new IllegalArgumentException(); 60 60 } 61 61 62 62 File folder = new File(path); 63 63 if (!folder.isDirectory()) { … … 65 65 return; 66 66 } 67 67 68 68 AndroidLogParser parser = new AndroidLogParser(); 69 69 70 70 String absolutPath = folder.getAbsolutePath(); 71 71 for (String filename : folder.list()) { … … 80 80 } 81 81 } 82 82 83 83 Collection<List<Event>> sequences = parser.getSequences(); 84 84 85 85 GUIModel targets = parser.getGuiModel(); 86 86 … … 88 88 CommandHelpers.dataOverwritten(sequencesName); 89 89 } 90 90 91 91 if (GlobalDataContainer.getInstance().addData(sequencesName + "_targets", targets)) { 92 92 CommandHelpers.dataOverwritten(sequencesName + "_targets"); 93 93 } 94 95 }96 94 97 /* 95 } 96 97 /* 98 98 * (non-Javadoc) 99 99 * 100 100 * @see de.ugoe.cs.util.console.Command#help() 101 101 */ 102 103 104 105 102 @Override 103 public String help() { 104 return "parseDirAndroid <directory> {<sequencesName>}"; 105 } 106 106 107 107 } -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDButton.java
r1813 r1819 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 14 15 package de.ugoe.cs.autoquest.plugin.android.guimodel; 15 16 … … 24 25 * @author Florian Unger 25 26 */ 26 public class ANDROIDButton extends ANDROIDGUIElement implements IButton {27 27 public class ANDROIDButton extends ANDROIDGUIElement implements IButton { 28 /** 28 29 * <p> 29 30 * Id for object serialization. … … 31 32 */ 32 33 private static final long serialVersionUID = 1L; 33 34 34 35 /** 35 36 * <p> … … 43 44 * window 44 45 */ 45 public ANDROIDButton(ANDROIDGUIElementSpec specification, 46 ANDROIDGUIElement parent) { 47 super(specification, parent); 48 // TODO Auto-generated constructor stub 49 } 50 46 public ANDROIDButton(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 47 super(specification, parent); 48 // TODO Auto-generated constructor stub 49 } 50 51 51 /* 52 52 * (non-Javadoc) -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDFrame.java
r1813 r1819 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 14 15 package de.ugoe.cs.autoquest.plugin.android.guimodel; 15 16 16 17 import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame; 18 17 19 /** 18 20 * <p> … … 23 25 * @author Florian Unger 24 26 */ 25 public class ANDROIDFrame extends ANDROIDGUIElement implements IFrame {26 27 public class ANDROIDFrame extends ANDROIDGUIElement implements IFrame { 28 /** 27 29 * <p> 28 30 * Id for object serialization. … … 30 32 */ 31 33 private static final long serialVersionUID = 1L; 32 34 33 35 /** 34 36 * <p> … … 42 44 * window 43 45 */ 44 public ANDROIDFrame(ANDROIDGUIElementSpec specification, 45 ANDROIDGUIElement parent) { 46 super(specification, parent); 47 } 46 public ANDROIDFrame(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 47 super(specification, parent); 48 } 48 49 49 50 /* 50 51 * (non-Javadoc) 51 52 * -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDGUIElement.java
r1790 r1819 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 14 15 package de.ugoe.cs.autoquest.plugin.android.guimodel; 15 16 … … 26 27 * @author Florian Unger 27 28 */ 28 public class ANDROIDGUIElement extends AbstractDefaultGUIElement {29 public class ANDROIDGUIElement extends AbstractDefaultGUIElement { 29 30 30 31 /** 31 32 * <p> 32 33 * Id for object serialization. … … 34 35 */ 35 36 private static final long serialVersionUID = 1L; 36 37 37 38 /** 38 39 * <p> … … 41 42 */ 42 43 private ANDROIDGUIElementSpec specification; 43 44 44 45 /** 45 46 * <p> … … 54 55 */ 55 56 public ANDROIDGUIElement(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 56 57 58 59 57 super(specification, parent); 58 this.specification = specification; 59 } 60 60 61 /* 61 62 * (non-Javadoc) … … 66 67 */ 67 68 @Override 68 69 //nothing do do here up to now. 70 69 public void updateSpecification(IGUIElementSpec furtherSpec) { 70 // nothing do do here up to now. 71 } 71 72 72 73 /* … … 75 76 * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getDistanceTo(IGUIElement) 76 77 */ 77 78 79 80 81 82 78 @Override 79 public double getDistanceTo(IGUIElement otherElement) { 80 throw new UnsupportedOperationException("not implemented yet"); 81 } 82 83 /** 83 84 * <p> 84 85 * Returns the type of the GUI element, i.e., the name of its Java class. … … 90 91 return specification.getType(); 91 92 } 92 93 94 93 95 94 /* 96 95 * (non-Javadoc) 97 96 * 98 97 * @see de.ugoe.cs.autoquest.eventcore.IEventTarget#getPlatform() 99 98 */ 100 101 102 103 99 @Override 100 public String getPlatform() { 101 return "Android"; 102 } 104 103 105 104 /* 106 105 * (non-Javadoc) 107 106 * 108 107 * @see java.lang.Object#toString() 109 108 */ 110 111 112 109 @Override 110 public String getStringIdentifier() { 111 String str = this.toString(); 113 112 if (getParent() != null) { 114 113 return str + "<-" + getParent().getStringIdentifier(); 115 114 } 116 115 return str; 117 118 119 116 } 117 118 /** 120 119 * <p> 121 120 * A short string describing the GUI element, e.g., Button, Canvas, or ScrollBar. -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDGUIElementSpec.java
r1815 r1819 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 14 15 package de.ugoe.cs.autoquest.plugin.android.guimodel; 15 16 … … 20 21 /** 21 22 * <p> 22 * Implements the specification of {@link IGUIElement} for 23 * {@link ANDROIDGUIElement}s. 23 * Implements the specification of {@link IGUIElement} for {@link ANDROIDGUIElement}s. 24 24 * </p> 25 25 * … … 29 29 public class ANDROIDGUIElementSpec implements IGUIElementSpec { 30 30 31 32 33 34 35 36 31 /** 32 * <p> 33 * default serial version UID 34 * </p> 35 */ 36 private static final long serialVersionUID = 1L; 37 37 38 /* 39 * (non-Javadoc) see 40 * de.ugoe.cs.autoquest.androidmonitor.AndroidmonitorLogFile#logComponent() 41 */ 42 /** 43 * <p> 44 * Hash code of the GUI element. Used as unique identifier during parsing a 45 * log file. Note that it is possible that the hash code of an element 46 * changes over several log files even if they come from the same target. 47 * </p> 48 */ 49 private int hashCode; 38 /* 39 * (non-Javadoc) see de.ugoe.cs.autoquest.androidmonitor.AndroidmonitorLogFile#logComponent() 40 */ 41 /** 42 * <p> 43 * Hash code of the GUI element. Used as unique identifier during parsing a log file. Note that 44 * it is possible that the hash code of an element changes over several log files even if they 45 * come from the same target. 46 * </p> 47 */ 48 private int hashCode; 50 49 51 /** 52 * <p> 53 * Path to an element in an activity. e.g. a path of a button could look 54 * like MainActivity/DecorView/ActionBarOverlayLayout/FrameLayout/ 55 * RelativeLayout/Button 56 * </p> 57 */ 58 private String path; 59 60 /** 61 * <p> 62 * id of the object as it is returned by view.getId() 63 * </p> 64 */ 65 private int index; 50 /** 51 * <p> 52 * Path to an element in an activity. e.g. a path of a button could look like 53 * MainActivity/DecorView/ActionBarOverlayLayout/FrameLayout/ RelativeLayout/Button 54 * </p> 55 */ 56 private String path; 66 57 67 /** 68 * <p> 69 * the type of GUI element represented by this specification, which is 70 * usually the java class of the android GUI element 71 * </p> 72 */ 73 private String type; 74 75 /** 58 /** 59 * <p> 60 * id of the object as it is returned by view.getId() 61 * </p> 62 */ 63 private int index; 64 65 /** 66 * <p> 67 * the type of GUI element represented by this specification, which is usually the java class of 68 * the android GUI element 69 * </p> 70 */ 71 private String type; 72 73 /** 76 74 * <p> 77 75 * Type hierarchy of the class itself … … 80 78 private List<String> typeHierarchy = null; 81 79 82 83 84 85 86 87 88 89 90 80 /* 81 * (non-Javadoc) 82 * 83 * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getType() 84 */ 85 @Override 86 public String getType() { 87 return type; 88 } 91 89 92 /* 93 * (non-Javadoc) 94 * 95 * @see 96 * de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getTypeHierarchy 97 * () 98 */ 99 @Override 100 public String[] getTypeHierarchy() { 101 if (typeHierarchy == null) { 90 /* 91 * (non-Javadoc) 92 * 93 * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getTypeHierarchy () 94 */ 95 @Override 96 public String[] getTypeHierarchy() { 97 if (typeHierarchy == null) { 102 98 return new String[] 103 99 { (getType()) }; … … 105 101 else 106 102 return typeHierarchy.toArray(new String[typeHierarchy.size()]); 107 103 } 108 104 109 110 111 112 113 105 @Override 106 public boolean getSimilarity(IGUIElementSpec other) { 107 if (this == other) { 108 return true; 109 } 114 110 115 116 117 111 if (!(other instanceof ANDROIDGUIElementSpec)) { 112 return false; 113 } 118 114 119 120 121 122 123 124 125 115 // Check wheter view.id() keeps the same even if something in the 116 // structure changes. The hash in the JFCMonitor seems to be unique at 117 // all. In the Androidmonitore the hash of an element changes even from 118 // one start of the activity to another. 119 /* 120 * Maybe some other comparisons will be necessary in the future. 121 */ 126 122 127 128 123 return false; 124 } 129 125 130 131 132 133 134 135 136 137 138 126 /* 127 * (non-Javadoc) 128 * 129 * @see java.lang.Object#hashCode() 130 */ 131 @Override 132 public int hashCode() { 133 return hashCode; 134 } 139 135 140 /** 141 * <p> 142 * Returns the path associated with the specified GUI element. 143 * </p> 144 * @return the path to an element 145 */ 146 public String getPath() { 147 return path; 148 } 136 /** 137 * <p> 138 * Returns the path associated with the specified GUI element. 139 * </p> 140 * 141 * @return the path to an element 142 */ 143 public String getPath() { 144 return path; 145 } 149 146 150 151 152 147 public int getIndex() { 148 return index; 149 } 153 150 154 155 156 151 public void setIndex(int index) { 152 this.index = index; 153 } 157 154 158 /** 159 * Set the hash code associated with the GUI element. 160 * @param hash 161 * the hash of an element object 162 */ 163 public void setHashCode(int hash){ 164 this.hashCode = hash; 165 } 166 167 /** 168 * Set the path associated with the specified GUI element. 169 * @param path 170 * the path to an element 171 */ 172 public void setPath(String path) { 173 this.path = path; 174 } 175 176 /** 155 /** 156 * Set the hash code associated with the GUI element. 157 * 158 * @param hash 159 * the hash of an element object 160 */ 161 public void setHashCode(int hash) { 162 this.hashCode = hash; 163 } 164 165 /** 166 * Set the path associated with the specified GUI element. 167 * 168 * @param path 169 * the path to an element 170 */ 171 public void setPath(String path) { 172 this.path = path; 173 } 174 175 /** 177 176 * <p> 178 177 * Sets the type of the specified GUI element. … … 185 184 this.type = type; 186 185 } 187 186 188 187 /** 189 188 * <p> … … 196 195 this.typeHierarchy = typeHierarchy; 197 196 } 198 199 197 200 198 } -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDPanel.java
r1813 r1819 25 25 * @author Florian Unger 26 26 */ 27 public class ANDROIDPanel extends ANDROIDGUIElement implements IPanel {27 public class ANDROIDPanel extends ANDROIDGUIElement implements IPanel { 28 28 29 29 /** 30 30 * <p> 31 31 * Id for object serialization. 32 32 * </p> 33 33 */ 34 private static final long serialVersionUID = 1L; 35 34 private static final long serialVersionUID = 1L; 35 36 36 /** 37 37 * <p> … … 45 45 * window 46 46 */ 47 public ANDROIDPanel(ANDROIDGUIElementSpec specification, 48 ANDROIDGUIElement parent) { 49 super(specification, parent); 50 51 } 47 public ANDROIDPanel(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 48 super(specification, parent); 52 49 53 /* 50 } 51 52 /* 54 53 * (non-Javadoc) 55 54 * … … 60 59 return "Panel"; 61 60 } 62 61 63 62 } -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDRadioButton.java
r1811 r1819 25 25 * @author Florian Unger 26 26 */ 27 public class ANDROIDRadioButton extends ANDROIDGUIElement implements IRadioButton {27 public class ANDROIDRadioButton extends ANDROIDGUIElement implements IRadioButton { 28 28 29 29 /** 30 30 * <p> 31 31 * Id for object serialization. … … 45 45 * window 46 46 */ 47 public ANDROIDRadioButton(ANDROIDGUIElementSpec specification, 48 ANDROIDGUIElement parent) { 49 super(specification, parent); 50 } 47 public ANDROIDRadioButton(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 48 super(specification, parent); 49 } 51 50 52 51 /* 53 52 * (non-Javadoc) 54 53 * -
trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDTextField.java
r1813 r1819 25 25 * @author Florian Unger 26 26 */ 27 public class ANDROIDTextField extends ANDROIDGUIElement implements ITextField {27 public class ANDROIDTextField extends ANDROIDGUIElement implements ITextField { 28 28 29 29 /** 30 30 * <p> 31 31 * Id for object serialization. … … 45 45 * window 46 46 */ 47 public ANDROIDTextField(ANDROIDGUIElementSpec specification, 48 ANDROIDGUIElement parent) { 49 super(specification, parent); 50 51 } 52 53 /* 47 public ANDROIDTextField(ANDROIDGUIElementSpec specification, ANDROIDGUIElement parent) { 48 super(specification, parent); 49 50 } 51 52 /* 54 53 * (non-Javadoc) 55 54 *
Note: See TracChangeset
for help on using the changeset viewer.