- Timestamp:
- 09/09/11 06:23:36 (13 years ago)
- File:
-
- 1 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
Note: See TracChangeset
for help on using the changeset viewer.