source: trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerationRule.java @ 655

Last change on this file since 655 was 655, checked in by pharms, 12 years ago
  • removed old copyright file header
File size: 19.3 KB
Line 
1package de.ugoe.cs.quest.plugin.mfc;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import org.jdom.Element;
7import org.jdom.Namespace;
8
9import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessageType;
10
11/**
12 * <p>
13 * TODO comment
14 * </p>
15 *
16 * @version $Revision: $ $Date: 22.08.2012$
17 * @author 2012, last modified by $Author: patrick$
18 */
19class EventGenerationRule {
20
21    /**
22     * <p>
23     * the namespace used for parsing the rule
24     * </p>
25     */
26    private Namespace namespace;
27
28    /**
29     * <p>
30     * the name of the rule
31     * </p>
32     */
33    private String name;
34
35    /**
36     * <p>
37     * the list of conditions for the rule to be matched
38     * </p>
39     */
40    private List<MessageCondition> messageConditions;
41
42    /**
43     * <p>
44     * the list of parameters to be provided to the generated event
45     * </p>
46     */
47    private List<Term> eventParameters;
48
49    /**
50     * <p>
51     * the list of replay message generation rules
52     * </p>
53     */
54    private List<ReplayMessageSpec> replayMessageSpecifications;
55
56    /**
57     * <p>
58     * TODO: comment
59     * </p>
60     *
61     * @param ruleElement
62     * @param rulesNamespace
63     */
64    @SuppressWarnings("unchecked")
65    EventGenerationRule(Element ruleElement, Namespace rulesNamespace) {
66        this.namespace = rulesNamespace;
67       
68        this.name = ruleElement.getAttributeValue("name");
69       
70        this.messageConditions = new ArrayList<MessageCondition>();
71        this.eventParameters = new ArrayList<Term>();
72        this.replayMessageSpecifications = new ArrayList<ReplayMessageSpec>();
73       
74        for (Element child : (List<Element>) ruleElement.getChildren()) {
75            if ("msg".equals(child.getName()) && namespace.equals(child.getNamespace())) {
76                messageConditions.add(new MessageCondition(child));
77            }
78            else if ("idinfo".equals(child.getName()) && namespace.equals(child.getNamespace())) {
79                for (Element parameterElements : (List<Element>) child.getChildren()) {
80                    eventParameters.add(new Term(parameterElements));
81                }
82            }
83            else if ("genMsg".equals(child.getName()) && namespace.equals(child.getNamespace())) {
84                replayMessageSpecifications.add(new ReplayMessageSpec(child));
85            }
86            else if ("genMsgSeq".equals(child.getName()) && namespace.equals(child.getNamespace())) {
87                replayMessageSpecifications.add(new ReplayMessageSpec(child));
88            }
89            else {
90                throw new IllegalArgumentException
91                    ("the provided rules can not be parsed: unknown element " + child.getName());
92            }
93        }
94    }
95
96    /**
97     * @return the name
98     */
99    String getName() {
100        return name;
101    }
102
103    /**
104     * <p>
105     * TODO: comment
106     * </p>
107     *
108     * @return
109     */
110    List<MessageCondition> getMessageConditions() {
111        return messageConditions;
112    }
113
114    /**
115     * <p>
116     * TODO: comment
117     * </p>
118     *
119     * @return
120     */
121    List<Term> getEventParameters() {
122        return eventParameters;
123    }
124
125    /**
126     * <p>
127     * TODO: comment
128     * </p>
129     *
130     * @return
131     */
132    List<ReplayMessageSpec> getReplayMessageSpecifications() {
133        return replayMessageSpecifications;
134    }
135
136    /**
137     * <p>
138     * TODO comment
139     * </p>
140     *
141     * @version $Revision: $ $Date: 22.08.2012$
142     * @author 2012, last modified by $Author: patrick$
143     */
144    class MessageCondition {
145
146        /**
147         * <p>
148         * true, if the condition defines to match several conditions
149         * </p>
150         */
151        private boolean matchMultiple;
152       
153        /**
154         * <p>
155         * the type of the message matched by the condition
156         * </p>
157         */
158        private WindowsMessageType messageType;
159
160        /**
161         * <p>
162         * the term conditions associate with the rule condition
163         * </p>
164         */
165        private List<AttributeCondition> attributeConditions;
166
167        /**
168         * <p>
169         * the list of messages to be stored, if the message matches, for continuing the
170         * rule application
171         * </p>
172         */
173        private ArrayList<Term> messagesToStore;
174
175        /**
176         * <p>
177         * TODO: comment
178         * </p>
179         *
180         * @param msgChild
181         */
182        @SuppressWarnings("unchecked")
183        private MessageCondition(Element msgChild) {
184            this.matchMultiple = "true".equals(msgChild.getAttributeValue("multiple"));
185            this.messageType =
186                WindowsMessageType.parseMessageType(msgChild.getAttributeValue("type"));
187           
188            this.attributeConditions = new ArrayList<AttributeCondition>();
189            for (Element childElement : (List<Element>) msgChild.getChildren("equals", namespace)) {
190                attributeConditions.add(new AttributeCondition(childElement));
191            }
192           
193            this.messagesToStore = new ArrayList<Term>();
194            for (Element childElement : (List<Element>) msgChild.getChildren("store", namespace)) {
195                messagesToStore.add(new Term(childElement));
196            }
197            for (Element childElement :
198                 (List<Element>) msgChild.getChildren("storeSeq", namespace))
199            {
200                messagesToStore.add(new Term(childElement));
201            }
202        }
203
204        /**
205         * @return the matchMultiple
206         */
207        boolean matchMultiple() {
208            return matchMultiple;
209        }
210
211        /**
212         * <p>
213         * TODO: comment
214         * </p>
215         *
216         * @return
217         */
218        WindowsMessageType getMessageType() {
219            return messageType;
220        }
221
222        /**
223         * <p>
224         * TODO: comment
225         * </p>
226         *
227         * @return
228         */
229        List<AttributeCondition> getAttributeConditions() {
230            return attributeConditions;
231        }
232
233        /**
234         * @return the valuesToStore
235         */
236        ArrayList<Term> getMessagesToStore() {
237            return messagesToStore;
238        }
239
240    }
241
242    /**
243     * <p>
244     * TODO comment
245     * </p>
246     *
247     * @version $Revision: $ $Date: 22.08.2012$
248     * @author 2012, last modified by $Author: patrick$
249     */
250    class AttributeCondition {
251
252        /**
253         * <p>
254         * the left hand side of the condition
255         * </p>
256         */
257        private Term leftHandSide;
258       
259        /**
260         * <p>
261         * the left hand side of the condition
262         * </p>
263         */
264        private Term rightHandSide;
265
266        /**
267         * <p>
268         * TODO: comment
269         * </p>
270         *
271         * @param childElement
272         */
273        private AttributeCondition(Element conditionElement) {
274            this.leftHandSide = new Term((Element) conditionElement.getChildren().get(0));
275            this.rightHandSide = new Term((Element) conditionElement.getChildren().get(1));
276        }
277       
278        /**
279         * @return the leftHandSide
280         */
281        Term getLeftHandSide() {
282            return leftHandSide;
283        }
284
285        /**
286         * @return the rightHandSide
287         */
288        Term getRightHandSide() {
289            return rightHandSide;
290        }
291
292    }
293
294    /**
295     * <p>
296     * TODO comment
297     * </p>
298     *
299     * @version $Revision: $ $Date: 22.08.2012$
300     * @author 2012, last modified by $Author: patrick$
301     */
302    class Term {
303
304        /**
305         * <p>
306         * the name of the term
307         * </p>
308         */
309        private String name;
310       
311        /**
312         * <p>
313         * the value of the term, if it is a constValue, null instead
314         * </p>
315         */
316        private String value;
317
318        /**
319         * <p>
320         * the variable name of the object, i.e. a message, of which a parameter is identified if
321         * the term is a winInfoValue or a msgInfoValue; null instead
322         * </p>
323         */
324        private String messageId;
325
326        /**
327         * <p>
328         * the name of the parameter of the object, e.g. a message, of which a parameter is
329         * identified if the term is a paramValue, null instead
330         * </p>
331         */
332        private String messageParameterName;
333
334        /**
335         * <p>
336         * the variable name of the message sequence denoted by the term in case of a seqValue;
337         * null instead
338         * </p>
339         */
340        private String sequenceId;
341
342        /**
343         * <p>
344         * the name of the parameter of the sequence of which a parameter is
345         * identified if the term is a seqValue, null instead
346         * </p>
347         */
348        private String sequenceParameterName;
349
350        /**
351         * <p>
352         * the name of the parameter of the window of the object, e.g. a message, of which a
353         * parameter is identified if the term is a winInfoValue, null instead
354         * </p>
355         */
356        private String windowParameterName;
357
358        /**
359         * <p>
360         * the name of the info of the message of which a parameter is identified if the
361         * term is a msgInfoValue, null instead
362         * </p>
363         */
364        private String messageInfoName;
365
366        /**
367         * <p>
368         * the name of the parameter of the message into which a value shall be stored if the
369         * term is a resolveHwnd, null instead
370         * </p>
371         */
372        private String storeParameterName;
373
374        /**
375         * <p>
376         * the list of handles to be resolved in case the term is a store or storeSeq, null instead
377         * </p>
378         */
379        private List<Term> resolveHandles;
380
381        /**
382         * <p>
383         * TODO: comment
384         * </p>
385         *
386         * @param object
387         */
388        @SuppressWarnings("unchecked")
389        private Term(Element termElement) {
390            this.name = termElement.getName();
391           
392            if ("constValue".equals(name)) {
393                this.value = termElement.getAttributeValue("value");
394            }
395            else if ("paramValue".equals(name)) {
396                this.messageId = termElement.getAttributeValue("obj");
397                this.messageParameterName = termElement.getAttributeValue("param");
398            }
399            else if ("winInfoValue".equals(name)) {
400                this.messageId = termElement.getAttributeValue("obj");
401                this.windowParameterName = termElement.getAttributeValue("winParam");
402            }
403            else if ("msgInfoValue".equals(name)) {
404                this.messageId = termElement.getAttributeValue("obj");
405                this.messageInfoName = termElement.getAttributeValue("msgParam");
406            }
407            else if ("seqValue".equals(name)) {
408                this.sequenceId = termElement.getAttributeValue("seqObj");
409                this.sequenceParameterName = termElement.getAttributeValue("param");
410            }
411            else if ("store".equals(name)) {
412                this.messageId = termElement.getAttributeValue("var");
413                if ((termElement.getChildren() != null) && (termElement.getChildren().size() > 0)) {
414                    this.resolveHandles = new ArrayList<Term>();
415                    for (Element child : (List<Element>) termElement.getChildren()) {
416                        this.resolveHandles.add(new Term(child));
417                    }
418                }
419            }
420            else if ("storeSeq".equals(name)) {
421                this.sequenceId = termElement.getAttributeValue("varSeq");
422                if ((termElement.getChildren() != null) && (termElement.getChildren().size() > 0)) {
423                    this.resolveHandles = new ArrayList<Term>();
424                    for (Element child : (List<Element>) termElement.getChildren()) {
425                        this.resolveHandles.add(new Term(child));
426                    }
427                }
428            }
429            else if ("resolveHwnd".equals(name)) {
430                this.messageParameterName = termElement.getAttributeValue("param");
431                this.storeParameterName = termElement.getAttributeValue("storeParam");
432            }
433        }
434
435        /**
436         * @return the name
437         */
438        String getName() {
439            return name;
440        }
441
442        /**
443         * @return the value
444         */
445        String getValue() {
446            return value;
447        }
448
449        /**
450         * @return the object
451         */
452        String getMessageId() {
453            return messageId;
454        }
455
456        /**
457         * @return the objectParameter
458         */
459        String getMessageParameterName() {
460            return messageParameterName;
461        }
462
463        /**
464         * @return the sequenceId
465         */
466        String getSequenceId() {
467            return sequenceId;
468        }
469
470        /**
471         * @return the sequenceParameter
472         */
473        String getSequenceParameterName() {
474            return sequenceParameterName;
475        }
476
477        /**
478         * @return the windowParameter
479         */
480        String getWindowParameterName() {
481            return windowParameterName;
482        }
483
484        /**
485         * @return the messageParameter
486         */
487        String getMessageInfoName() {
488            return messageInfoName;
489        }
490
491        /**
492         * @return the storeParameter
493         */
494        String getStoreParameterName() {
495            return storeParameterName;
496        }
497
498        /**
499         * @return the resolveHandles
500         */
501        List<Term> getResolveHandles() {
502            return resolveHandles;
503        }
504
505    }
506   
507    /**
508     * <p>
509     * TODO comment
510     * </p>
511     *
512     * @version $Revision: $ $Date: 22.08.2012$
513     * @author 2012, last modified by $Author: patrick$
514     */
515    class ReplayMessageSpec {
516
517        /**
518         * <p>
519         * determines, if this specification defines one, or a sequence of messages
520         * </p>
521         */
522        private boolean generateSingleMessage;
523       
524        /**
525         * <p>
526         * the id of a concrete message of message sequence to be replayed as is
527         * </p>
528         */
529        private String replayObjectId;
530
531        private Term type;
532
533        private Term target;
534
535        private Term lparamLoWord;
536
537        private Term lparamHiWord;
538
539        private Term lparam;
540
541        private Term wparamLoWord;
542
543        private Term wparamHiWord;
544
545        private Term wparam;
546
547        private int delay;
548       
549        /**
550         * <p>
551         * TODO: comment
552         * </p>
553         *
554         * @param child
555         */
556        @SuppressWarnings("unchecked")
557        private ReplayMessageSpec(Element replayMessageSpecElement) {
558            List<Element> children = replayMessageSpecElement.getChildren();
559            if ("genMsg".equals(replayMessageSpecElement.getName())) {
560                generateSingleMessage = true;
561                if (children.size() == 1) {
562                    replayObjectId = children.get(0).getAttributeValue("obj");
563                }
564            }
565            else {
566                generateSingleMessage = false;
567                if (children.size() == 1) {
568                    replayObjectId = children.get(0).getAttributeValue("seqObj");
569                }
570            }
571           
572            this.delay = Integer.parseInt(replayMessageSpecElement.getAttributeValue("delay"));
573           
574            if (children.size() > 1) {
575                for (Element child : children) {
576                    Element termElement = (Element) child.getChildren().get(0);
577                   
578                    if (child.getName().equals("type")) {
579                        this.type = new Term(termElement);
580                    }
581                    else if (child.getName().equals("target")) {
582                        this.target = new Term(termElement);
583                       
584                        if (!generateSingleMessage) {
585                            // in this case, the target is always a sequence value term, i.e.
586                            // the targets of the originally recorded sequence. So the
587                            // replay object id is set to this sequence
588                            replayObjectId = target.getSequenceId();
589                        }
590                    }
591                    else if (child.getName().equals("LPARAM")) {
592                        Element loWordElement = child.getChild("LOWORD", namespace);
593                        if (loWordElement != null) {
594                            this.lparamLoWord =
595                                new Term((Element) loWordElement.getChildren().get(0));
596                        }
597                       
598                        Element hiWordElement = child.getChild("HIWORD", namespace);
599                        if (hiWordElement != null) {
600                            this.lparamHiWord =
601                                 new Term((Element) hiWordElement.getChildren().get(0));
602                        }
603                       
604                        if ((lparamLoWord == null) && (lparamHiWord == null)) {
605                            this.lparam = new Term(termElement);
606                        }
607                    }
608                    else if (child.getName().equals("WPARAM")) {
609                        Element loWordElement = child.getChild("LOWORD", namespace);
610                        if (loWordElement != null) {
611                            this.wparamLoWord =
612                                new Term((Element) loWordElement.getChildren().get(0));
613                        }
614                       
615                        Element hiWordElement = child.getChild("HIWORD", namespace);
616                        if (hiWordElement != null) {
617                            this.wparamHiWord =
618                                 new Term((Element) hiWordElement.getChildren().get(0));
619                        }
620                       
621                        if ((wparamLoWord == null) && (wparamHiWord == null)) {
622                            this.wparam = new Term(termElement);
623                        }
624                    }
625                }
626            }
627        }
628
629        /**
630         * <p>
631         * TODO: comment
632         * </p>
633         *
634         * @return
635         */
636        boolean generateSingleMessage() {
637            return generateSingleMessage;
638        }
639
640        /**
641         * <p>
642         * TODO: comment
643         * </p>
644         *
645         * @return
646         */
647        String getReplayObjectId() {
648            return replayObjectId;
649        }
650
651        /**
652         * @return the type
653         */
654        Term getType() {
655            return type;
656        }
657
658        /**
659         * @return the target
660         */
661        Term getTarget() {
662            return target;
663        }
664
665        /**
666         * @return the lparamLoWord
667         */
668        Term getLparamLoWord() {
669            return lparamLoWord;
670        }
671
672        /**
673         * @return the lparamHiWord
674         */
675        Term getLparamHiWord() {
676            return lparamHiWord;
677        }
678
679        /**
680         * @return the lparam
681         */
682        Term getLparam() {
683            return lparam;
684        }
685
686        /**
687         * @return the wparamLoWord
688         */
689        Term getWparamLoWord() {
690            return wparamLoWord;
691        }
692
693        /**
694         * @return the wparamHiWord
695         */
696        Term getWparamHiWord() {
697            return wparamHiWord;
698        }
699
700        /**
701         * @return the wparam
702         */
703        Term getWparam() {
704            return wparam;
705        }
706
707        /**
708         * @return the delay
709         */
710        int getDelay() {
711            return delay;
712        }
713
714    }
715}
Note: See TracBrowser for help on using the repository browser.