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

Last change on this file since 23 was 18, checked in by sherbold, 14 years ago
  • removed all reference to de.ugoe.cs.eventbench.MarkovModel? and replaced them with de.ugoe.cs.eventbench.models.FirstOrderMarkovModel? and de.ugoe.cs.eventbench.models.IStochasticProcess
File size: 24.0 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                                }
549                        }
550                } else if (termElement.getName().equals("msgInfoValue")) {
551                        String objectName = termElement.getAttributeValue("obj");
552                        varMessage = getStoredMessageVariable(currentMessage, objectName);
553                        if (varMessage != null) {
554                                String paramString = termElement.getAttributeValue("msgParam");
555                                if (paramString.equals("type")) {
556                                        value = "" + varMessage.getType();
557                                } else if (paramString.equals("target")) {
558                                        value = varMessage.getXmlWindowDescription();
559                                }
560                        }
561                }
562                return value;
563        }
564
565        private List<String> getTermValueSeq(WindowsMessage currentMessage,
566                        Element termElement) {
567                List<String> values = new LinkedList<String>();
568                if (termElement.getName().equals("seqValue")) {
569                        String obj = termElement.getAttributeValue("seqObj");
570                        String param = termElement.getAttributeValue("param");
571                        List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
572
573                        for (WindowsMessage msg : seqVar) {
574                                // msg.getParameter returns null, if parameter is not found,
575                                // therefore the List can contain null-values
576                                values.add(msg.getParameter(param));
577                        }
578                }
579                return values;
580        }
581
582        @SuppressWarnings("unchecked")
583        private void handleStorage(Element messageElement,
584                        WindowsMessage currentMessage) {
585                for (Element childElement : (List<Element>) messageElement.getChildren(
586                                "store", rulesNamespace)) {
587                        String identifier = childElement.getAttributeValue("var");
588                        messageStorage.put(identifier, currentMessage);
589                        resolveHwnd(currentMessage, childElement);
590                }
591                for (Element childElement : (List<Element>) messageElement.getChildren(
592                                "storeSeq", rulesNamespace)) {
593                        String identifier = childElement.getAttributeValue("varSeq");
594                        Object tmp = messageStorage.get(identifier);
595                        List<WindowsMessage> storedSequence;
596                        if (tmp == null || tmp instanceof WindowsMessage) {
597                                storedSequence = new LinkedList<WindowsMessage>();
598                                storedSequence.add(currentMessage);
599                                messageStorage.put(identifier, storedSequence);
600                        } else if (tmp instanceof List<?>) {
601                                storedSequence = (List<WindowsMessage>) tmp;
602                                storedSequence.add(currentMessage);
603                                messageStorage.put(identifier, storedSequence);
604                        }
605                        resolveHwnd(currentMessage, childElement);
606                }
607        }
608
609        private boolean matchMultipleMessages(Element messageElement,
610                        Element nextMessageElement) {
611                boolean isMatch = false;
612                boolean isCurrentMatch = false;
613                boolean nextMatchFound = false;
614                WindowsMessage currentMessage = null;
615                WindowsMessage nextMessage = null;
616
617                int type = Integer.parseInt(messageElement.getAttributeValue("type"));
618
619                int nextType = -1;
620                if (nextMessageElement != null) {
621                        nextType = Integer.parseInt(nextMessageElement
622                                        .getAttributeValue("type"));
623                }
624
625                while (!nextMatchFound && sequenceIterator.hasNext()) {
626                        currentMessage = sequenceIterator.next();
627                        if (type == currentMessage.getType()) {
628                                isCurrentMatch = evalEqualRestrictions(currentMessage,
629                                                messageElement);
630                                isMatch = isMatch || isCurrentMatch;
631
632                                if (isCurrentMatch) {
633                                        handleStorage(messageElement, currentMessage);
634                                        currentToken.setTarget(currentMessage
635                                                        .getXmlWindowDescription());
636                                        currentToken
637                                                        .setTargetShort(currentMessage.getParentNames());
638                                }
639                        }
640                        if (nextMessageElement != null && isMatch) {
641                                // peek next message to check if the sequence ends and the next
642                                // match is found
643                                if (!sequenceIterator.hasNext()) {
644                                        return false; // sequence is over, but not all messages are
645                                                                        // found
646                                }
647                                nextMessage = sequenceIterator.next();
648                                sequenceIterator.previous();
649
650                                if (nextType == nextMessage.getType()) {
651                                        nextMatchFound = evalEqualRestrictions(nextMessage,
652                                                        nextMessageElement);
653                                }
654
655                        }
656                }
657
658                return isMatch;
659        }
660
661        private boolean matchSingleMessage(Element messageElement) {
662                boolean isMatch = false;
663                WindowsMessage currentMessage = null;
664
665                int type = Integer.parseInt(messageElement.getAttributeValue("type"));
666
667                while (!isMatch && sequenceIterator.hasNext()) {
668                        // traverses the messages from the current position forward till a
669                        // message with the correct type is found
670                        currentMessage = sequenceIterator.next();
671                        if (type == currentMessage.getType()) {
672                                // message with the correct type found
673                                // eval child nodes for further matching/storing
674                                isMatch = evalEqualRestrictions(currentMessage, messageElement);
675
676                                // in case the message is a match, eval storage children
677                                if (isMatch) {
678                                        handleStorage(messageElement, currentMessage);
679                                        currentToken.setTarget(currentMessage
680                                                        .getXmlWindowDescription());
681                                        currentToken
682                                                        .setTargetShort(currentMessage.getParentNames());
683                                }
684                        }
685                }
686
687                return isMatch;
688        }
689
690        @SuppressWarnings("unchecked")
691        private void resolveHwnd(WindowsMessage currentMessage, Element childElement) {
692                List<Element> resolveElements = childElement.getChildren("resolveHwnd",
693                                rulesNamespace);
694                for (Element resolveElement : resolveElements) {
695                        String param = resolveElement.getAttributeValue("param");
696                        String storeParam = resolveElement.getAttributeValue("storeParam");
697                        int paramHwnd = Integer
698                                        .parseInt(currentMessage.getParameter(param));
699                        WindowTreeNode node = WindowTree.getInstance().find(paramHwnd);
700                        if (node != null) {
701                                currentMessage.addParameter(storeParam,
702                                                node.xmlRepresentation());
703                        }
704                }
705        }
706
707}
Note: See TracBrowser for help on using the repository browser.