source: trunk/EventBenchConsole/src/de/ugoe/cs/eventbench/EventGenerator.java @ 28

Last change on this file since 28 was 28, checked in by sherbold, 13 years ago
  • minor changes
File size: 24.3 KB
Line 
1package de.ugoe.cs.eventbench;
2
3import java.io.IOException;
4import java.security.InvalidParameterException;
5import java.util.HashMap;
6import java.util.Iterator;
7import java.util.LinkedList;
8import java.util.List;
9import java.util.ListIterator;
10import java.util.Map;
11import java.util.NoSuchElementException;
12
13import org.jdom.Document;
14import org.jdom.Element;
15import org.jdom.JDOMException;
16import org.jdom.Namespace;
17import org.jdom.input.SAXBuilder;
18
19import de.ugoe.cs.eventbench.data.Event;
20import de.ugoe.cs.eventbench.data.ReplayableEvent;
21import de.ugoe.cs.eventbench.data.WindowTree;
22import de.ugoe.cs.eventbench.data.WindowTreeNode;
23import de.ugoe.cs.eventbench.data.WindowsMessage;
24import de.ugoe.cs.util.console.Console;
25
26/**
27 * <p>
28 * Translates sequences of windows messages into events that can be used by the
29 * Logalyzer core libraries for usage analysis.
30 * </p>
31 *
32 * @author Steffen Herbold
33 *
34 */
35public class EventGenerator {
36
37        /**
38         * <p>
39         * Helper method that fetches the document node of an XML file.
40         * </p>
41         *
42         * @param filename
43         *            name of the XML file
44         * @return the document node
45         */
46        private static Document getDocument(String filename) {
47                SAXBuilder builder = new SAXBuilder();
48                Document doc = null;
49
50                try {
51                        doc = builder.build(filename);
52                        rulesNamespace = Namespace.getNamespace("ul:rules");
53                } catch (JDOMException e) {
54                        System.err.println("Invalid rules file.");
55                        e.printStackTrace();
56                } catch (IOException e) {
57                        System.err.println("Invalid rules file.");
58                        e.printStackTrace();
59                }
60
61                return doc;
62        }
63
64        /**
65         * <p>
66         * Name and path of the XML files containing the rules.
67         * </p>
68         */
69        private String rulesFile;
70
71        /**
72         * <p>
73         * Iterator used for the current sequence.
74         * </p>
75         */
76        private ListIterator<WindowsMessage> sequenceIterator;
77
78        /**
79         * <p>
80         * Token that is currently being generated.
81         * </p>
82         */
83        private ReplayableEvent<WindowsMessage> currentToken;
84
85        /**
86         * <p>
87         * Reference to the ul:rules namespace.
88         * </p>
89         */
90        private static Namespace rulesNamespace;
91
92        /**
93         * <p>
94         * The name of the rule that is currently being evaluated.
95         * </p>
96         */
97        private String currentRuleName;
98
99        /**
100         * <p>
101         * Internal message storage. Used to implement the
102         * <code>{@literal <store>}</code> and <code>{@literal <storeSeq>}</code>
103         * tags.
104         * </p>
105         */
106        private Map<String, Object> messageStorage;
107
108        /**
109         * <p>
110         * Creates a new EventGenerator. Sets "rules/rules.xml" as default file for
111         * the rules.
112         * </p>
113         */
114        public EventGenerator() {
115                rulesFile = "rules/rules.xml";
116        }
117
118        /**
119         * <p>
120         * Tries to match the rules to the given sequence to generate an
121         * {@link Event}.
122         * </p>
123         * <p>
124         * The rules are matched the order, in which they are defined in the XML
125         * file. Therefore, the order of the rules in the file defines priorities,
126         * when multiple rules could be matched to the same sequence.
127         * </p>
128         *
129         * @param sequence
130         *            sequence of message for which an event will be generated
131         * @return event that matches the messages; null, if no rule can be matched
132         */
133        @SuppressWarnings("unchecked")
134        public Event<WindowsMessage> generateEvent(List<WindowsMessage> sequence) {
135                Document rulesDoc = getDocument(rulesFile);
136                Element rulesRoot = rulesDoc.getRootElement();
137
138                List<Element> ruleElements = rulesRoot.getChildren("rule",
139                                rulesNamespace);
140
141                boolean isMatch = false;
142
143                for (int ruleIndex = 0; ruleIndex < ruleElements.size() && !isMatch; ruleIndex++) {
144                        Element currentRule = ruleElements.get(ruleIndex);
145                        currentRuleName = currentRule.getAttributeValue("name");
146                        currentToken = new ReplayableEvent<WindowsMessage>(currentRuleName);
147                        isMatch = true;
148                        messageStorage = new HashMap<String, Object>();
149                        sequenceIterator = sequence.listIterator();
150                        List<Element> ruleChildrenMsg = currentRule.getChildren("msg",
151                                        rulesNamespace);
152
153                        int i = 0;
154                        while (isMatch && i < ruleChildrenMsg.size()) {
155                                Element messageElement = ruleChildrenMsg.get(i);
156                                if ("true".equals(messageElement.getAttributeValue("multiple"))) {
157                                        Element nextMessageElement = null;
158                                        if (i + 1 < ruleChildrenMsg.size()) {
159                                                nextMessageElement = ruleChildrenMsg.get(i + 1);
160                                        }
161                                        try {
162                                                isMatch = matchMultipleMessages(messageElement,
163                                                                nextMessageElement);
164                                        } catch (InvalidParameterException e) {
165                                                Console.printerrln(e.getMessage());
166                                        }
167                                } else {
168                                        try {
169                                                isMatch = matchSingleMessage(messageElement);
170                                        } catch (InvalidParameterException e) {
171                                                Console.printerrln(e.getMessage());
172                                        }
173                                }
174                                i++;
175                        }
176                        if (isMatch) {
177                                List<Element> ruleChildren = currentRule.getChildren();
178                                for (Element genMsgElement : ruleChildren) {
179                                        if (genMsgElement.getName().equals("genMsg")) {
180                                                try {
181                                                        generateReplayMessage(genMsgElement);
182                                                } catch (InvalidParameterException e) {
183                                                        Console.printerrln(e.getMessage());
184                                                        currentToken.invalidateReplay();
185                                                }
186                                        } else if (genMsgElement.getName().equals("genMsgSeq")) {
187                                                try {
188                                                        generateReplaySequence(genMsgElement);
189                                                        currentToken.invalidateReplay();
190                                                } catch (InvalidParameterException e) {
191                                                        Console.printerrln(e.getMessage());
192                                                        currentToken.invalidateReplay();
193                                                }
194                                        }
195                                }
196                                Element idinfoElement = currentRule.getChild("idinfo",
197                                                rulesNamespace);
198                                if (idinfoElement != null) {
199                                        // cannot be empty if document is valid
200                                        List<Element> valueElements = idinfoElement.getChildren();
201                                        currentToken.setIdInfo(getTermValue(null,
202                                                        valueElements.get(0)));
203                                }
204                                Console.traceln(currentRule.getAttributeValue("name")
205                                                + currentToken.getIdInfo() + " matched");
206                        } else {
207                                currentToken = null;
208                        }
209                }
210                if (!isMatch) {
211                        Console.traceln("no match found for sequence: "
212                                        + sequence.toString());
213                }
214                return currentToken;
215        }
216
217        private boolean createSequenceLParam(
218                        List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
219                        int constMsgType, Element termElement)
220                        throws NoSuchElementException {
221                Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
222                if (termElement.getName().equals("seqValue")) {
223                        String obj = termElement.getAttributeValue("seqObj");
224                        List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
225                        if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
226                                throw new InvalidParameterException(
227                                                "Failure generating replay sequence for rule "
228                                                                + currentRuleName
229                                                                + ": One or more of the sequence variables used to generate a sequence have different lenghts.");
230                        }
231                        for (WindowsMessage msg : seqVar) {
232                                WindowsMessage currentSeqMsg = getCurrentSeqMsg(
233                                                generatedMessageSeq, msgsGenerated, constMsgType,
234                                                seqIterator);
235                                String paramValueStr = msg.getParameter(termElement
236                                                .getAttributeValue("param"));
237                                int paramValue = 0;
238                                try {
239                                        paramValue = Integer.parseInt(paramValueStr);
240                                        currentSeqMsg.setLPARAM(paramValue);
241                                } catch (NumberFormatException e) {
242                                        currentSeqMsg.setLPARAMasWindowDesc(paramValueStr);
243                                }
244                        }
245                        if (seqIterator.hasNext()) {
246                                // the first seq-var has a different number of elements than the
247                                // current one
248                                throw new NoSuchElementException();
249                        }
250                        msgsGenerated = true;
251                } else { // const value
252                        int paramValue = Integer.parseInt(getTermValue(null, termElement));
253                        while (seqIterator.hasNext()) {
254                                seqIterator.next().setLPARAM(paramValue);
255                        }
256                }
257                return msgsGenerated;
258        }
259
260        private boolean createSequenceTarget(
261                        List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
262                        int constMsgType, Element termElement)
263                        throws NoSuchElementException {
264                Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
265                if (termElement.getName().equals("seqValue")) {
266                        String obj = termElement.getAttributeValue("seqObj");
267                        List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
268                        if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
269                                throw new InvalidParameterException(
270                                                "Failure generating replay sequence for rule "
271                                                                + currentRuleName
272                                                                + ": One or more of the sequence variables used to generate a sequence have different lenghts.");
273                        }
274                        for (WindowsMessage msg : seqVar) {
275                                WindowsMessage currentSeqMsg = getCurrentSeqMsg(
276                                                generatedMessageSeq, msgsGenerated, constMsgType,
277                                                seqIterator);
278                                String targetString = msg.getParameter(termElement
279                                                .getAttributeValue("param"));
280                                currentSeqMsg.setXmlWindowDescription(targetString);
281                        }
282                        msgsGenerated = true;
283                } else { // const value
284                        throw new AssertionError("target must be a sequence variable!");
285                        /*
286                         * If target would not be a variable, the message-elements could not
287                         * yet be created and the whole sequence might be broken. If this is
288                         * to be changed, createSequenceLParam and createSequenceWParam need
289                         * to be addepted, too.
290                         */
291                }
292                return msgsGenerated;
293        }
294
295        private boolean createSequenceWParam(
296                        List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
297                        int constMsgType, Element termElement)
298                        throws NoSuchElementException {
299                Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
300                if (termElement.getName().equals("seqValue")) {
301                        String obj = termElement.getAttributeValue("seqObj");
302                        List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
303                        if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
304                                throw new InvalidParameterException(
305                                                "Failure generating replay sequence for rule "
306                                                                + currentRuleName
307                                                                + ": One or more of the sequence variables used to generate a sequence have different lenghts.");
308                        }
309                        for (WindowsMessage msg : seqVar) {
310                                WindowsMessage currentSeqMsg = getCurrentSeqMsg(
311                                                generatedMessageSeq, msgsGenerated, constMsgType,
312                                                seqIterator);
313                                String paramValueStr = msg.getParameter(termElement
314                                                .getAttributeValue("param"));
315                                int paramValue = 0;
316                                try {
317                                        paramValue = Integer.parseInt(paramValueStr);
318                                        currentSeqMsg.setWPARAM(paramValue);
319                                } catch (NumberFormatException e) {
320                                        currentSeqMsg.setWPARAMasWindowDesc(paramValueStr);
321                                }
322                        }
323                        if (seqIterator.hasNext()) {
324                                // the first seq-var has a different number of elements than the
325                                // current one
326                                throw new NoSuchElementException();
327                        }
328                        msgsGenerated = true;
329                } else { // const value
330                        int paramValue = Integer.parseInt(getTermValue(null, termElement));
331                        while (seqIterator.hasNext()) {
332                                seqIterator.next().setWPARAM(paramValue);
333                        }
334                }
335                return msgsGenerated;
336        }
337
338        @SuppressWarnings("unchecked")
339        private boolean evalEqualRestrictions(WindowsMessage currentMessage,
340                        Element messageElement) {
341                boolean isMatch = true;
342                for (Element childElement : (List<Element>) messageElement.getChildren(
343                                "equals", rulesNamespace)) {
344                        List<Element> termElements = childElement.getChildren();
345                        // the size 2 of termElements is guaranteed by the XML schema
346                        String value1 = getTermValue(currentMessage, termElements.get(0));
347                        String value2 = getTermValue(currentMessage, termElements.get(1));
348                        if (value1 == null || value2 == null) {
349                                isMatch = false;
350                        } else {
351                                isMatch = isMatch && value1.equals(value2);
352                        }
353                }
354                for (Element childElement : (List<Element>) messageElement.getChildren(
355                                "equalsSeq", rulesNamespace)) {
356                        List<Element> termElements = childElement.getChildren();
357                        List<String> values1 = getTermValueSeq(currentMessage,
358                                        termElements.get(0));
359                        List<String> values2 = getTermValueSeq(currentMessage,
360                                        termElements.get(0));
361                        if (values1 == null || values2 == null) {
362                                isMatch = false;
363                        } else {
364                                isMatch = isMatch && values1.equals(values2);
365                        }
366                }
367                return isMatch;
368        }
369
370        @SuppressWarnings("unchecked")
371        private void generateReplayMessage(Element genMsgElement) {
372                List<Element> genMsgChildren = genMsgElement.getChildren();
373                WindowsMessage generatedMessage = null;
374                if (genMsgChildren.size() == 1) { // replay stored message without
375                                                                                        // change
376                        String obj = genMsgChildren.get(0).getAttributeValue("obj");
377                        generatedMessage = getStoredMessageVariable(null, obj);
378                } else { // generate message according to the rule
379                        for (Element genMsgChild : genMsgChildren) {
380                                Element termElement = (Element) genMsgChild.getChildren()
381                                                .get(0);
382                                if (genMsgChild.getName().equals("type")) {
383                                        try {
384                                                int msgType = Integer.parseInt(getTermValue(null,
385                                                                termElement));
386                                                generatedMessage = new WindowsMessage(msgType);
387                                        } catch (NumberFormatException e) {
388                                                throw new InvalidParameterException(
389                                                                "Failure generating replay sequence for rule "
390                                                                                + currentRuleName
391                                                                                + ": Defined type is not an integer.");
392                                        }
393                                } else if (genMsgChild.getName().equals("target")) {
394                                        String targetString = getTermValue(null, termElement);
395                                        generatedMessage.setXmlWindowDescription(targetString);
396                                } else if (genMsgChild.getName().equals("LPARAM")) {
397                                        String paramValueStr = getTermValue(null, termElement);
398                                        int paramValue = 0;
399                                        try {
400                                                paramValue = Integer.parseInt(paramValueStr);
401                                                generatedMessage.setLPARAM(paramValue);
402                                        } catch (NumberFormatException e) {
403                                                generatedMessage.setLPARAMasWindowDesc(paramValueStr);
404                                        }
405                                } else if (genMsgChild.getName().equals("WPARAM")) {
406                                        String paramValueStr = getTermValue(null, termElement);
407                                        int paramValue = 0;
408                                        try {
409                                                paramValue = Integer.parseInt(paramValueStr);
410                                                generatedMessage.setWPARAM(paramValue);
411                                        } catch (NumberFormatException e) {
412                                                generatedMessage.setWPARAMasWindowDesc(paramValueStr);
413                                        }
414                                }
415                        }
416                }
417                if (generatedMessage != null) {
418                        int delay = Integer.parseInt(genMsgElement
419                                        .getAttributeValue("delay"));
420                        generatedMessage.setDelay(delay);
421                } else {
422                        currentToken.invalidateReplay();
423                }
424                currentToken.addReplayEvent(generatedMessage);
425        }
426
427        @SuppressWarnings("unchecked")
428        private void generateReplaySequence(Element genMsgElement) {
429                List<Element> genMsgSeqChildren = genMsgElement.getChildren();
430                List<WindowsMessage> generatedMessageSeq = new LinkedList<WindowsMessage>();
431                if (genMsgSeqChildren.size() == 1) {
432                        String obj = genMsgSeqChildren.get(0).getAttributeValue("seqObj");
433                        generatedMessageSeq = getStoredSeqVariable(obj);
434                } else {
435                        boolean msgsGenerated = false;
436                        int constMsgType = 0;
437                        for (Element genMsgSeqChild : genMsgSeqChildren) {
438                                Element termElement = (Element) genMsgSeqChild.getChildren()
439                                                .get(0);
440                                if (genMsgSeqChild.getName().equals("type")) {
441                                        // note: cannot easily be extracted because of mulitple
442                                        // return values
443                                        if (termElement.getName().equals("seqValue")) {
444                                                String obj = termElement.getAttributeValue("seqObj");
445                                                List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
446                                                for (WindowsMessage msg : seqVar) {
447                                                        generatedMessageSeq.add(new WindowsMessage(msg
448                                                                        .getType()));
449                                                }
450                                                msgsGenerated = true;
451                                        } else { // constValue type
452                                                constMsgType = Integer.parseInt(getTermValue(null,
453                                                                termElement));
454                                        }
455                                } else if (genMsgSeqChild.getName().equals("target")) {
456                                        msgsGenerated = createSequenceTarget(generatedMessageSeq,
457                                                        msgsGenerated, constMsgType, termElement);
458                                } else if (genMsgSeqChild.getName().equals("LPARAM")) {
459                                        msgsGenerated = createSequenceLParam(generatedMessageSeq,
460                                                        msgsGenerated, constMsgType, termElement);
461                                } else if (genMsgSeqChild.getName().equals("WPARAM")) {
462                                        msgsGenerated = createSequenceWParam(generatedMessageSeq,
463                                                        msgsGenerated, constMsgType, termElement);
464                                }
465                        }
466                }
467                currentToken.addReplaySequence(generatedMessageSeq);
468        }
469
470        private WindowsMessage getCurrentSeqMsg(
471                        List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
472                        int constMsgType, Iterator<WindowsMessage> seqIterator) {
473                WindowsMessage currentSeqMsg = null;
474                if (msgsGenerated) {
475                        currentSeqMsg = seqIterator.next();
476                } else {
477                        currentSeqMsg = new WindowsMessage(constMsgType);
478                        generatedMessageSeq.add(currentSeqMsg);
479                }
480                return currentSeqMsg;
481        }
482
483        private WindowsMessage getStoredMessageVariable(
484                        WindowsMessage currentMessage, String obj)
485                        throws InvalidParameterException {
486                WindowsMessage varMessage = null;
487                if (obj.equals("this")) {
488                        if (currentMessage == null) {
489                                throw new InvalidParameterException(
490                                                "Failure obtaining term value for rule "
491                                                                + currentRuleName
492                                                                + ": \"this\" is not a valid name for generating runtime messages.");
493                        }
494                        varMessage = currentMessage;
495                } else {
496                        Object tmp = messageStorage.get(obj);
497                        if (tmp instanceof WindowsMessage) {
498                                varMessage = (WindowsMessage) tmp;
499                        } else {
500                                throw new InvalidParameterException(
501                                                "Failure obtaining term value for rule "
502                                                                + currentRuleName + ": No message \"" + obj
503                                                                + "\" stored.");
504                        }
505                }
506                return varMessage;
507        }
508
509        @SuppressWarnings("unchecked")
510        private List<WindowsMessage> getStoredSeqVariable(String obj)
511                        throws InvalidParameterException {
512                List<WindowsMessage> varMsgSeq = null;
513                Object tmp = messageStorage.get(obj);
514                if (tmp instanceof List<?>) {
515                        varMsgSeq = (List<WindowsMessage>) tmp;
516                } else {
517                        throw new InvalidParameterException(
518                                        "Failure obtaining term value for rule " + currentRuleName
519                                                        + ": No sequence \"" + obj + "\" store.");
520                }
521                return varMsgSeq;
522        }
523
524        private String getTermValue(WindowsMessage currentMessage,
525                        Element termElement) {
526                String value = null;
527                WindowsMessage varMessage = null;
528                if (termElement.getName().equals("constValue")) {
529                        value = termElement.getAttributeValue("value");
530                } else if (termElement.getName().equals("paramValue")) {
531                        String objectName = termElement.getAttributeValue("obj");
532                        varMessage = getStoredMessageVariable(currentMessage, objectName);
533                        if (varMessage != null) {
534                                String param = termElement.getAttributeValue("param");
535                                value = varMessage.getParameter(param);
536                        }
537                } else if (termElement.getName().equals("winInfoValue")) {
538                        String objectName = termElement.getAttributeValue("obj");
539                        varMessage = getStoredMessageVariable(currentMessage, objectName);
540                        if (varMessage != null) {
541                                String paramString = termElement.getAttributeValue("winParam");
542                                if (paramString.equals("class")) {
543                                        value = varMessage.getWindowClass();
544                                } else if (paramString.equals("resourceId")) {
545                                        value = "" + varMessage.getWindowResourceId();
546                                } else if (paramString.equals("hwnd")) {
547                                        value = "" + varMessage.getHwnd();
548                                } else if (paramString.equals("parentTarget")) {
549                                        String target = varMessage.getXmlWindowDescription();
550                                        int index = target.lastIndexOf("<");
551                                        if( index==0 ) {
552                                                Console.println("Trying to adress parent of top-level window! Replay probably invalid!");
553                                        }
554                                        value = target.substring(0, index);
555                                }
556                        }
557                } else if (termElement.getName().equals("msgInfoValue")) {
558                        String objectName = termElement.getAttributeValue("obj");
559                        varMessage = getStoredMessageVariable(currentMessage, objectName);
560                        if (varMessage != null) {
561                                String paramString = termElement.getAttributeValue("msgParam");
562                                if (paramString.equals("type")) {
563                                        value = "" + varMessage.getType();
564                                } else if (paramString.equals("target")) {
565                                        value = varMessage.getXmlWindowDescription();
566                                }
567                        }
568                }
569                return value;
570        }
571
572        private List<String> getTermValueSeq(WindowsMessage currentMessage,
573                        Element termElement) {
574                List<String> values = new LinkedList<String>();
575                if (termElement.getName().equals("seqValue")) {
576                        String obj = termElement.getAttributeValue("seqObj");
577                        String param = termElement.getAttributeValue("param");
578                        List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
579
580                        for (WindowsMessage msg : seqVar) {
581                                // msg.getParameter returns null, if parameter is not found,
582                                // therefore the List can contain null-values
583                                values.add(msg.getParameter(param));
584                        }
585                }
586                return values;
587        }
588
589        @SuppressWarnings("unchecked")
590        private void handleStorage(Element messageElement,
591                        WindowsMessage currentMessage) {
592                for (Element childElement : (List<Element>) messageElement.getChildren(
593                                "store", rulesNamespace)) {
594                        String identifier = childElement.getAttributeValue("var");
595                        messageStorage.put(identifier, currentMessage);
596                        resolveHwnd(currentMessage, childElement);
597                }
598                for (Element childElement : (List<Element>) messageElement.getChildren(
599                                "storeSeq", rulesNamespace)) {
600                        String identifier = childElement.getAttributeValue("varSeq");
601                        Object tmp = messageStorage.get(identifier);
602                        List<WindowsMessage> storedSequence;
603                        if (tmp == null || tmp instanceof WindowsMessage) {
604                                storedSequence = new LinkedList<WindowsMessage>();
605                                storedSequence.add(currentMessage);
606                                messageStorage.put(identifier, storedSequence);
607                        } else if (tmp instanceof List<?>) {
608                                storedSequence = (List<WindowsMessage>) tmp;
609                                storedSequence.add(currentMessage);
610                                messageStorage.put(identifier, storedSequence);
611                        }
612                        resolveHwnd(currentMessage, childElement);
613                }
614        }
615
616        private boolean matchMultipleMessages(Element messageElement,
617                        Element nextMessageElement) {
618                boolean isMatch = false;
619                boolean isCurrentMatch = false;
620                boolean nextMatchFound = false;
621                WindowsMessage currentMessage = null;
622                WindowsMessage nextMessage = null;
623
624                int type = Integer.parseInt(messageElement.getAttributeValue("type"));
625
626                int nextType = -1;
627                if (nextMessageElement != null) {
628                        nextType = Integer.parseInt(nextMessageElement
629                                        .getAttributeValue("type"));
630                }
631
632                while (!nextMatchFound && sequenceIterator.hasNext()) {
633                        currentMessage = sequenceIterator.next();
634                        if (type == currentMessage.getType()) {
635                                isCurrentMatch = evalEqualRestrictions(currentMessage,
636                                                messageElement);
637                                isMatch = isMatch || isCurrentMatch;
638
639                                if (isCurrentMatch) {
640                                        handleStorage(messageElement, currentMessage);
641                                        currentToken.setTarget(currentMessage
642                                                        .getXmlWindowDescription());
643                                        currentToken
644                                                        .setTargetShort(currentMessage.getParentNames());
645                                }
646                        }
647                        if (nextMessageElement != null && isMatch) {
648                                // peek next message to check if the sequence ends and the next
649                                // match is found
650                                if (!sequenceIterator.hasNext()) {
651                                        return false; // sequence is over, but not all messages are
652                                                                        // found
653                                }
654                                nextMessage = sequenceIterator.next();
655                                sequenceIterator.previous();
656
657                                if (nextType == nextMessage.getType()) {
658                                        nextMatchFound = evalEqualRestrictions(nextMessage,
659                                                        nextMessageElement);
660                                }
661
662                        }
663                }
664
665                return isMatch;
666        }
667
668        private boolean matchSingleMessage(Element messageElement) {
669                boolean isMatch = false;
670                WindowsMessage currentMessage = null;
671
672                int type = Integer.parseInt(messageElement.getAttributeValue("type"));
673
674                while (!isMatch && sequenceIterator.hasNext()) {
675                        // traverses the messages from the current position forward till a
676                        // message with the correct type is found
677                        currentMessage = sequenceIterator.next();
678                        if (type == currentMessage.getType()) {
679                                // message with the correct type found
680                                // eval child nodes for further matching/storing
681                                isMatch = evalEqualRestrictions(currentMessage, messageElement);
682
683                                // in case the message is a match, eval storage children
684                                if (isMatch) {
685                                        handleStorage(messageElement, currentMessage);
686                                        currentToken.setTarget(currentMessage
687                                                        .getXmlWindowDescription());
688                                        currentToken
689                                                        .setTargetShort(currentMessage.getParentNames());
690                                }
691                        }
692                }
693
694                return isMatch;
695        }
696
697        @SuppressWarnings("unchecked")
698        private void resolveHwnd(WindowsMessage currentMessage, Element childElement) {
699                List<Element> resolveElements = childElement.getChildren("resolveHwnd",
700                                rulesNamespace);
701                for (Element resolveElement : resolveElements) {
702                        String param = resolveElement.getAttributeValue("param");
703                        String storeParam = resolveElement.getAttributeValue("storeParam");
704                        int paramHwnd = Integer
705                                        .parseInt(currentMessage.getParameter(param));
706                        WindowTreeNode node = WindowTree.getInstance().find(paramHwnd);
707                        if (node != null) {
708                                currentMessage.addParameter(storeParam,
709                                                node.xmlRepresentation());
710                        }
711                }
712        }
713
714}
Note: See TracBrowser for help on using the repository browser.