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

Last change on this file since 581 was 581, checked in by sherbold, 12 years ago
  • some updates to the assembly configuration
  • moved MFC plugin code from quest-ui-core to quest-plugin-mfc
File size: 6.6 KB
Line 
1package de.ugoe.cs.quest.plugin.mfc;
2
3import java.util.LinkedList;
4import java.util.List;
5
6import de.ugoe.cs.quest.eventcore.Event;
7import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage;
8import de.ugoe.cs.util.console.Console;
9
10/**
11 * <p>
12 * Responsible to split sequences into subsequences, such that each subsequences
13 * contains exactly one event.
14 * </p>
15 *
16 * @author Steffen Herbold
17 * @version 1.0
18 */
19public class SequenceSplitter {
20
21        /**
22         * <p>
23         * Contains the current subsequence.
24         * </p>
25         */
26        private List<WindowsMessage> currentSequence;
27
28        /**
29         * <p>
30         * Number of messages in the current sequences, that signal that a key or
31         * mouse button has been pressed down to which not yet a message has been
32         * found, that signals that the button has been released.
33         * </p>
34         */
35        private int openDowns;
36
37        /**
38         * <p>
39         * Internal flag that signals if {@link #currentSequence} needs to be
40         * initialized.
41         * </p>
42         */
43        private boolean initMessages;
44
45        /**
46         * <p>
47         * The {@link EventGenerator} used to convert the subsequences into
48         * {@link Event}s
49         * </p>
50         */
51        private EventGenerator tokenGenerator;
52
53        /**
54         * <p>
55         * The event sequence generated.
56         * </p>
57         */
58        private List<Event> actionSequence;
59
60        /**
61         * <p>
62         * Type of the previous message.
63         * </p>
64         */
65        private int prevMsg = 0;
66
67        /**
68         * <p>
69         * Constructor. Creates a new SequenceSplitter.
70         * </p>
71         */
72        public SequenceSplitter() {
73                currentSequence = new LinkedList<WindowsMessage>();
74                openDowns = 0;
75                initMessages = true;
76                tokenGenerator = new EventGenerator();
77                actionSequence = new LinkedList<Event>();
78                prevMsg = 0;
79        }
80
81        /**
82         * <p>
83         * Called by the {@link MFCLogParser} every time a message is parsed.
84         * </p>
85         *
86         * @param msg
87         *            message to be added
88         */
89        public void addMessage(WindowsMessage msg) {
90                if (startOfSequence(msg)) {
91                        if (!initMessages) {
92                                Event currentAction = tokenGenerator
93                                                .generateEvent(currentSequence);
94                                if (currentAction != null) {
95                                        actionSequence.add(currentAction);
96                                }
97                                if (isKeyMessage(msg.getType()) && openDowns > 0) {
98                                        Console.traceln("Key message found with open down mouse messages - will probabably result in a faulty sequence.");
99                                }
100                        } else {
101                                initMessages = false;
102                        }
103                        currentSequence = new LinkedList<WindowsMessage>();
104                }
105                if (isUpMessage(msg.getType())) {
106                        if (openDowns > 0) {
107                                openDowns--;
108                        }
109                }
110
111                // this fix checks if there are two consecutive mouse-down messages.
112                // This sometimes occurs due to incorrect filtering in the monitoring
113                // dll.
114                if (!(prevMsg == MessageDefs.WM_LBUTTONDOWN && prevMsg == msg.getType())) {
115                        currentSequence.add(msg);
116                } else {
117                        openDowns--;
118                }
119                prevMsg = msg.getType();
120        }
121
122        /**
123         * <p>
124         * Returns the event sequence generated from the message that have been
125         * added.
126         * </p>
127         *
128         * @return generated event sequence
129         */
130        public List<Event> getSequence() {
131                return actionSequence;
132        }
133
134        /**
135         * <p>
136         * Called when a session in the log file is finished, i.e., a closing
137         * session-node is found.
138         * </p>
139         */
140        public void endSession() {
141                Event currentAction = tokenGenerator
142                                .generateEvent(currentSequence);
143                if (currentAction != null) {
144                        actionSequence.add(currentAction);
145                }
146        }
147
148        /**
149         * <p>
150         * Checks if the message starts a new subsequence and returns the result.
151         * </p>
152         *
153         * @param msg
154         *            message that is checked
155         * @return true, if a new subsequence begins
156         */
157        private boolean startOfSequence(WindowsMessage msg) {
158                boolean isStart = false;
159                int msgType = msg.getType();
160                if (isKeyMessage(msgType)) {
161                        isStart = true;
162                }
163                if (isDownMessage(msgType)) {
164                        openDowns++;
165                        if (openDowns == 1) {
166                                isStart = true;
167                        }
168                }
169                if (isDblclkMessage(msgType)) {
170                        openDowns++;
171                }
172                return isStart;
173        }
174
175        /**
176         * <p>
177         * Checks if the type of a message is generated is a keyboard interaction.
178         * </p>
179         *
180         * @param msgType
181         *            type of the message
182         * @return true if it is a keyboard interaction; false otherwise
183         */
184        private boolean isKeyMessage(int msgType) {
185                boolean isKeyMsg = false;
186                switch (msgType) {
187                case MessageDefs.WM_KEYDOWN:
188                case MessageDefs.WM_KEYUP:
189                case MessageDefs.WM_SYSKEYDOWN:
190                case MessageDefs.WM_SYSKEYUP:
191                        isKeyMsg = true;
192                        break;
193                default:
194                        break;
195                }
196                return isKeyMsg;
197        }
198
199        /**
200         * <p>
201         * Checks if the type of a message indicates that the mouse has been pressed
202         * down.
203         * </p>
204         *
205         * @param msgType
206         *            type of the message
207         * @return true if it is mouse-down message; false otherwise
208         */
209        private boolean isDownMessage(int msgType) {
210                boolean isDownMsg = false;
211                switch (msgType) {
212                case MessageDefs.WM_LBUTTONDOWN:
213                case MessageDefs.WM_RBUTTONDOWN:
214                case MessageDefs.WM_MBUTTONDOWN:
215                case MessageDefs.WM_XBUTTONDOWN:
216                case MessageDefs.WM_NCLBUTTONDOWN:
217                case MessageDefs.WM_NCRBUTTONDOWN:
218                case MessageDefs.WM_NCMBUTTONDOWN:
219                case MessageDefs.WM_NCXBUTTONDOWN:
220                        isDownMsg = true;
221                        break;
222                default:
223                        break;
224                }
225                return isDownMsg;
226        }
227
228        /**
229         * <p>
230         * Checks if the type of a message indicates that a double click has been
231         * performed.
232         * </p>
233         *
234         * @param msgType
235         *            type of the message
236         * @return true if it is a double click message; false otherwise
237         */
238        private boolean isDblclkMessage(int msgType) {
239                boolean isDblclkMsg = false;
240                switch (msgType) {
241                case MessageDefs.WM_LBUTTONDBLCLK:
242                case MessageDefs.WM_RBUTTONDBLCLK:
243                case MessageDefs.WM_MBUTTONDBLCLK:
244                case MessageDefs.WM_XBUTTONDBLCLK:
245                case MessageDefs.WM_NCLBUTTONDBLCLK:
246                case MessageDefs.WM_NCRBUTTONDBLCLK:
247                case MessageDefs.WM_NCMBUTTONDBLCLK:
248                case MessageDefs.WM_NCXBUTTONDBLCLK:
249                        isDblclkMsg = true;
250                        break;
251                default:
252                        break;
253                }
254                return isDblclkMsg;
255        }
256
257        /**
258         * <p>
259         * Checks if the type of a message indicates that the mouse has been
260         * released.
261         * </p>
262         *
263         * @param msgType
264         *            type of the message
265         * @return true if it is mouse-up message; false otherwise
266         */
267        private boolean isUpMessage(int msgType) {
268                boolean isUpMsg = false;
269                switch (msgType) {
270                case MessageDefs.WM_LBUTTONUP:
271                case MessageDefs.WM_RBUTTONUP:
272                case MessageDefs.WM_MBUTTONUP:
273                case MessageDefs.WM_XBUTTONUP:
274                case MessageDefs.WM_NCLBUTTONUP:
275                case MessageDefs.WM_NCRBUTTONUP:
276                case MessageDefs.WM_NCMBUTTONUP:
277                case MessageDefs.WM_NCXBUTTONUP:
278                        isUpMsg = true;
279                        break;
280                default:
281                        break;
282                }
283                return isUpMsg;
284        }
285
286}
Note: See TracBrowser for help on using the repository browser.