package de.ugoe.cs.quest.plugin.mfc; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import de.ugoe.cs.quest.eventcore.Event; import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage; import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessageType; import de.ugoe.cs.quest.plugin.mfc.guimodel.WindowTree; import de.ugoe.cs.util.console.Console; /** *

* Responsible to split sequences into subsequences, such that each subsequences contains exactly * one event. *

* * @author Steffen Herbold * @version 1.0 */ public class SequenceSplitter { /** *

* Contains the current subsequence. *

*/ private List currentSequence; /** *

* Number of messages in the current sequences, that signal that a key or mouse button has been * pressed down to which not yet a message has been found, that signals that the button has been * released. *

*/ private int openDowns; /** *

* Internal flag that signals if {@link #currentSequence} needs to be initialized. *

*/ private boolean initMessages; /** *

* The {@link EventGenerator} used to convert the subsequences into {@link Event}s *

*/ private EventGenerator tokenGenerator; /** *

* The event sequence generated. *

*/ private List actionSequence; /** *

* Type of the previous message. *

*/ private WindowsMessageType prevMsg; /** *

* Constructor. Creates a new SequenceSplitter. *

*/ public SequenceSplitter(WindowTree windowTree) { currentSequence = new LinkedList(); openDowns = 0; initMessages = true; tokenGenerator = new EventGenerator(windowTree); actionSequence = new LinkedList(); prevMsg = null; } /** *

* Called by the {@link MFCLogParser} every time a message is parsed. *

* * @param msg * message to be added */ public void addMessage(WindowsMessage msg) { if (startOfSequence(msg)) { if (!initMessages) { Event currentAction = tokenGenerator.generateEvent(currentSequence); if (currentAction != null) { actionSequence.add(currentAction); } if (msg.getType().isKeyMessage() && openDowns > 0) { Console.traceln(Level.SEVERE, "Key message found with open down mouse " + "messages - will probabably result in a faulty sequence."); } } else { initMessages = false; } currentSequence = new LinkedList(); } if (msg.getType().isUpMessage()) { if (openDowns > 0) { openDowns--; } } // this fix checks if there are two consecutive mouse-down messages. // This sometimes occurs due to incorrect filtering in the monitoring // dll. if (!(prevMsg == WindowsMessageType.WM_LBUTTONDOWN && prevMsg == msg.getType())) { currentSequence.add(msg); } else { openDowns--; } prevMsg = msg.getType(); } /** *

* Returns the event sequence generated from the message that have been added. *

* * @return generated event sequence */ public List getSequence() { return actionSequence; } /** *

* Called when a session in the log file is finished, i.e., a closing session-node is found. *

*/ public void endSession() { Event currentAction = tokenGenerator.generateEvent(currentSequence); if (currentAction != null) { actionSequence.add(currentAction); } } /** *

* Checks if the message starts a new subsequence and returns the result. *

* * @param msg * message that is checked * @return true, if a new subsequence begins */ private boolean startOfSequence(WindowsMessage msg) { boolean isStart = false; WindowsMessageType msgType = msg.getType(); if (msgType.isKeyMessage()) { isStart = true; } if (msgType.isDownMessage()) { openDowns++; if (openDowns == 1) { isStart = true; } } if (msgType.isDblclkMessage()) { openDowns++; } return isStart; } }