- Timestamp:
- 01/07/15 14:04:59 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-jfc/src/main/java/de/ugoe/cs/autoquest/plugin/jfc/commands/CMDgenerateJacaretoReplay.java
r1838 r1856 50 50 import de.ugoe.cs.util.console.GlobalDataContainer; 51 51 52 // helper class for the tree like structure part within a Jacareto file53 class StructureNode {54 public static int nextRef = 0;55 56 public String content;57 public ArrayList<StructureNode> children;58 59 public StructureNode(String type) {60 setContent(type);61 children = new ArrayList<StructureNode>();62 }63 64 public StructureNode() {65 content = "<Recordable ref=\"" + (nextRef++) + "\" />";66 children = new ArrayList<StructureNode>();67 }68 69 public void setContent(String type) {70 content = "<StructureElement class=\"jacareto.struct." + type + "\">";71 }72 73 public StructureNode add(String type) {74 StructureNode node = new StructureNode(type);75 children.add(node);76 return node;77 }78 79 public void addRecordable() {80 children.add(new StructureNode());81 }82 83 @Override84 public String toString() {85 String separator = System.getProperty("line.separator");86 String result = content + separator;87 88 for (StructureNode child : children) {89 result += child.toString();90 }91 92 if (content.endsWith("/>")) {93 return result;94 }95 return result + "</StructureElement>" + separator;96 }97 }98 99 52 /** 100 53 * <p> … … 106 59 */ 107 60 public class CMDgenerateJacaretoReplay implements Command { 61 62 /** 63 * <p> 64 * Helper class for the tree like structure part within a Jacareto file. 65 * </p> 66 */ 67 private static class StructureNode { 68 69 /** 70 * <p> 71 * Keeps track of the next structure node id. 72 * </p> 73 */ 74 public static int nextRef = 0; 75 76 /** 77 * <p> 78 * The node's type packaged into an XML string. 79 * </p> 80 */ 81 public String content; 82 83 /** 84 * <p> 85 * This node's children. 86 * </p> 87 */ 88 public ArrayList<StructureNode> children; 89 90 /** 91 * <p> 92 * Constructor. Creates a new StructureNode of a specified type and builds its Jacareto XML 93 * representation. 94 * </p> 95 * 96 * @param type 97 * the type of this StructureNode, for example: 'MouseDownEvent' 98 */ 99 public StructureNode(String type) { 100 setContent(type); 101 children = new ArrayList<StructureNode>(); 102 } 103 104 /** 105 * <p> 106 * Constructor. Creates a StructureNode of type 'Recordable' with a valid id and builds its 107 * Jacareto XML representation. 108 * </p> 109 */ 110 public StructureNode() { 111 content = "<Recordable ref=\"" + (nextRef++) + "\" />"; 112 children = new ArrayList<StructureNode>(); 113 } 114 115 /** 116 * <p> 117 * Builds the XML representation of a Jacareto structure type. 118 * </p> 119 * 120 * @param type 121 * the type of this StructureNode, for example: 'MouseDownEvent' 122 */ 123 public void setContent(String type) { 124 content = "<StructureElement class=\"jacareto.struct." + type + "\">"; 125 } 126 127 /** 128 * <p> 129 * Adds a new StructureNode as a child of this node. 130 * </p> 131 * 132 * @param type 133 * the type of the child node, for example: 'MouseDownEvent' 134 */ 135 public StructureNode add(String type) { 136 StructureNode node = new StructureNode(type); 137 children.add(node); 138 return node; 139 } 140 141 /** 142 * <p> 143 * Builds the XML representation of a Jacareto structure type. 144 * </p> 145 * 146 * @param type 147 * the type of this StructureNode, for example: 'MouseDownEvent' 148 */ 149 public void addRecordable() { 150 children.add(new StructureNode()); 151 } 152 153 /** 154 * <p> 155 * Returns a Jacareto XML representation of this StructureNode, includin all its children. 156 * </p> 157 */ 158 @Override 159 public String toString() { 160 String separator = System.getProperty("line.separator"); 161 String result = content + separator; 162 163 for (StructureNode child : children) { 164 result += child.toString(); 165 } 166 167 if (content.endsWith("/>")) { 168 return result; 169 } 170 return result + "</StructureElement>" + separator; 171 } 172 } 173 174 /** 175 * <p> 176 * The time it takes for Jacareto to replay an event in ms. 177 * </p> 178 */ 108 179 private static final int EVENT_DURATION = 150; 180 181 /** 182 * <p> 183 * The time it takes for Jacareto to replay each part of a double click event in ms. 184 * </p> 185 */ 109 186 private static final int DOUBLE_CLICK_DURATION = 50; 187 188 /** 189 * <p> 190 * Application startup time in ms. The application needs to be fully initialized before Jacareto 191 * can start replaying. 192 * </p> 193 */ 110 194 private static final int STARTUP_DELAY = 10000; 111 195 196 /** 197 * <p> 198 * The GUI element which is currently focused. 199 * </p> 200 */ 112 201 private JFCGUIElement currentFocus; 202 203 /** 204 * <p> 205 * A tree of StructureNodes which represents the structure part inside a Jacareto XML file. 206 * </p> 207 */ 113 208 private StructureNode structure; 114 209 210 /** 211 * <p> 212 * XML structure for key events modeled as StructureNodes. 213 * </p> 214 */ 115 215 private StructureNode lastKeySequenceEvent; 216 217 /** 218 * <p> 219 * XML structure for key events modeled as StructureNodes. 220 * </p> 221 */ 116 222 private StructureNode lastKeyTypedEvent; 223 224 /** 225 * <p> 226 * Bitmask which represents currently used key modifiers (such as shift etc). 227 * </p> 228 */ 117 229 private int currentKeyModifiers; 118 230 231 /** 232 * <p> 233 * Maps VirtualKey objects for modifier keys back to AWT Event codes. 234 * </p> 235 */ 119 236 private HashMap<VirtualKey, Integer> modifiers; 120 237 238 /** 239 * <p> 240 * XML structure for mouse events modeled as StructureNodes. 241 * </p> 242 */ 121 243 private StructureNode lastMouseClickEvent; 244 245 /** 246 * <p> 247 * XML structure for focus events modeled as StructureNodes. 248 * </p> 249 */ 122 250 private StructureNode lastFocusChangeEvent; 251 252 /** 253 * <p> 254 * XML structure for item and action events modeled as StructureNodes. 255 * </p> 256 */ 123 257 private StructureNode lastItemActionEvent; 258 259 /** 260 * <p> 261 * The target of the last mouseDownEvent. It is necessary to save this because mouse down and up 262 * targets can differ. 263 * </p> 264 */ 124 265 private IEventTarget lastMouseDownTarget; 266 267 /** 268 * <p> 269 * Associates the name of a menu element with its corresponding JFCGUIElement. 270 * </p> 271 */ 125 272 private HashMap<String, JFCGUIElement> menuElements; 273 274 /** 275 * <p> 276 * The menu hierarchy. 277 * </p> 278 */ 126 279 private List<String> menuList; 127 280 … … 184 337 185 338 sequences = (Collection<List<Event>>) dataObject; 186 187 339 menuElements = new HashMap<>(); 188 189 // map which maps VirtualKeys back to awt key modifier codes 190 modifiers = new HashMap<>(); 191 modifiers.put(VirtualKey.SHIFT, 1); 192 modifiers.put(VirtualKey.CONTROL, 2); 193 modifiers.put(VirtualKey.ALT, 8); 194 modifiers.put(VirtualKey.ALT_GRAPH, 32); 340 modifiers = createModifierMap(); 195 341 currentKeyModifiers = 0; 196 197 342 StructureNode.nextRef = 0; 198 343 … … 200 345 } 201 346 347 /** 348 * <p> 349 * Associates keyboard modifier keys with their AWT event codes. 350 * </p> 351 */ 352 private HashMap<VirtualKey, Integer> createModifierMap() { 353 HashMap<VirtualKey, Integer> result = new HashMap<>(); 354 355 result.put(VirtualKey.SHIFT, 1); 356 result.put(VirtualKey.CONTROL, 2); 357 result.put(VirtualKey.ALT, 8); 358 result.put(VirtualKey.ALT_GRAPH, 32); 359 360 return result; 361 } 362 363 /** 364 * <p> 365 * Writes a line and creates a new line. 366 * </p> 367 * 368 * @param writer 369 * the BufferedWriter which writes the XML 370 * @param line 371 * the line to write 372 * 373 */ 202 374 private void writeLine(BufferedWriter writer, String line) throws IOException { 203 375 writer.write(line); … … 205 377 } 206 378 379 /** 380 * <p> 381 * Writes the Jacareto XML head part. This mainly contains information about the state of the 382 * system when the replay was captured. 383 * 384 * @param writer 385 * the BufferedWriter which writes the XML 386 * @param classname 387 * name of the main class of the program that will be replayed 388 * @param basepath 389 * a basepath that is prepended to all paths specified in classpathext 390 * @param classpathext 391 * additional required resources (e.g. jar files) 392 * 393 * </p> 394 */ 207 395 private void writeJacaretoHead(BufferedWriter writer, 208 396 String classname, … … 251 439 } 252 440 441 /** 442 * <p> 443 * Writes Jacareto XML code for all events within the Autoquest sequences. 444 * </p> 445 * 446 * @param writer 447 * the BufferedWriter which writes the XML 448 * @param sequences 449 * the Autoquest sequences 450 * 451 */ 253 452 private void writeJacaretoEvents(BufferedWriter writer, Collection<List<Event>> sequences) 254 453 throws IOException … … 267 466 268 467 if (event.getType() instanceof MouseButtonDown) { 269 handleMouse Down(writer, event, "MouseClick");468 handleMouseButtonDown(writer, event); 270 469 } 271 470 else if (event.getType() instanceof MouseButtonUp) { 272 handleMouse Up(writer, event);471 handleMouseButtonUp(writer, event); 273 472 } 274 473 else if (event.getType() instanceof MouseDoubleClick) { 275 StructureNode multiClick = structure.add("MultipleMouseClick"); 276 277 // first click 278 lastMouseClickEvent = multiClick.add("MouseClick"); 279 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 280 DOUBLE_CLICK_DURATION, 501); 281 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 282 DOUBLE_CLICK_DURATION, 502); 283 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 284 DOUBLE_CLICK_DURATION, 500); 285 // second click 286 lastMouseClickEvent = multiClick.add("MouseClick"); 287 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 288 DOUBLE_CLICK_DURATION, 501); 289 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 290 DOUBLE_CLICK_DURATION, 502); 291 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 292 DOUBLE_CLICK_DURATION, 500); 293 294 lastMouseClickEvent = null; 474 handleMouseDoubleClick(writer, event); 295 475 } 296 476 else if (event.getType() instanceof MouseClick) { … … 315 495 } 316 496 317 lastKeySequenceEvent = null; 318 319 if (lastMouseClickEvent != null) { 320 if (lastMouseDownTarget == event.getTarget()) { 321 // this is the standard case: 322 // mouseDown, mouseUp and mouseClick sequence 323 // was triggered on this target 324 325 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 326 EVENT_DURATION, 500); 327 writeItemActionEvent(writer, event); 328 329 if (lastFocusChangeEvent == null) { 330 // write structure sequentially 331 structure.children.add(lastMouseClickEvent); 332 structure.children.add(lastItemActionEvent); 333 } 334 else { 335 // with nested structure 336 structure.children.add(lastItemActionEvent); 337 lastItemActionEvent.children.add(0, lastFocusChangeEvent); 338 lastFocusChangeEvent.children.add(0, lastMouseClickEvent); 339 340 lastFocusChangeEvent = null; 341 lastMouseClickEvent = null; 342 } 343 } 344 else { 345 // target of mouseDown and mouseClick are different 346 // -> this is, for example, a click on a menu item 347 // within a condensed sequence 348 commitFocusEvent(); 349 350 // finish the last click on the old target 351 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 352 EVENT_DURATION, 500); 353 structure.children.add(lastMouseClickEvent); 354 355 // and generate a new one 356 generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 357 } 358 } 359 else { 360 // a target was clicked repeatedly: 361 // the condensed sequence contains no mouseDowns or 362 // mouseUps anymore 363 // -> just generate another full click 364 generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 365 } 497 handleMouseClick(writer, event); 366 498 } 367 499 else if (event.getType() instanceof KeyboardFocusChange) { 368 lastKeySequenceEvent = null; 369 370 writeFocusChangeEvent(writer, event); 500 handleKeyboardFocusChange(writer, event); 371 501 } 372 502 else if (event.getType() instanceof MouseDragAndDrop) { … … 390 520 } 391 521 392 private void handleMouseDown(BufferedWriter writer, Event event, String structureName) 393 throws IOException 394 { 522 // EVENT HANDLERS 523 524 private void handleMouseClick(BufferedWriter writer, Event event) throws IOException { 525 lastKeySequenceEvent = null; 526 527 if (lastMouseClickEvent != null) { 528 if (lastMouseDownTarget == event.getTarget()) { 529 // this is the standard case: 530 // mouseDown, mouseUp and mouseClick sequence 531 // was triggered on this target 532 533 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 534 EVENT_DURATION, 500); 535 writeItemActionEvent(writer, event); 536 537 if (lastFocusChangeEvent == null) { 538 // write structure sequentially 539 structure.children.add(lastMouseClickEvent); 540 structure.children.add(lastItemActionEvent); 541 } 542 else { 543 // with nested structure 544 structure.children.add(lastItemActionEvent); 545 lastItemActionEvent.children.add(0, lastFocusChangeEvent); 546 lastFocusChangeEvent.children.add(0, lastMouseClickEvent); 547 548 lastFocusChangeEvent = null; 549 lastMouseClickEvent = null; 550 } 551 } 552 else { 553 // target of mouseDown and mouseClick are different 554 // -> this is, for example, a click on a menu item 555 // within a condensed sequence 556 commitFocusEvent(); 557 558 // finish the last click on the old target 559 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 560 EVENT_DURATION, 500); 561 structure.children.add(lastMouseClickEvent); 562 563 // and generate a new one 564 generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 565 } 566 } 567 else { 568 // a target was clicked repeatedly: 569 // the condensed sequence contains no mouseDowns or 570 // mouseUps anymore 571 // -> just generate another full click 572 generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 573 } 574 575 } 576 577 private void handleMouseDoubleClick(BufferedWriter writer, Event event) throws IOException { 578 StructureNode multiClick = structure.add("MultipleMouseClick"); 579 580 // first click 581 lastMouseClickEvent = multiClick.add("MouseClick"); 582 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 583 DOUBLE_CLICK_DURATION, 501); 584 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 585 DOUBLE_CLICK_DURATION, 502); 586 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 587 DOUBLE_CLICK_DURATION, 500); 588 // second click 589 lastMouseClickEvent = multiClick.add("MouseClick"); 590 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 591 DOUBLE_CLICK_DURATION, 501); 592 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 593 DOUBLE_CLICK_DURATION, 502); 594 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 595 DOUBLE_CLICK_DURATION, 500); 596 597 lastMouseClickEvent = null; 598 599 } 600 601 private void handleKeyboardFocusChange(BufferedWriter writer, Event event) throws IOException { 602 lastKeySequenceEvent = null; 603 writeFocusChangeEvent(writer, event); 604 } 605 606 private void handleMouseButtonDown(BufferedWriter writer, Event event) throws IOException { 395 607 commitFocusEvent(); 396 608 lastKeySequenceEvent = null; 397 609 398 lastMouseClickEvent = new StructureNode( structureName);610 lastMouseClickEvent = new StructureNode("MouseClick"); 399 611 lastMouseDownTarget = event.getTarget(); 400 612 writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), EVENT_DURATION, 501); 401 613 } 402 614 403 private void handleMouse Up(BufferedWriter writer, Event event) throws IOException {615 private void handleMouseButtonUp(BufferedWriter writer, Event event) throws IOException { 404 616 lastKeySequenceEvent = null; 405 617
Note: See TracChangeset
for help on using the changeset viewer.