Changeset 171 for trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows
- Timestamp:
- 09/09/11 06:23:36 (13 years ago)
- Location:
- trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/EventGenerator.java
r141 r171 17 17 import org.jdom.input.SAXBuilder; 18 18 19 import de.ugoe.cs.eventbench.data.Event; 19 20 import de.ugoe.cs.eventbench.windows.data.WindowTree; 20 21 import de.ugoe.cs.eventbench.windows.data.WindowTreeNode; … … 24 25 /** 25 26 * <p> 26 * Translates sequences of windows messages into events that can be used by the27 * Logalyzer core libraries for usage analysis.27 * Translates sequences of windows messages into {@link WindowsEvent}s that can 28 * be used by the EventBench core libraries. 28 29 * </p> 29 30 * 30 31 * @author Steffen Herbold 31 * 32 * @version 1.0 32 33 */ 33 34 public class EventGenerator { … … 214 215 } 215 216 216 private boolean createSequenceLParam( 217 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 218 int constMsgType, Element termElement) 219 throws NoSuchElementException { 220 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 221 if (termElement.getName().equals("seqValue")) { 222 String obj = termElement.getAttributeValue("seqObj"); 223 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 224 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 225 throw new InvalidParameterException( 226 "Failure generating replay sequence for rule " 227 + currentRuleName 228 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 229 } 230 for (WindowsMessage msg : seqVar) { 231 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 232 generatedMessageSeq, msgsGenerated, constMsgType, 233 seqIterator); 234 String paramValueStr = msg.getParameter(termElement 235 .getAttributeValue("param")); 236 int paramValue = 0; 237 try { 238 paramValue = Integer.parseInt(paramValueStr); 239 currentSeqMsg.setLPARAM(paramValue); 240 } catch (NumberFormatException e) { 241 currentSeqMsg.setLPARAMasWindowDesc(paramValueStr); 242 } 243 } 244 if (seqIterator.hasNext()) { 245 // the first seq-var has a different number of elements than the 246 // current one 247 throw new NoSuchElementException(); 248 } 249 msgsGenerated = true; 250 } else { // const value 251 int paramValue = Integer.parseInt(getTermValue(null, termElement)); 252 while (seqIterator.hasNext()) { 253 seqIterator.next().setLPARAM(paramValue); 254 } 255 } 256 return msgsGenerated; 257 } 258 259 private boolean createSequenceTarget( 260 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 261 int constMsgType, Element termElement) 262 throws NoSuchElementException { 263 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 264 if (termElement.getName().equals("seqValue")) { 265 String obj = termElement.getAttributeValue("seqObj"); 266 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 267 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 268 throw new InvalidParameterException( 269 "Failure generating replay sequence for rule " 270 + currentRuleName 271 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 272 } 273 for (WindowsMessage msg : seqVar) { 274 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 275 generatedMessageSeq, msgsGenerated, constMsgType, 276 seqIterator); 277 String targetString = msg.getParameter(termElement 278 .getAttributeValue("param")); 279 currentSeqMsg.setXmlWindowDescription(targetString); 280 } 281 msgsGenerated = true; 282 } else { // const value 283 throw new AssertionError("target must be a sequence variable!"); 217 // //////////////////////////////////////////////////////////// 218 // Helper functions for matching of events, i.e., msg-nodes // 219 // //////////////////////////////////////////////////////////// 220 221 /** 222 * <p> 223 * Handles msg-nodes where multiple is not true, i.e., not a sequences. 224 * </p> 225 * 226 * @param messageElement 227 * {@link Element} representing the msg-node 228 * @return true, if a match is found; false otherwise 229 */ 230 private boolean matchSingleMessage(Element messageElement) { 231 boolean isMatch = false; 232 WindowsMessage currentMessage = null; 233 234 int type = Integer.parseInt(messageElement.getAttributeValue("type")); 235 236 while (!isMatch && sequenceIterator.hasNext()) { 284 237 /* 285 * If target would not be a variable, the message-elements could not 286 * yet be created and the whole sequence might be broken. If this is 287 * to be changed, createSequenceLParam and createSequenceWParam need 288 * to be addepted, too. 238 * traverses the messages from the current position forward till a 239 * message with the correct type is found 289 240 */ 290 } 291 return msgsGenerated; 292 } 293 294 private boolean createSequenceWParam( 295 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 296 int constMsgType, Element termElement) 297 throws NoSuchElementException { 298 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 299 if (termElement.getName().equals("seqValue")) { 300 String obj = termElement.getAttributeValue("seqObj"); 301 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 302 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 303 throw new InvalidParameterException( 304 "Failure generating replay sequence for rule " 305 + currentRuleName 306 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 307 } 308 for (WindowsMessage msg : seqVar) { 309 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 310 generatedMessageSeq, msgsGenerated, constMsgType, 311 seqIterator); 312 String paramValueStr = msg.getParameter(termElement 313 .getAttributeValue("param")); 314 int paramValue = 0; 315 try { 316 paramValue = Integer.parseInt(paramValueStr); 317 currentSeqMsg.setWPARAM(paramValue); 318 } catch (NumberFormatException e) { 319 currentSeqMsg.setWPARAMasWindowDesc(paramValueStr); 320 } 321 } 322 if (seqIterator.hasNext()) { 323 // the first seq-var has a different number of elements than the 324 // current one 325 throw new NoSuchElementException(); 326 } 327 msgsGenerated = true; 328 } else { // const value 329 int paramValue = Integer.parseInt(getTermValue(null, termElement)); 330 while (seqIterator.hasNext()) { 331 seqIterator.next().setWPARAM(paramValue); 332 } 333 } 334 return msgsGenerated; 335 } 336 241 currentMessage = sequenceIterator.next(); 242 if (type == currentMessage.getType()) { 243 // message with the correct type found 244 // eval child nodes for further matching/storing 245 isMatch = evalEqualRestrictions(currentMessage, messageElement); 246 247 // in case the message is a match, eval storage children 248 if (isMatch) { 249 handleStorage(messageElement, currentMessage); 250 currentToken.setTarget(currentMessage 251 .getXmlWindowDescription()); 252 currentToken 253 .setTargetShort(currentMessage.getParentNames()); 254 } 255 } 256 } 257 258 return isMatch; 259 } 260 261 /** 262 * <p> 263 * Handles msg-nodes where multiple is true, i.e., sequences. Requires 264 * knowledge about the next msg-node to determine the end of the sequence. 265 * </p> 266 * 267 * @param messageElement 268 * {@link Element} representing the msg-node 269 * @param nextMessageElement 270 * {@link Element} representing the next msg-node; {@code null} 271 * if the current node is the last one 272 * @return true, if a sequence is matched; false otherwise 273 */ 274 private boolean matchMultipleMessages(Element messageElement, 275 Element nextMessageElement) { 276 boolean isMatch = false; 277 boolean isCurrentMatch = false; 278 boolean nextMatchFound = false; 279 WindowsMessage currentMessage = null; 280 WindowsMessage nextMessage = null; 281 282 int type = Integer.parseInt(messageElement.getAttributeValue("type")); 283 284 int nextType = -1; 285 if (nextMessageElement != null) { 286 nextType = Integer.parseInt(nextMessageElement 287 .getAttributeValue("type")); 288 } 289 290 while (!nextMatchFound && sequenceIterator.hasNext()) { 291 currentMessage = sequenceIterator.next(); 292 if (type == currentMessage.getType()) { 293 isCurrentMatch = evalEqualRestrictions(currentMessage, 294 messageElement); 295 isMatch = isMatch || isCurrentMatch; 296 297 if (isCurrentMatch) { 298 handleStorage(messageElement, currentMessage); 299 currentToken.setTarget(currentMessage 300 .getXmlWindowDescription()); 301 currentToken 302 .setTargetShort(currentMessage.getParentNames()); 303 } 304 } 305 if (nextMessageElement != null && isMatch) { 306 // peek next message to check if the sequence ends and the next 307 // match is found 308 if (!sequenceIterator.hasNext()) { 309 return false; // sequence is over, but not all messages are 310 // found 311 } 312 nextMessage = sequenceIterator.next(); 313 sequenceIterator.previous(); 314 315 if (nextType == nextMessage.getType()) { 316 nextMatchFound = evalEqualRestrictions(nextMessage, 317 nextMessageElement); 318 } 319 320 } 321 } 322 323 return isMatch; 324 } 325 326 /** 327 * <p> 328 * Handles equals-nodes. 329 * </p> 330 * 331 * @param currentMessage 332 * {@link Element} representing the msg-node the equals-node 333 * belongs to 334 * @param messageElement 335 * {@link Element} representing the equals-node to be evaluated 336 * @return true, if constraint is fulfilled; false otherwise 337 */ 337 338 @SuppressWarnings("unchecked") 338 339 private boolean evalEqualRestrictions(WindowsMessage currentMessage, … … 354 355 "equalsSeq", rulesNamespace)) { 355 356 List<Element> termElements = childElement.getChildren(); 356 List<String> values1 = getTermValueSeq(currentMessage, 357 termElements.get(0)); 358 List<String> values2 = getTermValueSeq(currentMessage, 359 termElements.get(0)); 357 List<String> values1 = getTermValueSeq(termElements.get(0)); 358 List<String> values2 = getTermValueSeq(termElements.get(0)); 360 359 if (values1 == null || values2 == null) { 361 360 isMatch = false; … … 367 366 } 368 367 368 /** 369 * <p> 370 * Handles store-nodes and storeSeq-nodes. 371 * </p> 372 * 373 * @param messageElement 374 * {@link Element} representing the msg-node that is currently 375 * being evaluated 376 * @param currentMessage 377 * current message in the message sequence that is matched; this 378 * is the message that is stored 379 */ 380 @SuppressWarnings("unchecked") 381 private void handleStorage(Element messageElement, 382 WindowsMessage currentMessage) { 383 for (Element childElement : (List<Element>) messageElement.getChildren( 384 "store", rulesNamespace)) { 385 String identifier = childElement.getAttributeValue("var"); 386 messageStorage.put(identifier, currentMessage); 387 resolveHwnd(currentMessage, childElement); 388 } 389 for (Element childElement : (List<Element>) messageElement.getChildren( 390 "storeSeq", rulesNamespace)) { 391 String identifier = childElement.getAttributeValue("varSeq"); 392 Object tmp = messageStorage.get(identifier); 393 List<WindowsMessage> storedSequence; 394 if (tmp == null || tmp instanceof WindowsMessage) { 395 storedSequence = new LinkedList<WindowsMessage>(); 396 storedSequence.add(currentMessage); 397 messageStorage.put(identifier, storedSequence); 398 } else if (tmp instanceof List<?>) { 399 storedSequence = (List<WindowsMessage>) tmp; 400 storedSequence.add(currentMessage); 401 messageStorage.put(identifier, storedSequence); 402 } 403 resolveHwnd(currentMessage, childElement); 404 } 405 } 406 407 /** 408 * <p> 409 * Resolves a parameter that contains a HWND of a message to the target 410 * string of the HWND and stores it. 411 * </p> 412 * 413 * @param currentMessage 414 * message whose HWND is resolved 415 * @param childElement 416 * child element of the store node that represents the resolve 417 */ 418 @SuppressWarnings("unchecked") 419 private void resolveHwnd(WindowsMessage currentMessage, Element childElement) { 420 List<Element> resolveElements = childElement.getChildren("resolveHwnd", 421 rulesNamespace); 422 for (Element resolveElement : resolveElements) { 423 String param = resolveElement.getAttributeValue("param"); 424 String storeParam = resolveElement.getAttributeValue("storeParam"); 425 int paramHwnd = Integer 426 .parseInt(currentMessage.getParameter(param)); 427 WindowTreeNode node = WindowTree.getInstance().find(paramHwnd); 428 if (node != null) { 429 currentMessage.addParameter(storeParam, 430 node.xmlRepresentation()); 431 } 432 } 433 } 434 435 // ///////////////////////////////////////////////////// 436 // Helper functions for generating the replay, i.e., 437 // parsing of genMsg und genMsgSeq-nodes 438 // ///////////////////////////////////////////////////// 439 440 /** 441 * <p> 442 * Handles genMsg-nodes and adds the replay to the {@link Event} that is 443 * generated. 444 * </p> 445 * 446 * @param genMsgElement 447 * {@link Element} representing the genMsg-node 448 */ 369 449 @SuppressWarnings("unchecked") 370 450 private void generateReplayMessage(Element genMsgElement) { … … 396 476 String paramValueStr = getTermValue(null, termElement); 397 477 long paramValue = 0; 398 Element loword = genMsgChild.getChild("LOWORD", rulesNamespace); 399 if( loword!=null ) { 478 Element loword = genMsgChild.getChild("LOWORD", 479 rulesNamespace); 480 if (loword != null) { 400 481 paramValue = loHiWord(genMsgChild); 401 482 generatedMessage.setLPARAM(paramValue); … … 405 486 generatedMessage.setLPARAM(paramValue); 406 487 } catch (NumberFormatException e) { 407 generatedMessage.setLPARAMasWindowDesc(paramValueStr); 488 generatedMessage 489 .setLPARAMasWindowDesc(paramValueStr); 408 490 } 409 491 } … … 411 493 String paramValueStr = getTermValue(null, termElement); 412 494 long paramValue = 0; 413 Element loword = genMsgChild.getChild("LOWORD", rulesNamespace); 414 if( loword!=null ) { 495 Element loword = genMsgChild.getChild("LOWORD", 496 rulesNamespace); 497 if (loword != null) { 415 498 paramValue = loHiWord(genMsgChild); 416 499 generatedMessage.setWPARAM(paramValue); … … 420 503 generatedMessage.setWPARAM(paramValue); 421 504 } catch (NumberFormatException e) { 422 generatedMessage.setWPARAMasWindowDesc(paramValueStr); 505 generatedMessage 506 .setWPARAMasWindowDesc(paramValueStr); 423 507 } 424 508 } … … 436 520 } 437 521 522 /** 523 * Handles genMsgSeq-nodes and adds the replay to the {@link Event} that is 524 * generated.</p> 525 * 526 * @param genMsgElement 527 * {@link Element} representing the genMsgSeq-node. 528 */ 438 529 @SuppressWarnings("unchecked") 439 530 private void generateReplaySequence(Element genMsgElement) { … … 479 570 } 480 571 572 /** 573 * <p> 574 * Creates the targets for replay sequences generated with genMsgSeq-nodes. 575 * </p> 576 * 577 * @param generatedMessageSeq 578 * list of the messages that is being generated 579 * @param msgsGenerated 580 * boolean stating if the list of messages is already generated 581 * or if the generation has to be handles by this method 582 * @param constMsgType 583 * a constant message type that is used for message generation, 584 * in case the list of message is generated by this method 585 * @param termElement 586 * {@link Element} representing the term-node describing the 587 * target 588 * @return true, if the list of message is generated after calling this 589 * method; false otherwise 590 * @throws NoSuchElementException 591 * thrown if the seqVar referred to in the termElement contains 592 * a different number of messages than is contained in 593 * messageSeq 594 */ 595 private boolean createSequenceTarget( 596 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 597 int constMsgType, Element termElement) 598 throws NoSuchElementException { 599 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 600 if (termElement.getName().equals("seqValue")) { 601 String obj = termElement.getAttributeValue("seqObj"); 602 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 603 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 604 throw new InvalidParameterException( 605 "Failure generating replay sequence for rule " 606 + currentRuleName 607 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 608 } 609 for (WindowsMessage msg : seqVar) { 610 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 611 generatedMessageSeq, msgsGenerated, constMsgType, 612 seqIterator); 613 String targetString = msg.getParameter(termElement 614 .getAttributeValue("param")); 615 currentSeqMsg.setXmlWindowDescription(targetString); 616 } 617 msgsGenerated = true; 618 } else { // const value 619 throw new AssertionError("target must be a sequence variable!"); 620 /* 621 * If target would not be a variable, the message-elements could not 622 * yet be created and the whole sequence might be broken. If this is 623 * to be changed, createSequenceLParam and createSequenceWParam need 624 * to be addepted, too. 625 */ 626 } 627 return msgsGenerated; 628 } 629 630 /** 631 * <p> 632 * Creates the LPARAMs for replay sequences generated with genMsgSeq-nodes. 633 * </p> 634 * 635 * @param generatedMessageSeq 636 * list of the messages that is being generated 637 * @param msgsGenerated 638 * boolean stating if the list of messages is already generated 639 * or if the generation has to be handles by this method 640 * @param constMsgType 641 * a constant message type that is used for message generation, 642 * in case the list of message is generated by this method 643 * @param termElement 644 * {@link Element} representing the term-node describing the 645 * LPARAM 646 * @return true, if the list of message is generated after calling this 647 * method; false otherwise 648 * @throws NoSuchElementException 649 * thrown if the seqVar referred to in the termElement contains 650 * a different number of messages than is contained in 651 * messageSeq 652 */ 653 private boolean createSequenceLParam( 654 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 655 int constMsgType, Element termElement) 656 throws NoSuchElementException { 657 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 658 if (termElement.getName().equals("seqValue")) { 659 String obj = termElement.getAttributeValue("seqObj"); 660 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 661 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 662 throw new InvalidParameterException( 663 "Failure generating replay sequence for rule " 664 + currentRuleName 665 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 666 } 667 for (WindowsMessage msg : seqVar) { 668 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 669 generatedMessageSeq, msgsGenerated, constMsgType, 670 seqIterator); 671 String paramValueStr = msg.getParameter(termElement 672 .getAttributeValue("param")); 673 int paramValue = 0; 674 try { 675 paramValue = Integer.parseInt(paramValueStr); 676 currentSeqMsg.setLPARAM(paramValue); 677 } catch (NumberFormatException e) { 678 currentSeqMsg.setLPARAMasWindowDesc(paramValueStr); 679 } 680 } 681 if (seqIterator.hasNext()) { 682 // the first seq-var has a different number of elements than the 683 // current one 684 throw new NoSuchElementException(); 685 } 686 msgsGenerated = true; 687 } else { // const value 688 int paramValue = Integer.parseInt(getTermValue(null, termElement)); 689 while (seqIterator.hasNext()) { 690 seqIterator.next().setLPARAM(paramValue); 691 } 692 } 693 return msgsGenerated; 694 } 695 696 /** 697 * <p> 698 * Creates the WPARAMs for replay sequences generated with genMsgSeq-nodes. 699 * </p> 700 * 701 * @param generatedMessageSeq 702 * list of the messages that is being generated 703 * @param msgsGenerated 704 * boolean stating if the list of messages is already generated 705 * or if the generation has to be handles by this method 706 * @param constMsgType 707 * a constant message type that is used for message generation, 708 * in case the list of message is generated by this method 709 * @param termElement 710 * {@link Element} representing the term-node describing the 711 * WPARAM 712 * @return true, if the list of message is generated after calling this 713 * method; false otherwise 714 * @throws NoSuchElementException 715 * thrown if the seqVar referred to in the termElement contains 716 * a different number of messages than is contained in 717 * messageSeq 718 */ 719 private boolean createSequenceWParam( 720 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, 721 int constMsgType, Element termElement) 722 throws NoSuchElementException { 723 Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator(); 724 if (termElement.getName().equals("seqValue")) { 725 String obj = termElement.getAttributeValue("seqObj"); 726 List<WindowsMessage> seqVar = getStoredSeqVariable(obj); 727 if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) { 728 throw new InvalidParameterException( 729 "Failure generating replay sequence for rule " 730 + currentRuleName 731 + ": One or more of the sequence variables used to generate a sequence have different lenghts."); 732 } 733 for (WindowsMessage msg : seqVar) { 734 WindowsMessage currentSeqMsg = getCurrentSeqMsg( 735 generatedMessageSeq, msgsGenerated, constMsgType, 736 seqIterator); 737 String paramValueStr = msg.getParameter(termElement 738 .getAttributeValue("param")); 739 int paramValue = 0; 740 try { 741 paramValue = Integer.parseInt(paramValueStr); 742 currentSeqMsg.setWPARAM(paramValue); 743 } catch (NumberFormatException e) { 744 currentSeqMsg.setWPARAMasWindowDesc(paramValueStr); 745 } 746 } 747 if (seqIterator.hasNext()) { 748 // the first seq-var has a different number of elements than the 749 // current one 750 throw new NoSuchElementException(); 751 } 752 msgsGenerated = true; 753 } else { // const value 754 int paramValue = Integer.parseInt(getTermValue(null, termElement)); 755 while (seqIterator.hasNext()) { 756 seqIterator.next().setWPARAM(paramValue); 757 } 758 } 759 return msgsGenerated; 760 } 761 762 /** 763 * <p> 764 * If a message sequence is already generated, i.e., msgsGenerated is true, 765 * the seqIterator is used to iterate through these messages and return the 766 * current one. If the message sequence is not yet generated, i.e., 767 * msgsGenerated is false, the message sequence is generated on the fly 768 * during each call of this message and the newly generated messages are 769 * returned. 770 * </p> 771 * 772 * @param generatedMessageSeq 773 * message sequence 774 * @param msgsGenerated 775 * indicates if generatedMessageSeq is already generated or has 776 * to be generated on the fly by this method 777 * @param constMsgType 778 * type of the message to be used for message generation 779 * @param seqIterator 780 * iterates through an already generated message sequence; must 781 * not be {@code null}, if msgsGenerated is true 782 * @return current message 783 */ 481 784 private WindowsMessage getCurrentSeqMsg( 482 785 List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated, … … 492 795 } 493 796 797 // //////////////////////////// 798 // General helper functions // 799 // //////////////////////////// 800 801 /** 802 * <p> 803 * Retrieves a message from the storage for, e.g., comparison or replay. 804 * "this" is used to refer to the current message. 805 * </p> 806 * 807 * @param currentMessage 808 * current message during the parsing; passed to handle "this" 809 * @param obj 810 * object identifier in the storage 811 * @return message retrieved from the storage 812 * @throws InvalidParameterException 813 * thrown in case of invalid uses of "this" or if no message 814 * with the identifier obj is found in the storage 815 */ 494 816 private WindowsMessage getStoredMessageVariable( 495 817 WindowsMessage currentMessage, String obj) … … 518 840 } 519 841 842 /** 843 * <p> 844 * Retrieves a stored message sequence from the storage. 845 * </p> 846 * 847 * @param obj 848 * object identifier in the storage 849 * @return message sequence retrieved from the storage 850 * @throws InvalidParameterException 851 * thrown if no message sequences with the identifier obj is 852 * found in the storage 853 */ 520 854 @SuppressWarnings("unchecked") 521 855 private List<WindowsMessage> getStoredSeqVariable(String obj) … … 533 867 } 534 868 869 /** 870 * <p> 871 * Handles term-nodes and returns the value of the described term. 872 * </p> 873 * 874 * @param currentMessage 875 * current message during the parsing; required to resolve 876 * references to "this" in a term 877 * @param termElement 878 * {@link Element} representing the term node 879 * @return value of the term or {@code null} of the term node could not be 880 * evaluated 881 */ 535 882 private String getTermValue(WindowsMessage currentMessage, 536 883 Element termElement) { … … 560 907 String target = varMessage.getXmlWindowDescription(); 561 908 int index = target.lastIndexOf("<"); 562 if ( index==0) {909 if (index == 0) { 563 910 Console.println("Trying to adress parent of top-level window! Replay probably invalid!"); 564 911 } … … 583 930 } 584 931 585 private List<String> getTermValueSeq(WindowsMessage currentMessage, 586 Element termElement) { 932 /** 933 * <p> 934 * Handles term-nodes contained by equalSeq nodes. 935 * </p> 936 * 937 * @param termElement 938 * {@link Element} representing the term-node 939 * @return list of values of the term 940 */ 941 private List<String> getTermValueSeq(Element termElement) { 587 942 List<String> values = new LinkedList<String>(); 588 943 if (termElement.getName().equals("seqValue")) { … … 600 955 } 601 956 602 @SuppressWarnings("unchecked") 603 private void handleStorage(Element messageElement, 604 WindowsMessage currentMessage) { 605 for (Element childElement : (List<Element>) messageElement.getChildren( 606 "store", rulesNamespace)) { 607 String identifier = childElement.getAttributeValue("var"); 608 messageStorage.put(identifier, currentMessage); 609 resolveHwnd(currentMessage, childElement); 610 } 611 for (Element childElement : (List<Element>) messageElement.getChildren( 612 "storeSeq", rulesNamespace)) { 613 String identifier = childElement.getAttributeValue("varSeq"); 614 Object tmp = messageStorage.get(identifier); 615 List<WindowsMessage> storedSequence; 616 if (tmp == null || tmp instanceof WindowsMessage) { 617 storedSequence = new LinkedList<WindowsMessage>(); 618 storedSequence.add(currentMessage); 619 messageStorage.put(identifier, storedSequence); 620 } else if (tmp instanceof List<?>) { 621 storedSequence = (List<WindowsMessage>) tmp; 622 storedSequence.add(currentMessage); 623 messageStorage.put(identifier, storedSequence); 624 } 625 resolveHwnd(currentMessage, childElement); 626 } 627 } 628 629 private boolean matchMultipleMessages(Element messageElement, 630 Element nextMessageElement) { 631 boolean isMatch = false; 632 boolean isCurrentMatch = false; 633 boolean nextMatchFound = false; 634 WindowsMessage currentMessage = null; 635 WindowsMessage nextMessage = null; 636 637 int type = Integer.parseInt(messageElement.getAttributeValue("type")); 638 639 int nextType = -1; 640 if (nextMessageElement != null) { 641 nextType = Integer.parseInt(nextMessageElement 642 .getAttributeValue("type")); 643 } 644 645 while (!nextMatchFound && sequenceIterator.hasNext()) { 646 currentMessage = sequenceIterator.next(); 647 if (type == currentMessage.getType()) { 648 isCurrentMatch = evalEqualRestrictions(currentMessage, 649 messageElement); 650 isMatch = isMatch || isCurrentMatch; 651 652 if (isCurrentMatch) { 653 handleStorage(messageElement, currentMessage); 654 currentToken.setTarget(currentMessage 655 .getXmlWindowDescription()); 656 currentToken 657 .setTargetShort(currentMessage.getParentNames()); 658 } 659 } 660 if (nextMessageElement != null && isMatch) { 661 // peek next message to check if the sequence ends and the next 662 // match is found 663 if (!sequenceIterator.hasNext()) { 664 return false; // sequence is over, but not all messages are 665 // found 666 } 667 nextMessage = sequenceIterator.next(); 668 sequenceIterator.previous(); 669 670 if (nextType == nextMessage.getType()) { 671 nextMatchFound = evalEqualRestrictions(nextMessage, 672 nextMessageElement); 673 } 674 675 } 676 } 677 678 return isMatch; 679 } 680 681 private boolean matchSingleMessage(Element messageElement) { 682 boolean isMatch = false; 683 WindowsMessage currentMessage = null; 684 685 int type = Integer.parseInt(messageElement.getAttributeValue("type")); 686 687 while (!isMatch && sequenceIterator.hasNext()) { 688 // traverses the messages from the current position forward till a 689 // message with the correct type is found 690 currentMessage = sequenceIterator.next(); 691 if (type == currentMessage.getType()) { 692 // message with the correct type found 693 // eval child nodes for further matching/storing 694 isMatch = evalEqualRestrictions(currentMessage, messageElement); 695 696 // in case the message is a match, eval storage children 697 if (isMatch) { 698 handleStorage(messageElement, currentMessage); 699 currentToken.setTarget(currentMessage 700 .getXmlWindowDescription()); 701 currentToken 702 .setTargetShort(currentMessage.getParentNames()); 703 } 704 } 705 } 706 707 return isMatch; 708 } 709 710 @SuppressWarnings("unchecked") 711 private void resolveHwnd(WindowsMessage currentMessage, Element childElement) { 712 List<Element> resolveElements = childElement.getChildren("resolveHwnd", 713 rulesNamespace); 714 for (Element resolveElement : resolveElements) { 715 String param = resolveElement.getAttributeValue("param"); 716 String storeParam = resolveElement.getAttributeValue("storeParam"); 717 int paramHwnd = Integer 718 .parseInt(currentMessage.getParameter(param)); 719 WindowTreeNode node = WindowTree.getInstance().find(paramHwnd); 720 if (node != null) { 721 currentMessage.addParameter(storeParam, 722 node.xmlRepresentation()); 723 } 724 } 725 } 726 957 /** 958 * <p> 959 * Handles LOWORD and HIWORD child nodes of LPARAM and WPARAM nodes. The 960 * returned value is the LPARAM/WPARAM value based on the LOWORD and HIWORD. 961 * </p> 962 * 963 * @param param 964 * {@link Element} representing the LPARAM/WPARAM node 965 * @return value of the LPARAM/WPARAM 966 */ 727 967 private long loHiWord(Element param) { 728 968 Element loword = param.getChild("LOWORD", rulesNamespace); 729 969 Element hiword = param.getChild("HIWORD", rulesNamespace); 730 String lowordStr = getTermValue(null, (Element) loword.getChildren().get(0)); 731 String hiwordStr = getTermValue(null, (Element) hiword.getChildren().get(0)); 732 return MAKEPARAM(Short.parseShort(lowordStr), Short.parseShort(hiwordStr)); 733 } 734 970 String lowordStr = getTermValue(null, (Element) loword.getChildren() 971 .get(0)); 972 String hiwordStr = getTermValue(null, (Element) hiword.getChildren() 973 .get(0)); 974 return MAKEPARAM(Short.parseShort(lowordStr), 975 Short.parseShort(hiwordStr)); 976 } 977 978 /** 979 * <p> 980 * Takes to short integers and combines them into the high and low order 981 * bits of an integer. 982 * </p> 983 * 984 * @param loword 985 * low word 986 * @param hiword 987 * high word 988 * @return combined integer 989 */ 735 990 private static int MAKEPARAM(short loword, short hiword) { 736 return loword | ((int) hiword) << Short.SIZE;991 return loword | ((int) hiword) << Short.SIZE; 737 992 } 738 993 -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/HandlerCreate.java
r156 r171 3 3 import de.ugoe.cs.eventbench.windows.data.WindowTree; 4 4 5 /** 6 * <p> 7 * Message handler for {@code WM_CREATE} messages. The handler maintains the 8 * {@link WindowTree}. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 5 14 public class HandlerCreate extends MessageHandler { 6 15 16 /** 17 * <p> 18 * Constructor. Creates a new HandlerCreate. 19 * </p> 20 */ 7 21 public HandlerCreate() { 8 22 super(); 9 23 } 10 24 25 /** 26 * <p> 27 * Name of the created window. 28 * </p> 29 */ 11 30 private String windowName; 31 32 /** 33 * <p> 34 * HWND of the created window. 35 * </p> 36 */ 12 37 private int hwnd; 38 39 /** 40 * <p> 41 * HWND of the created window's parent. 42 * </p> 43 */ 13 44 private int parentHwnd; 45 46 /** 47 * <p> 48 * Resource Id of the created window. 49 * </p> 50 */ 14 51 private int resourceId; 52 53 /** 54 * <p> 55 * Window class of the created window. 56 * </p> 57 */ 15 58 private String className; 59 60 /** 61 * <p> 62 * Modality of the created window. 63 * </p> 64 */ 16 65 private boolean isModal; 17 66 67 /* 68 * (non-Javadoc) 69 * 70 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onEndElement() 71 */ 18 72 @Override 19 73 public void onEndElement() { 20 if( hwnd!=0 ) { 21 WindowTree.getInstance().add(parentHwnd, hwnd, windowName, resourceId, className, isModal); 74 if (hwnd != 0) { 75 WindowTree.getInstance().add(parentHwnd, hwnd, windowName, 76 resourceId, className, isModal); 22 77 } 23 78 } 24 79 80 /* 81 * (non-Javadoc) 82 * 83 * @see 84 * de.ugoe.cs.eventbench.windows.MessageHandler#onParameter(java.lang.String 85 * , java.lang.String) 86 */ 25 87 @Override 26 88 public void onParameter(String name, String value) { 27 if ( name.equals("window.hwnd")) {89 if (name.equals("window.hwnd")) { 28 90 hwnd = Integer.parseInt(value); 29 } 30 else if( name.equals("window.name") ) { 91 } else if (name.equals("window.name")) { 31 92 windowName = value; 32 } 33 else if( name.equals("window.parent.hwnd") ) { 93 } else if (name.equals("window.parent.hwnd")) { 34 94 parentHwnd = Integer.parseInt(value); 35 } 36 else if( name.equals("window.resourceId") ) { 95 } else if (name.equals("window.resourceId")) { 37 96 resourceId = Integer.parseInt(value); 38 } 39 else if( name.equals("window.class") ) { 40 if( value.startsWith("Afx:") ) { 97 } else if (name.equals("window.class")) { 98 if (value.startsWith("Afx:")) { 41 99 className = "Afx:"; 42 100 } else { 43 101 className = value; 44 102 } 45 } 46 else if( name.equals("window.ismodal") ) { 47 if( value.equals("true") || value.equals("1") ) { 103 } else if (name.equals("window.ismodal")) { 104 if (value.equals("true") || value.equals("1")) { 48 105 isModal = true; 49 106 } … … 51 108 } 52 109 110 /* 111 * (non-Javadoc) 112 * 113 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onStartElement() 114 */ 53 115 @Override 54 116 public void onStartElement() { -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/HandlerDestroy.java
r75 r171 3 3 import de.ugoe.cs.eventbench.windows.data.WindowTree; 4 4 5 /** 6 * <p> 7 * Handler for {@code WM_DESTROY} message. The handler maintains the 8 * {@link WindowTree}. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 5 14 public class HandlerDestroy extends MessageHandler { 6 15 16 /** 17 * <p> 18 * Constructor. Creates a new HandlerDestroy. 19 * </p> 20 */ 7 21 public HandlerDestroy() { 8 22 super(); 9 23 } 10 24 25 /** 26 * <p> 27 * HWND of the window that is destroyed. 28 * </p> 29 */ 11 30 private int hwnd; 12 31 32 /* 33 * (non-Javadoc) 34 * 35 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onEndElement() 36 */ 13 37 @Override 14 38 public void onEndElement() { 15 if ( hwnd!=0) {39 if (hwnd != 0) { 16 40 WindowTree.getInstance().remove(hwnd); 17 41 } 18 42 } 19 43 44 /* 45 * (non-Javadoc) 46 * 47 * @see 48 * de.ugoe.cs.eventbench.windows.MessageHandler#onParameter(java.lang.String 49 * , java.lang.String) 50 */ 20 51 @Override 21 52 public void onParameter(String name, String value) { 22 if ( name.equals("window.hwnd")) {53 if (name.equals("window.hwnd")) { 23 54 hwnd = Integer.parseInt(value); 24 55 } 25 56 } 26 57 58 /* 59 * (non-Javadoc) 60 * 61 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onStartElement() 62 */ 27 63 @Override 28 64 public void onStartElement() { -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/HandlerSetText.java
r75 r171 4 4 import de.ugoe.cs.eventbench.windows.data.WindowTreeNode; 5 5 6 /** 7 * <p> 8 * Handles {@code WM_SETTEXT} messages. Handler maintains the {@link WindowTree}. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 6 14 public class HandlerSetText extends MessageHandler { 7 15 16 /** 17 * <p> 18 * Constructor. Creates a new HanderSetText. 19 * </p> 20 */ 8 21 public HandlerSetText() { 9 22 super(); 10 23 } 11 24 25 /** 26 * <p> 27 * New name of the window. 28 * </p> 29 */ 12 30 private String windowName; 31 32 /** 33 * <p> 34 * HWND of the window. 35 * </p> 36 */ 13 37 private int hwnd; 14 38 39 /* 40 * (non-Javadoc) 41 * 42 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onEndElement() 43 */ 15 44 @Override 16 45 public void onEndElement() { … … 21 50 } 22 51 52 /* 53 * (non-Javadoc) 54 * 55 * @see 56 * de.ugoe.cs.eventbench.windows.MessageHandler#onParameter(java.lang.String 57 * , java.lang.String) 58 */ 23 59 @Override 24 60 public void onParameter(String name, String value) { … … 30 66 } 31 67 68 /* 69 * (non-Javadoc) 70 * 71 * @see de.ugoe.cs.eventbench.windows.MessageHandler#onStartElement() 72 */ 32 73 @Override 33 74 public void onStartElement() { -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/LogParser.java
r77 r171 28 28 import de.ugoe.cs.util.console.Console; 29 29 30 /** 31 * <p> 32 * This class provides functionality to parse XML log files generated by the 33 * MFCUsageMonitor of EventBench. The result of parsing a file is a collection 34 * of event sequences. It uses the {@link SequenceSplitter} and the 35 * {@link EventGenerator} as well as custom defined {@link MessageHandler} for 36 * the parsing. 37 * </p> 38 * 39 * @author Steffen Herbold 40 * @version 1.0 41 */ 30 42 public class LogParser extends DefaultHandler { 31 43 44 /** 45 * <p> 46 * If a custom message handler is used, this field contains its handle. 47 * Otherwise this field is {@code null}. 48 * </p> 49 */ 32 50 private MessageHandler currentHandler; 33 51 52 /** 53 * <p> 54 * Handle to the message that is currently parsed. 55 * </p> 56 */ 34 57 private WindowsMessage currentMessage; 35 58 59 /** 60 * <p> 61 * {@link SequenceSplitter} instance used by the {@link LogParser}. 62 * </p> 63 */ 36 64 private SequenceSplitter sequenceSplitter; 37 65 66 /** 67 * <p> 68 * Collection of event sequences that is contained in the log file, which is 69 * parsed. 70 * </p> 71 */ 38 72 private List<List<WindowsEvent>> sequences; 39 73 74 /** 75 * <p> 76 * Debugging variable that allows the analysis which message type occurs how 77 * often in the log file. Can be used to enhance the message filter. 78 * </p> 79 */ 40 80 private SortedMap<Integer, Integer> typeCounter; 41 81 82 /** 83 * <p> 84 * Debugging variable that enables the counting of the occurrences of each 85 * message. Used in combination with {@link #typeCounter}. 86 * </p> 87 */ 42 88 private boolean countMessageOccurences; 43 89 90 /** 91 * <p> 92 * Constructor. Creates a new LogParser that does not count message 93 * occurrences. 94 * </p> 95 */ 44 96 public LogParser() { 45 97 this(false); 46 98 } 47 99 100 /** 101 * <p> 102 * Constructor. Creates a new LogParser. 103 * </p> 104 * 105 * @param countMessageOccurences 106 * if true, the occurrences of each message type in the log is 107 * counted. 108 */ 48 109 public LogParser(boolean countMessageOccurences) { 49 110 sequenceSplitter = new SequenceSplitter(); … … 51 112 currentHandler = null; 52 113 this.countMessageOccurences = countMessageOccurences; 53 if (countMessageOccurences) {114 if (countMessageOccurences) { 54 115 typeCounter = new TreeMap<Integer, Integer>(); 55 116 } 56 57 } 58 117 118 } 119 120 /** 121 * <p> 122 * Returns the collection of event sequences that is obtained from parsing 123 * log files. 124 * </p> 125 * 126 * @return collection of event sequences 127 */ 59 128 public List<List<WindowsEvent>> getSequences() { 60 129 return sequences; 61 130 } 62 131 132 /* 133 * (non-Javadoc) 134 * 135 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, 136 * java.lang.String, java.lang.String, org.xml.sax.Attributes) 137 */ 63 138 @Override 64 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { 65 if( qName.equals("session") ) { 139 public void startElement(String uri, String localName, String qName, 140 Attributes atts) throws SAXException { 141 if (qName.equals("session")) { 66 142 Console.traceln("start of session"); 67 143 sequenceSplitter = new SequenceSplitter(); 68 } 69 else if( qName.equals("msg") ) { 144 } else if (qName.equals("msg")) { 70 145 String msgType = atts.getValue("type"); 71 146 int msgInt = -1; 72 147 try { 73 148 msgInt = Integer.parseInt(msgType); 74 75 if ( countMessageOccurences) {149 150 if (countMessageOccurences) { 76 151 Integer currentCount = typeCounter.get(msgInt); 77 if ( currentCount==null) {152 if (currentCount == null) { 78 153 typeCounter.put(msgInt, 1); 79 154 } else { 80 typeCounter.put(msgInt, currentCount +1);155 typeCounter.put(msgInt, currentCount + 1); 81 156 } 82 157 } 83 84 if ( msgInt==MessageDefs.WM_CREATE) {158 159 if (msgInt == MessageDefs.WM_CREATE) { 85 160 currentHandler = new HandlerCreate(); 86 161 currentHandler.onStartElement(); 87 } 88 else if( msgInt==MessageDefs.WM_DESTROY ) { 162 } else if (msgInt == MessageDefs.WM_DESTROY) { 89 163 currentHandler = new HandlerDestroy(); 90 164 currentHandler.onStartElement(); 91 } 92 else if( msgInt==MessageDefs.WM_SETTEXT ) { 165 } else if (msgInt == MessageDefs.WM_SETTEXT) { 93 166 currentHandler = new HandlerSetText(); 94 167 currentHandler.onStartElement(); … … 96 169 currentMessage = new WindowsMessage(msgInt); 97 170 } 98 } catch (NumberFormatException e) {171 } catch (NumberFormatException e) { 99 172 Console.printerrln("Invalid message type: type not a number"); 100 173 e.printStackTrace(); 101 174 } 102 } 103 else if( qName.equals("param")) {104 if( currentHandler!=null ) {105 currentHandler.onParameter(atts.getValue("name"),atts.getValue("value"));175 } else if (qName.equals("param")) { 176 if (currentHandler != null) { 177 currentHandler.onParameter(atts.getValue("name"), 178 atts.getValue("value")); 106 179 } else { 107 currentMessage.addParameter(atts.getValue("name"), atts.getValue("value")); 108 } 109 } 110 } 111 180 currentMessage.addParameter(atts.getValue("name"), 181 atts.getValue("value")); 182 } 183 } 184 } 185 186 /* 187 * (non-Javadoc) 188 * 189 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, 190 * java.lang.String, java.lang.String) 191 */ 112 192 @Override 113 public void endElement(String uri, String localName, String qName) throws SAXException { 114 if( qName.equals("msg") ) { 115 if( currentHandler!=null ) { 193 public void endElement(String uri, String localName, String qName) 194 throws SAXException { 195 if (qName.equals("msg")) { 196 if (currentHandler != null) { 116 197 currentHandler.onEndElement(); 117 198 currentHandler = null; … … 121 202 sequenceSplitter.addMessage(currentMessage); 122 203 } catch (InvalidParameterException e) { 123 Console.traceln(e.getMessage() + " WindowsMessage " + currentMessage + " ignored.");124 }125 }126 }127 else if(qName.equals("session")) {204 Console.traceln(e.getMessage() + " WindowsMessage " 205 + currentMessage + " ignored."); 206 } 207 } 208 } else if (qName.equals("session")) { 128 209 sequenceSplitter.endSession(); 129 210 sequences.add(sequenceSplitter.getSequence()); … … 131 212 } 132 213 } 133 214 215 /** 216 * <p> 217 * Parses a given log file and adds its contents to the collection of event 218 * sequences. 219 * </p> 220 * 221 * @param filename 222 * name and path of the log file 223 */ 134 224 public void parseFile(String filename) { 135 if ( filename==null) {225 if (filename == null) { 136 226 throw new InvalidParameterException("filename must not be null"); 137 227 } 138 228 139 229 SAXParserFactory spf = SAXParserFactory.newInstance(); 140 230 spf.setValidating(true); 141 231 142 232 SAXParser saxParser = null; 143 233 InputSource inputSource = null; 144 234 try { 145 235 saxParser = spf.newSAXParser(); 146 inputSource = new InputSource(new InputStreamReader(new FileInputStream(filename), "UTF-16")); 236 inputSource = new InputSource(new InputStreamReader( 237 new FileInputStream(filename), "UTF-16")); 147 238 } catch (UnsupportedEncodingException e) { 148 239 e.printStackTrace(); … … 154 245 e.printStackTrace(); 155 246 } 156 if( inputSource!=null ) { 157 inputSource.setSystemId("file://" + new File(filename).getAbsolutePath()); 158 try { 159 if( saxParser==null) { 160 throw new RuntimeException("SAXParser creation failed"); 161 } 247 if (inputSource != null) { 248 inputSource.setSystemId("file://" 249 + new File(filename).getAbsolutePath()); 250 try { 251 if (saxParser == null) { 252 throw new RuntimeException("SAXParser creation failed"); 253 } 162 254 saxParser.parse(inputSource, this); 163 } catch (SAXParseException e) { 164 Console.printerrln("Failure parsing file in line " + e.getLineNumber() + ", column " + e.getColumnNumber() +"."); 165 e.printStackTrace(); 255 } catch (SAXParseException e) { 256 Console.printerrln("Failure parsing file in line " 257 + e.getLineNumber() + ", column " + e.getColumnNumber() 258 + "."); 259 e.printStackTrace(); 166 260 } catch (SAXException e) { 167 261 e.printStackTrace(); … … 170 264 } 171 265 } 172 if ( countMessageOccurences) {266 if (countMessageOccurences) { 173 267 Console.println("Message statistics:"); 174 Console.println(typeCounter.toString().replace(" ", StringTools.ENDLINE).replaceAll("[\\{\\}]","")); 268 Console.println(typeCounter.toString() 269 .replace(" ", StringTools.ENDLINE) 270 .replaceAll("[\\{\\}]", "")); 175 271 } 176 272 } -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/LogPreprocessor.java
r75 r171 13 13 import de.ugoe.cs.util.console.Console; 14 14 15 /** 16 * <p> 17 * Pre-processes log files generated by the EventBench's MFCUsageMonitor. It 18 * decodes Base64 encoding into UTF-16. It removes all lines of the log file, 19 * that do not start with the prefix "UL:", end everything before the prefix and 20 * the prefix itself. 21 * </p> 22 * 23 * @author Steffen Herbold 24 * @version 1.0 25 */ 15 26 public class LogPreprocessor { 16 27 28 /** 29 * <p> 30 * Internal flag that monitors whether there is an open session-node in the 31 * XML file to ensure that there is a closing session-node for each opening 32 * session node and, thereby, ensure that the XML file is well formed. 33 * </p> 34 */ 17 35 private boolean sessionOpen = false; 36 37 /** 38 * <p> 39 * Internal flag that monitors whether a message node is longer than one 40 * line, as the prefix handling is different in this case. 41 * </p> 42 */ 18 43 private boolean msgIncomplete = false; 19 44 45 /** 46 * <p> 47 * Flag that marks whether the log file is Base64 encoded. 48 * </p> 49 */ 20 50 private boolean base64; 21 51 52 /** 53 * <p> 54 * Constructor. Creates a new LogPreprocessor that does not decode Base64. 55 * </p> 56 */ 22 57 public LogPreprocessor() { 23 58 this(false); 24 59 } 25 60 61 /** 62 * <p> 63 * Constructor. Creates a new LogPreprocessor. 64 * </p> 65 * 66 * @param base64 67 * if true, Base64 will be decoded. 68 */ 26 69 public LogPreprocessor(boolean base64) { 27 70 this.base64 = base64; 28 71 } 29 30 public void convertToXml(String source, String target) throws IOException, FileNotFoundException { 31 OutputStreamWriter targetFile = new OutputStreamWriter(new FileOutputStream(target), "UTF-16"); 32 targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + StringTools.ENDLINE); 72 73 /** 74 * <p> 75 * Pre-processes a single log file. 76 * </p> 77 * 78 * @param source 79 * name and path of the source file 80 * @param target 81 * name and path of the target file 82 * @throws IOException 83 * thrown if there is a problem with reading from or writing to 84 * the source, respectively target file 85 * @throws FileNotFoundException 86 * thrown if the source file is not found 87 */ 88 public void convertToXml(String source, String target) throws IOException, 89 FileNotFoundException { 90 OutputStreamWriter targetFile = new OutputStreamWriter( 91 new FileOutputStream(target), "UTF-16"); 92 targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" 93 + StringTools.ENDLINE); 33 94 targetFile.write("<log>" + StringTools.ENDLINE); 34 95 processFile(source, targetFile); 35 if ( sessionOpen) {96 if (sessionOpen) { 36 97 targetFile.write(" </session>" + StringTools.ENDLINE); 37 98 } … … 39 100 targetFile.close(); 40 101 } 41 42 43 public void convertDirToXml(String path, String target) throws IOException, FileNotFoundException { 44 OutputStreamWriter targetFile = new OutputStreamWriter(new FileOutputStream(target), "UTF-16"); 45 targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + StringTools.ENDLINE); 102 103 /** 104 * <p> 105 * Pre-processes all files in a given source folder. 106 * </p> 107 * 108 * @param source 109 * path of the source folder 110 * @param target 111 * name and path of the target file 112 * @throws IOException 113 * thrown if there is a problem with reading from or writing to 114 * the source, respectively target file 115 * @throws FileNotFoundException 116 * thrown if the source file is not found 117 */ 118 public void convertDirToXml(String path, String target) throws IOException, 119 FileNotFoundException { 120 OutputStreamWriter targetFile = new OutputStreamWriter( 121 new FileOutputStream(target), "UTF-16"); 122 targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" 123 + StringTools.ENDLINE); 46 124 targetFile.write("<log>" + StringTools.ENDLINE); 47 125 File folder = new File(path); 48 if ( !folder.isDirectory()) {126 if (!folder.isDirectory()) { 49 127 throw new IOException(path + " is not a directory"); 50 128 } 51 129 String absolutPath = folder.getAbsolutePath(); 52 for ( String filename : folder.list()) {130 for (String filename : folder.list()) { 53 131 String source = absolutPath + "/" + filename; 54 132 Console.traceln("Processing file: " + source); 55 133 processFile(source, targetFile); 56 134 } 57 58 if ( sessionOpen) {135 136 if (sessionOpen) { 59 137 targetFile.write(" </session>" + StringTools.ENDLINE); 60 138 } … … 63 141 } 64 142 143 /** 144 * <p> 145 * Internal function that pre-processes a log file. 146 * </p> 147 * 148 * @param source 149 * name and path of the source file 150 * @param target 151 * name and path of the target file 152 * @throws IOException 153 * thrown if there is a problem with reading from or writing to 154 * the source, respectively target file 155 * @throws FileNotFoundException 156 * thrown if the source file is not found 157 */ 65 158 private void processFile(String source, OutputStreamWriter targetFile) 66 159 throws FileNotFoundException, IOException { … … 68 161 String incompleteLine = ""; 69 162 // Open source and read line by line 70 for ( String currentLine : lines) {71 if (currentLine.contains("UL: <session>")) {72 if (sessionOpen) {163 for (String currentLine : lines) { 164 if (currentLine.contains("UL: <session>")) { 165 if (sessionOpen) { 73 166 targetFile.write(" </session>" + StringTools.ENDLINE); 74 167 targetFile.write(" <session>" + StringTools.ENDLINE); … … 77 170 sessionOpen = true; 78 171 } 79 } else if (currentLine.contains("UL: </session>")) {80 if (sessionOpen) {172 } else if (currentLine.contains("UL: </session>")) { 173 if (sessionOpen) { 81 174 targetFile.write(" </session>" + StringTools.ENDLINE); 82 175 sessionOpen = false; 83 176 } 84 } else if (msgIncomplete || currentLine.contains("UL: ")) {85 177 } else if (msgIncomplete || currentLine.contains("UL: ")) { 178 86 179 String currentContent; 87 180 String actualLine; 88 if ( msgIncomplete) {181 if (msgIncomplete) { 89 182 actualLine = currentLine; 90 183 } else { … … 92 185 actualLine = splitResult[1]; 93 186 } 94 if ( base64) {187 if (base64) { 95 188 Base64 decoder = new Base64(); 96 189 byte[] decoded = decoder.decode(actualLine); 97 190 currentContent = new String(decoded, "UTF-16LE"); 98 currentContent = currentContent.substring(0, currentContent.length()-1); 191 currentContent = currentContent.substring(0, 192 currentContent.length() - 1); 99 193 } else { 100 194 currentContent = actualLine; 101 195 } 102 if ( msgIncomplete) {196 if (msgIncomplete) { 103 197 incompleteLine += currentContent; 104 if ( incompleteLine.contains("</msg>")) {198 if (incompleteLine.contains("</msg>")) { 105 199 msgIncomplete = false; 106 200 targetFile.write(incompleteLine + StringTools.ENDLINE); … … 108 202 } 109 203 } else { 110 if( currentContent.contains("<msg") && sessionOpen ) { 111 if( currentContent.contains("</msg>") ) { 112 targetFile.write(" " + currentContent + StringTools.ENDLINE); 204 if (currentContent.contains("<msg") && sessionOpen) { 205 if (currentContent.contains("</msg>")) { 206 targetFile.write(" " + currentContent 207 + StringTools.ENDLINE); 113 208 } else { 114 209 msgIncomplete = true; -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/MFCReplayDecorator.java
r98 r171 4 4 import de.ugoe.cs.util.StringTools; 5 5 6 /** 7 * <p> 8 * {@link IReplayDecorator} for replay generated for EventBench's MFCReplay tool. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 6 14 public class MFCReplayDecorator implements IReplayDecorator { 7 15 8 16 /** 17 * <p> 9 18 * Id for object serialization. 19 * </p> 10 20 */ 11 21 private static final long serialVersionUID = 1L; 12 22 23 /** 24 * <p> 25 * The instance of the {@link MFCReplayDecorator} (implemented as 26 * singleton). 27 * </p> 28 */ 13 29 transient private static MFCReplayDecorator theInstance; 14 15 private MFCReplayDecorator() {}; 16 30 31 /** 32 * <p> 33 * Constructor. Private to guarantee that only one instance of the replay 34 * generator exists. 35 * </p> 36 */ 37 private MFCReplayDecorator() { 38 }; 39 40 /** 41 * <p> 42 * Returns the instance of the MFCReplayDecorator. 43 * </p> 44 * 45 * @return instance of the MFCReplayDecorator. 46 */ 17 47 public static MFCReplayDecorator getInstance() { 18 if ( theInstance==null) {48 if (theInstance == null) { 19 49 theInstance = new MFCReplayDecorator(); 20 50 } 21 51 return theInstance; 22 52 } 23 53 54 /* 55 * (non-Javadoc) 56 * 57 * @see de.ugoe.cs.eventbench.IReplayDecorator#getHeader() 58 */ 24 59 @Override 25 60 public String getHeader() { 26 return "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + StringTools.ENDLINE +27 28 61 return "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" 62 + StringTools.ENDLINE + "<log>" + StringTools.ENDLINE; 63 29 64 } 30 65 66 /* 67 * (non-Javadoc) 68 * 69 * @see de.ugoe.cs.eventbench.IReplayDecorator#getFooter() 70 */ 31 71 @Override 32 72 public String getFooter() { … … 34 74 } 35 75 76 /* 77 * (non-Javadoc) 78 * 79 * @see de.ugoe.cs.eventbench.IReplayDecorator#getSessionHeader(int) 80 */ 36 81 @Override 37 82 public String getSessionHeader(int sessionId) { 38 return " <session id=\"" +sessionId+"\">" + StringTools.ENDLINE;83 return " <session id=\"" + sessionId + "\">" + StringTools.ENDLINE; 39 84 } 40 85 86 /* 87 * (non-Javadoc) 88 * 89 * @see de.ugoe.cs.eventbench.IReplayDecorator#getSessionFooter(int) 90 */ 41 91 @Override 42 92 public String getSessionFooter(int sessionId) { 43 93 return " </session>" + StringTools.ENDLINE; 44 94 } 45 46 95 47 96 } -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/MessageDefs.java
r76 r171 1 1 package de.ugoe.cs.eventbench.windows; 2 2 3 /** 4 * <p> 5 * Contains definitions of windows message codes, such that they can be used 6 * internally by their name and not their integer value, to improve the 7 * readability of the source code. 8 * </p> 9 * 10 * @author Steffen Herbold 11 * @version 1.0 12 */ 3 13 public interface MessageDefs { 4 14 5 15 public static final int WM_NULL = 0; 6 16 public static final int WM_CREATE = 1; -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/MessageHandler.java
r75 r171 1 1 package de.ugoe.cs.eventbench.windows; 2 2 3 /** 4 * <p> 5 * Base class to define custom message handlers, for messages that shall be 6 * handled differently during the parsing of usage logs. It provides dummy 7 * implementations for all required methods, such that implementations can only 8 * overwrite the parts they actually require and ignore the rest. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 14 public class MessageHandler { 3 15 4 public class MessageHandler { 5 6 protected MessageHandler() {} 7 8 public void onStartElement() {} 9 public void onParameter(String name, String value) {} 10 public void onEndElement() {} 16 /** 17 * <p> 18 * Constructor. Protected to prohibit initialization of the base class 19 * itself. 20 * </p> 21 */ 22 protected MessageHandler() { 23 } 24 25 /** 26 * <p> 27 * Called in the startElement() method of the {@link LogParser} when a 28 * msg-node begins. 29 * </p> 30 */ 31 public void onStartElement() { 32 } 33 34 /** 35 * <p> 36 * Called by the {@link LogParser} to handle param-nodes. 37 * </p> 38 * 39 * @param name 40 * name (type) of the parameter 41 * @param value 42 * value of the parameter 43 */ 44 public void onParameter(String name, String value) { 45 } 46 47 /** 48 * <p> 49 * Called in the endElement() method of {@link LogParser} when a msg-node 50 * ends. 51 * </p> 52 */ 53 public void onEndElement() { 54 } 11 55 } -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/SequenceSplitter.java
r77 r171 4 4 import java.util.List; 5 5 6 import de.ugoe.cs.eventbench.data.Event; 6 7 import de.ugoe.cs.eventbench.windows.data.WindowsMessage; 7 8 import de.ugoe.cs.util.console.Console; 8 9 10 /** 11 * <p> 12 * Responsible to split sequences into subsequences, such that each subsequences 13 * contains exactly one event. 14 * </p> 15 * 16 * @author Steffen Herbold 17 * @version 1.0 18 */ 9 19 public class SequenceSplitter { 10 20 21 /** 22 * <p> 23 * Contains the current subsequence. 24 * </p> 25 */ 11 26 private List<WindowsMessage> currentSequence; 12 27 28 /** 29 * <p> 30 * Number of messages in the current sequences, that signal that a key or 31 * mouse button has been pressed down to which not yet a message has been 32 * found, that signals that the button has been released. 33 * </p> 34 */ 13 35 private int openDowns; 14 36 37 /** 38 * <p> 39 * Internal flag that signals if {@link #currentSequence} needs to be 40 * initialized. 41 * </p> 42 */ 15 43 private boolean initMessages; 16 44 45 /** 46 * <p> 47 * The {@link EventGenerator} used to convert the subsequences into 48 * {@link Event}s 49 * </p> 50 */ 17 51 private EventGenerator tokenGenerator; 18 52 53 /** 54 * <p> 55 * The event sequence generated. 56 * </p> 57 */ 19 58 private List<WindowsEvent> actionSequence; 20 59 60 /** 61 * <p> 62 * Constructor. Creates a new SequenceSplitter. 63 * </p> 64 */ 21 65 public SequenceSplitter() { 22 66 currentSequence = new LinkedList<WindowsMessage>(); … … 26 70 actionSequence = new LinkedList<WindowsEvent>(); 27 71 } 28 72 73 /** 74 * <p> 75 * Called by the {@link LogParser} every time a message is parsed. 76 * </p> 77 * 78 * @param msg 79 * message to be added 80 */ 29 81 public void addMessage(WindowsMessage msg) { 30 if( startOfSequence(msg) ) { 31 if( !initMessages ) { 32 WindowsEvent currentAction = tokenGenerator.generateEvent(currentSequence); 33 if( currentAction!=null ) { 82 if (startOfSequence(msg)) { 83 if (!initMessages) { 84 WindowsEvent currentAction = tokenGenerator 85 .generateEvent(currentSequence); 86 if (currentAction != null) { 34 87 actionSequence.add(currentAction); 35 88 } 36 if ( isKeyMessage(msg.getType()) && openDowns>0) {89 if (isKeyMessage(msg.getType()) && openDowns > 0) { 37 90 Console.traceln("Key message found with open down mouse messages - will probabably result in a faulty sequence."); 38 91 } … … 41 94 } 42 95 currentSequence = new LinkedList<WindowsMessage>(); 43 } 44 if ( isUpMessage(msg.getType())) {45 if ( openDowns>0 ) {96 } 97 if (isUpMessage(msg.getType())) { 98 if (openDowns > 0) { 46 99 openDowns--; 47 100 } … … 49 102 currentSequence.add(msg); 50 103 } 51 104 105 /** 106 * <p> 107 * Returns the event sequence generated from the message that have been 108 * added. 109 * </p> 110 * 111 * @return generated event sequence 112 */ 52 113 public List<WindowsEvent> getSequence() { 53 114 return actionSequence; 54 115 } 55 116 117 /** 118 * <p> 119 * Called when a session in the log file is finished, i.e., a closing 120 * session-node is found. 121 * </p> 122 */ 56 123 public void endSession() { 57 WindowsEvent currentAction = tokenGenerator.generateEvent(currentSequence); 58 if( currentAction!=null ) { 124 WindowsEvent currentAction = tokenGenerator 125 .generateEvent(currentSequence); 126 if (currentAction != null) { 59 127 actionSequence.add(currentAction); 60 128 } 61 129 } 62 130 131 /** 132 * <p> 133 * Checks if the message starts a new subsequence and returns the result. 134 * </p> 135 * 136 * @param msg 137 * message that is checked 138 * @return true, if a new subsequence begins 139 */ 63 140 private boolean startOfSequence(WindowsMessage msg) { 64 141 boolean isStart = false; 65 142 int msgType = msg.getType(); 66 if ( isKeyMessage(msgType)) {143 if (isKeyMessage(msgType)) { 67 144 isStart = true; 68 145 } 69 if ( isDownMessage(msgType)) {146 if (isDownMessage(msgType)) { 70 147 openDowns++; 71 if ( openDowns==1) {148 if (openDowns == 1) { 72 149 isStart = true; 73 150 } 74 151 } 75 if ( isDblclkMessage(msgType)) {152 if (isDblclkMessage(msgType)) { 76 153 openDowns++; 77 154 } … … 79 156 } 80 157 158 /** 159 * <p> 160 * Checks if the type of a message is generated is a keyboard interaction. 161 * </p> 162 * 163 * @param msgType 164 * type of the message 165 * @return true if it is a keyboard interaction; false otherwise 166 */ 81 167 private boolean isKeyMessage(int msgType) { 82 168 boolean isKeyMsg = false; 83 169 switch (msgType) { 84 85 86 87 88 89 90 91 170 case MessageDefs.WM_KEYDOWN: 171 case MessageDefs.WM_KEYUP: 172 case MessageDefs.WM_SYSKEYDOWN: 173 case MessageDefs.WM_SYSKEYUP: 174 isKeyMsg = true; 175 break; 176 default: 177 break; 92 178 } 93 179 return isKeyMsg; 94 180 } 95 181 182 /** 183 * <p> 184 * Checks if the type of a message indicates that the mouse has been pressed 185 * down. 186 * </p> 187 * 188 * @param msgType 189 * type of the message 190 * @return true if it is mouse-down message; false otherwise 191 */ 96 192 private boolean isDownMessage(int msgType) { 97 193 boolean isDownMsg = false; 98 194 switch (msgType) { 99 100 101 102 103 104 105 106 107 108 109 110 195 case MessageDefs.WM_LBUTTONDOWN: 196 case MessageDefs.WM_RBUTTONDOWN: 197 case MessageDefs.WM_MBUTTONDOWN: 198 case MessageDefs.WM_XBUTTONDOWN: 199 case MessageDefs.WM_NCLBUTTONDOWN: 200 case MessageDefs.WM_NCRBUTTONDOWN: 201 case MessageDefs.WM_NCMBUTTONDOWN: 202 case MessageDefs.WM_NCXBUTTONDOWN: 203 isDownMsg = true; 204 break; 205 default: 206 break; 111 207 } 112 208 return isDownMsg; 113 209 } 114 210 211 /** 212 * <p> 213 * Checks if the type of a message indicates that a double click has been 214 * performed. 215 * </p> 216 * 217 * @param msgType 218 * type of the message 219 * @return true if it is a double click message; false otherwise 220 */ 115 221 private boolean isDblclkMessage(int msgType) { 116 222 boolean isDblclkMsg = false; 117 223 switch (msgType) { 118 119 120 121 122 123 124 125 126 127 128 129 224 case MessageDefs.WM_LBUTTONDBLCLK: 225 case MessageDefs.WM_RBUTTONDBLCLK: 226 case MessageDefs.WM_MBUTTONDBLCLK: 227 case MessageDefs.WM_XBUTTONDBLCLK: 228 case MessageDefs.WM_NCLBUTTONDBLCLK: 229 case MessageDefs.WM_NCRBUTTONDBLCLK: 230 case MessageDefs.WM_NCMBUTTONDBLCLK: 231 case MessageDefs.WM_NCXBUTTONDBLCLK: 232 isDblclkMsg = true; 233 break; 234 default: 235 break; 130 236 } 131 237 return isDblclkMsg; 132 238 } 133 239 240 /** 241 * <p> 242 * Checks if the type of a message indicates that the mouse has been 243 * released. 244 * </p> 245 * 246 * @param msgType 247 * type of the message 248 * @return true if it is mouse-up message; false otherwise 249 */ 134 250 private boolean isUpMessage(int msgType) { 135 251 boolean isUpMsg = false; 136 252 switch (msgType) { 137 138 139 140 141 142 143 144 145 146 147 148 253 case MessageDefs.WM_LBUTTONUP: 254 case MessageDefs.WM_RBUTTONUP: 255 case MessageDefs.WM_MBUTTONUP: 256 case MessageDefs.WM_XBUTTONUP: 257 case MessageDefs.WM_NCLBUTTONUP: 258 case MessageDefs.WM_NCRBUTTONUP: 259 case MessageDefs.WM_NCMBUTTONUP: 260 case MessageDefs.WM_NCXBUTTONUP: 261 isUpMsg = true; 262 break; 263 default: 264 break; 149 265 } 150 266 return isUpMsg; 151 267 } 152 268 153 269 } -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/WindowsEvent.java
r87 r171 4 4 import de.ugoe.cs.eventbench.windows.data.WindowsMessage; 5 5 6 7 // convenience class 6 /** 7 * <p> 8 * Convenience class for working with Windows MFC events. 9 * </p> 10 * 11 * @author Steffen Herbold 12 * @version 1.0 13 */ 8 14 public class WindowsEvent extends ReplayableEvent<WindowsMessage> { 9 15 10 16 /** 17 * <p> 11 18 * Id for object serialization. 19 * </p> 12 20 */ 13 21 private static final long serialVersionUID = 1L; 14 22 23 /** 24 * <p> 25 * Constructor. Creates a new WindowEvent. 26 * </p> 27 * 28 * @see de.ugoe.cs.eventbench.data.Event#Event(String) 29 * @param type 30 * type of the event. 31 */ 15 32 public WindowsEvent(String type) { 16 33 super(type); -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/commands/CMDconvertDirToXml.java
r52 r171 10 10 import de.ugoe.cs.util.console.Console; 11 11 12 /** 13 * <p> 14 * Command to pre-process all files in a folder. 15 * </p> 16 * 17 * @author Steffen Herbold 18 * @version 1.0 19 */ 12 20 public class CMDconvertDirToXml implements Command { 13 21 22 /* 23 * (non-Javadoc) 24 * 25 * @see de.ugoe.cs.util.console.Command#help() 26 */ 14 27 @Override 15 28 public void help() { … … 17 30 } 18 31 32 /* 33 * (non-Javadoc) 34 * 35 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 36 */ 19 37 @Override 20 38 public void run(List<Object> parameters) { 21 if ( parameters.size() < 2) {39 if (parameters.size() < 2) { 22 40 throw new InvalidParameterException(); 23 41 } … … 25 43 String target = (String) parameters.get(1); 26 44 boolean base64 = false; 27 if ( parameters.size() == 3) {45 if (parameters.size() == 3) { 28 46 base64 = Boolean.parseBoolean((String) parameters.get(2)); 29 47 } 30 48 31 49 try { 32 50 new LogPreprocessor(base64).convertDirToXml(path, target); … … 36 54 Console.println(e.getMessage()); 37 55 } 38 56 39 57 } 40 58 -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/commands/CMDconvertToXml.java
r52 r171 10 10 import de.ugoe.cs.util.console.Console; 11 11 12 /** 13 * <p> 14 * Command to pre-process a single file. 15 * </p> 16 * 17 * @author Steffen Herbold 18 * @version 1.0 19 */ 12 20 public class CMDconvertToXml implements Command { 13 21 22 /* 23 * (non-Javadoc) 24 * 25 * @see de.ugoe.cs.util.console.Command#help() 26 */ 14 27 @Override 15 28 public void help() { … … 17 30 } 18 31 32 /* 33 * (non-Javadoc) 34 * 35 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 36 */ 19 37 @Override 20 38 public void run(List<Object> parameters) { 21 if ( parameters.size() < 2) {39 if (parameters.size() < 2) { 22 40 throw new InvalidParameterException(); 23 41 } … … 25 43 String target = (String) parameters.get(1); 26 44 boolean base64 = false; 27 if ( parameters.size() == 3) {45 if (parameters.size() == 3) { 28 46 base64 = Boolean.parseBoolean((String) parameters.get(2)); 29 47 } 30 48 31 49 try { 32 50 new LogPreprocessor(base64).convertToXml(source, target); … … 36 54 Console.println(e.getMessage()); 37 55 } 38 56 39 57 } 40 58 -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/commands/CMDparseXML.java
r84 r171 10 10 import de.ugoe.cs.util.console.Console; 11 11 12 /** 13 * <p> 14 * Command to parse an XML file with sessions monitored by EventBench's 15 * MFCUsageMonitor. 16 * </p> 17 * 18 * @author Steffen Herbold 19 * @version 1.0 20 */ 12 21 public class CMDparseXML implements Command { 13 22 23 /* (non-Javadoc) 24 * @see de.ugoe.cs.util.console.Command#help() 25 */ 14 26 @Override 15 27 public void help() { … … 17 29 } 18 30 31 /* (non-Javadoc) 32 * @see de.ugoe.cs.util.console.Command#run(java.util.List) 33 */ 19 34 @Override 20 35 public void run(List<Object> parameters) { 21 36 String filename; 22 37 boolean countMessageOccurences = false; 23 38 24 39 try { 25 40 filename = (String) parameters.get(0); 26 if( parameters.size()==2 ) { 27 countMessageOccurences = Boolean.parseBoolean((String) parameters.get(1)); 41 if (parameters.size() == 2) { 42 countMessageOccurences = Boolean 43 .parseBoolean((String) parameters.get(1)); 28 44 } 29 45 } catch (Exception e) { 30 46 throw new InvalidParameterException(); 31 47 } 32 48 33 49 LogParser parser = new LogParser(countMessageOccurences); 34 50 parser.parseFile(filename); 35 51 36 52 List<List<WindowsEvent>> sequences = parser.getSequences(); 37 38 if ( GlobalDataContainer.getInstance().addData("sequences", sequences )) {53 54 if (GlobalDataContainer.getInstance().addData("sequences", sequences)) { 39 55 Console.traceln("Old data \"" + "sequences" + "\" overwritten"); 40 } 56 } 41 57 } 42 58 -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/data/WindowTree.java
r157 r171 28 28 * 29 29 * @author Steffen Herbold 30 * @version 1.0 30 31 */ 31 32 public class WindowTree { -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/data/WindowTreeNode.java
r52 r171 18 18 * 19 19 * @author Steffen Herbold 20 * @version 1.0 20 21 */ 21 22 public class WindowTreeNode { … … 69 70 */ 70 71 private List<WindowTreeNode> children; 71 72 72 73 /** 73 74 * <p> … … 263 264 xmlString = parent.xmlRepresentation(); 264 265 } 265 xmlString += "<window name=\"" + StringTools.xmlEntityReplacement(windowName) + "\" class=\"" 266 + StringTools.xmlEntityReplacement(className) + "\" resourceId=\"" + resourceId + "\" isModal=\"" 267 + isModal + "\"/>"; 266 xmlString += "<window name=\"" 267 + StringTools.xmlEntityReplacement(windowName) + "\" class=\"" 268 + StringTools.xmlEntityReplacement(className) 269 + "\" resourceId=\"" + resourceId + "\" isModal=\"" + isModal 270 + "\"/>"; 268 271 return xmlString; 269 272 } 270 273 274 /** 275 * <p> 276 * Returns the names of the parents and itself separated by dots, e.g., 277 * "GrandParent.Parent.windowName" 278 * </p> 279 * 280 * @return names of the parents separated by dots 281 */ 271 282 public String getParentNames() { 272 283 String parentNames = ""; 273 if (parent != null 274 parentNames = parent.getParentNames() +".";284 if (parent != null) { 285 parentNames = parent.getParentNames() + "."; 275 286 } 276 287 parentNames += windowName; -
trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/windows/data/WindowsMessage.java
r141 r171 8 8 import de.ugoe.cs.util.StringTools; 9 9 10 /** 11 * <p> 12 * Contains all informations about a windows message, i.e., all parameters that 13 * are read when a windows message is parsed as well as its target, hwnd, etc. 14 * </p> 15 * 16 * @author Steffen Herbold 17 * @version 1.0 18 * 19 */ 10 20 public class WindowsMessage implements IReplayable { 11 /** 12 * Id for object serialization. 21 22 /** 23 * <p> 24 * Id for object serialization. 25 * </p> 13 26 */ 14 27 private static final long serialVersionUID = 1L; 15 28 29 /** 30 * <p> 31 * Type of the message. 32 * </p> 33 */ 16 34 final int type; 35 36 /** 37 * <p> 38 * Window class of the message target. Default: "" 39 * </p> 40 */ 17 41 private String windowClass = ""; 42 43 /** 44 * <p> 45 * Resource Id of the message target. Default: 0 46 * </p> 47 */ 18 48 private int resourceId = 0; 49 50 /** 51 * <p> 52 * XML representation of the message target. 53 * </p> 54 */ 19 55 private String xmlWindowDescription = ""; 56 57 /** 58 * <p> 59 * String that contains the names of all parent widgets and itself, separated by dots, 60 * e.g., "GrandParent.Parent.self". 61 * </p> 62 */ 20 63 private String parentNames = null; 64 65 /** 66 * <p> 67 * String that contains the window class of the parent widget. 68 * </p> 69 */ 21 70 private String parentClass = null; 22 71 72 /** 73 * <p> 74 * LPARAM of the message. Default: 0 75 * </p> 76 */ 23 77 private long LPARAM = 0; 78 79 /** 80 * <p> 81 * WPARAM of the message. Default: 0 82 * </p> 83 */ 24 84 private long WPARAM = 0; 25 85 86 /** 87 * <p> 88 * If the LPARAM contains a HWND, this string stores the target of the HWND. 89 * </p> 90 */ 26 91 private String LPARAMasWindowDesc = null; 92 93 /** 94 * <p> 95 * If the WPARAM contains a HWND, this string stores the target of the HWND. 96 * </p> 97 */ 27 98 private String WPARAMasWindowDesc = null; 28 99 100 /** 101 * <p> 102 * Delay after sending the messages during a replay. Default: 0 103 * </p> 104 */ 29 105 private int delay = 0; 30 106 107 /** 108 * <p> 109 * A map of all parameters, associated with the message, created during the 110 * parsing of messages from the logs {@code param}-nodes. 111 * </p> 112 */ 31 113 private Map<String, String> params = new HashMap<String, String>(); 32 114 115 /** 116 * <p> 117 * Constructor. Creates a new message with a given message type. 118 * </p> 119 * 120 * @param type 121 * type of the message 122 */ 33 123 public WindowsMessage(int type) { 34 124 this.type = type; 35 125 } 36 126 127 /** 128 * <p> 129 * Adds a parameter to the message. 130 * </p> 131 * 132 * @param type 133 * type descriptor of the parameter 134 * @param value 135 * value of the parameter 136 */ 37 137 public void addParameter(String type, String value) { 38 138 params.put(type, value); … … 44 144 } 45 145 146 /** 147 * <p> 148 * Returns the type of the message. 149 * </p> 150 * 151 * @return type of the message 152 */ 46 153 public int getType() { 47 154 return type; 48 155 } 49 156 157 /** 158 * <p> 159 * Returns the value of a parameter, given its type. If the parameter is not 160 * found, {@code null} is returned. 161 * </p> 162 * 163 * @param type 164 * type of the parameter 165 * @return value of the parameter 166 */ 50 167 public String getParameter(String type) { 51 168 return params.get(type); 52 169 } 53 170 171 /** 172 * <p> 173 * Returns the window class of the message target. 174 * </p> 175 * 176 * @return window class of the message target 177 */ 54 178 public String getWindowClass() { 55 179 return windowClass; 56 180 } 57 181 182 /** 183 * <p> 184 * Returns the HWND the message is addressed to. 185 * </p> 186 * 187 * @return HWND the message is addressed to 188 */ 58 189 public int getHwnd() { 59 190 int hwnd = -1; … … 67 198 } 68 199 200 /** 201 * <p> 202 * Returns the resource Id of the message target. 203 * </p> 204 * 205 * @return resource Id of the message target 206 */ 69 207 public int getWindowResourceId() { 70 208 return resourceId; 71 209 } 72 210 211 /** 212 * <p> 213 * Two {@link WindowsMessage} are equal, if their {@link #type}, 214 * {@link #xmlWindowDescription}, and {@link #params} are equal. 215 * </p> 216 * 217 * @see java.lang.Object#equals(java.lang.Object) 218 */ 73 219 @Override 74 220 public boolean equals(Object other) { 75 if ( other==this) {221 if (other == this) { 76 222 return true; 77 223 } … … 86 232 } 87 233 234 /* 235 * (non-Javadoc) 236 * 237 * @see java.lang.Object#hashCode() 238 */ 88 239 @Override 89 240 public int hashCode() { … … 98 249 } 99 250 251 /** 252 * <p> 253 * Returns a string representation of the message of the form 254 * "msg[target=HWND;type=TYPE]". 255 * </p> 256 * 257 * @see java.lang.Object#toString() 258 */ 100 259 @Override 101 260 public String toString() { … … 104 263 } 105 264 265 /** 266 * <p> 267 * Retrieves the target string of a message from a given {@link WindowTree} 268 * through looking up the HWND the message is addressed to in the window 269 * tree. 270 * </p> 271 * 272 * @param windowTree 273 * {@link WindowTree} from which the target is extracted 274 * @throws InvalidParameterException 275 * thrown if HWND is not contained in windowTree 276 */ 106 277 public void setTarget(WindowTree windowTree) 107 278 throws InvalidParameterException { … … 117 288 parentNames = node.getParentNames(); 118 289 WindowTreeNode parent = node.getParent(); 119 if ( parent==null) {290 if (parent == null) { 120 291 parentClass = ""; 121 292 } else { … … 125 296 } 126 297 298 /** 299 * <p> 300 * Sets the LPARAM of a message. 301 * </p> 302 * 303 * @param paramValue 304 * value of the LPARAM 305 */ 127 306 public void setLPARAM(long paramValue) { 128 307 LPARAM = paramValue; 129 308 } 130 309 310 /** 311 * <p> 312 * Sets the WPARAM of a message. 313 * </p> 314 * 315 * @param paramValue 316 * value of the WPARAM 317 */ 131 318 public void setWPARAM(long paramValue) { 132 319 WPARAM = paramValue; 133 320 } 134 321 322 /** 323 * <p> 324 * Returns the LPARAM of a message. 325 * </p> 326 * 327 * @return LPARAM of the message 328 */ 135 329 public long getLPARAM() { 136 330 return LPARAM; 137 331 } 138 332 333 /** 334 * <p> 335 * Returns the WPARAM of a message. 336 * </p> 337 * 338 * @return WPARAM of the message 339 */ 139 340 public long getWPARAM() { 140 341 return WPARAM; 141 342 } 142 343 344 /** 345 * <p> 346 * If the LPARAM contains a HWND, this function can be used to set a target 347 * string to identify the HWND at run-time. 348 * </p> 349 * 350 * @param windowDesc 351 * target string 352 */ 143 353 public void setLPARAMasWindowDesc(String windowDesc) { 144 354 LPARAMasWindowDesc = windowDesc; 145 355 } 146 356 357 /** 358 * <p> 359 * If the WPARAM contains a HWND, this function can be used to set a target 360 * string to identify the HWND at run-time. 361 * </p> 362 * 363 * @param windowDesc 364 * target string 365 */ 147 366 public void setWPARAMasWindowDesc(String windowDesc) { 148 367 WPARAMasWindowDesc = windowDesc; 149 368 } 150 369 370 /** 371 * <p> 372 * If the LPARAM contains a HWND and the target string for the HWND is set, 373 * this function returns the target string. Otherwise, {@code null} is 374 * returned. 375 * </p> 376 * 377 * @return target string if available; {@code null} otherwise 378 */ 151 379 public String getLPARAMasWindowDesc() { 152 380 return LPARAMasWindowDesc; 153 381 } 154 382 383 /** 384 * <p> 385 * If the WPARAM contains a HWND and the target string for the HWND is set, 386 * this function returns the target string. Otherwise, {@code null} is 387 * returned. 388 * </p> 389 * 390 * @return target string if available; {@code null} otherwise 391 */ 155 392 public String getWPARAMasWindowDesc() { 156 393 return WPARAMasWindowDesc; 157 394 } 158 395 396 /** 397 * <p> 398 * Returns the target string of the message. 399 * </p> 400 * 401 * @return target string of the message 402 */ 159 403 public String getXmlWindowDescription() { 160 404 return xmlWindowDescription; 161 405 } 162 406 407 /** 408 * <p> 409 * Sets the target string manually. 410 * </p> 411 * 412 * @param xmlWindowDescription 413 * target string 414 */ 163 415 public void setXmlWindowDescription(String xmlWindowDescription) { 164 416 this.xmlWindowDescription = xmlWindowDescription; 165 417 } 166 418 419 /** 420 * <p> 421 * Returns the delay after this message during replays. 422 * </p> 423 * 424 * @return delay after this message 425 */ 167 426 public int getDelay() { 168 427 return delay; 169 428 } 170 429 430 /** 431 * <p> 432 * Sets the delay after this message during replays. 433 * </p> 434 * 435 * @param delay 436 * delay after this message 437 */ 171 438 public void setDelay(int delay) { 172 439 this.delay = delay; 173 440 } 174 441 442 /** 443 * <p> 444 * Returns the parent names separated by dots, e.g., "GrandParent.Parent". 445 * </p> 446 * 447 * @return names of the parents 448 */ 175 449 public String getParentNames() { 176 450 return parentNames; 177 451 } 178 452 453 /** 454 * <p> 455 * Returns the window class of the parent. 456 * </p> 457 * 458 * @return window classes of the parents 459 */ 179 460 public String getParentClass() { 180 461 return parentClass; 181 462 } 182 463 464 /** 465 * <p> 466 * Returns the number of parameters stored together with this message. 467 * </p> 468 * 469 * @return 470 */ 183 471 public int getNumParams() { 184 472 return params.size(); 185 473 } 186 474 475 /* 476 * (non-Javadoc) 477 * 478 * @see de.ugoe.cs.eventbench.data.IReplayable#getReplay() 479 */ 480 @Override 187 481 public String getReplay() { 188 482 StringBuilder currentMsgStr = new StringBuilder(400); 189 currentMsgStr.append(" <msg type=\"" +type+"\" ");190 currentMsgStr.append("LPARAM=\"" +LPARAM+"\" ");191 currentMsgStr.append("WPARAM=\"" +WPARAM+"\" ");192 currentMsgStr.append("delay=\"" +delay+"\">");193 if ( LPARAMasWindowDesc!=null) {483 currentMsgStr.append(" <msg type=\"" + type + "\" "); 484 currentMsgStr.append("LPARAM=\"" + LPARAM + "\" "); 485 currentMsgStr.append("WPARAM=\"" + WPARAM + "\" "); 486 currentMsgStr.append("delay=\"" + delay + "\">"); 487 if (LPARAMasWindowDesc != null) { 194 488 currentMsgStr.append(StringTools.ENDLINE); 195 489 currentMsgStr.append(" <LPARAM>"); … … 198 492 currentMsgStr.append(StringTools.ENDLINE); 199 493 currentMsgStr.append("</LPARAM>"); 200 } 201 if ( WPARAMasWindowDesc!=null) {494 } 495 if (WPARAMasWindowDesc != null) { 202 496 currentMsgStr.append(StringTools.ENDLINE); 203 497 currentMsgStr.append(" <WPARAM>"); … … 214 508 return currentMsgStr.toString(); 215 509 } 216 510 511 /* 512 * (non-Javadoc) 513 * 514 * @see de.ugoe.cs.eventbench.data.IReplayable#getTarget() 515 */ 516 @Override 217 517 public String getTarget() { 218 518 return xmlWindowDescription;
Note: See TracChangeset
for help on using the changeset viewer.