source: trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.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: 7.7 KB
RevLine 
[434]1package de.ugoe.cs.quest.plugin.mfc;
[1]2
3import java.io.File;
[45]4import java.io.FileInputStream;
[1]5import java.io.FileNotFoundException;
6import java.io.IOException;
[45]7import java.io.InputStreamReader;
[1]8import java.security.InvalidParameterException;
[203]9import java.util.Collection;
[1]10import java.util.LinkedList;
11import java.util.List;
12import java.util.SortedMap;
13import java.util.TreeMap;
14
15import javax.xml.parsers.ParserConfigurationException;
16import javax.xml.parsers.SAXParser;
17import javax.xml.parsers.SAXParserFactory;
18
19import org.xml.sax.Attributes;
20import org.xml.sax.InputSource;
21import org.xml.sax.SAXException;
22import org.xml.sax.SAXParseException;
23import org.xml.sax.helpers.DefaultHandler;
24
[566]25import de.ugoe.cs.quest.eventcore.Event;
[434]26import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
27import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage;
[1]28import de.ugoe.cs.util.StringTools;
29import de.ugoe.cs.util.console.Console;
30
[171]31/**
32 * <p>
33 * This class provides functionality to parse XML log files generated by the
34 * MFCUsageMonitor of EventBench. The result of parsing a file is a collection
35 * of event sequences. It uses the {@link SequenceSplitter} and the
36 * {@link EventGenerator} as well as custom defined {@link MessageHandler} for
37 * the parsing.
38 * </p>
39 *
40 * @author Steffen Herbold
41 * @version 1.0
42 */
[297]43public class MFCLogParser extends DefaultHandler {
[171]44
45        /**
46         * <p>
47         * If a custom message handler is used, this field contains its handle.
48         * Otherwise this field is {@code null}.
49         * </p>
50         */
[1]51        private MessageHandler currentHandler;
[171]52
53        /**
54         * <p>
55         * Handle to the message that is currently parsed.
56         * </p>
57         */
[1]58        private WindowsMessage currentMessage;
[171]59
60        /**
61         * <p>
[297]62         * {@link SequenceSplitter} instance used by the {@link MFCLogParser}.
[171]63         * </p>
64         */
[1]65        private SequenceSplitter sequenceSplitter;
[171]66
67        /**
68         * <p>
69         * Collection of event sequences that is contained in the log file, which is
70         * parsed.
71         * </p>
72         */
[566]73        private Collection<List<Event>> sequences;
[171]74
75        /**
76         * <p>
77         * Debugging variable that allows the analysis which message type occurs how
78         * often in the log file. Can be used to enhance the message filter.
79         * </p>
80         */
[1]81        private SortedMap<Integer, Integer> typeCounter;
[171]82
83        /**
84         * <p>
85         * Debugging variable that enables the counting of the occurrences of each
86         * message. Used in combination with {@link #typeCounter}.
87         * </p>
88         */
[1]89        private boolean countMessageOccurences;
[171]90
91        /**
92         * <p>
93         * Constructor. Creates a new LogParser that does not count message
94         * occurrences.
95         * </p>
96         */
[297]97        public MFCLogParser() {
[1]98                this(false);
99        }
[171]100
101        /**
102         * <p>
103         * Constructor. Creates a new LogParser.
104         * </p>
105         *
106         * @param countMessageOccurences
107         *            if true, the occurrences of each message type in the log is
108         *            counted.
109         */
[297]110        public MFCLogParser(boolean countMessageOccurences) {
[1]111                sequenceSplitter = new SequenceSplitter();
[566]112                sequences = new LinkedList<List<Event>>();
[1]113                currentHandler = null;
114                this.countMessageOccurences = countMessageOccurences;
[171]115                if (countMessageOccurences) {
[1]116                        typeCounter = new TreeMap<Integer, Integer>();
117                }
[171]118
[1]119        }
[171]120
121        /**
122         * <p>
123         * Returns the collection of event sequences that is obtained from parsing
124         * log files.
125         * </p>
126         *
127         * @return collection of event sequences
128         */
[566]129        public Collection<List<Event>> getSequences() {
[1]130                return sequences;
131        }
[171]132
133        /*
134         * (non-Javadoc)
135         *
136         * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
137         * java.lang.String, java.lang.String, org.xml.sax.Attributes)
138         */
[1]139        @Override
[171]140        public void startElement(String uri, String localName, String qName,
141                        Attributes atts) throws SAXException {
142                if (qName.equals("session")) {
[1]143                        Console.traceln("start of session");
144                        sequenceSplitter = new SequenceSplitter();
[171]145                } else if (qName.equals("msg")) {
[1]146                        String msgType = atts.getValue("type");
147                        int msgInt = -1;
148                        try {
149                                msgInt = Integer.parseInt(msgType);
[171]150
151                                if (countMessageOccurences) {
[1]152                                        Integer currentCount = typeCounter.get(msgInt);
[171]153                                        if (currentCount == null) {
[1]154                                                typeCounter.put(msgInt, 1);
155                                        } else {
[171]156                                                typeCounter.put(msgInt, currentCount + 1);
[1]157                                        }
158                                }
[171]159
160                                if (msgInt == MessageDefs.WM_CREATE) {
[1]161                                        currentHandler = new HandlerCreate();
162                                        currentHandler.onStartElement();
[171]163                                } else if (msgInt == MessageDefs.WM_DESTROY) {
[1]164                                        currentHandler = new HandlerDestroy();
165                                        currentHandler.onStartElement();
[171]166                                } else if (msgInt == MessageDefs.WM_SETTEXT) {
[1]167                                        currentHandler = new HandlerSetText();
168                                        currentHandler.onStartElement();
169                                } else {
170                                        currentMessage = new WindowsMessage(msgInt);
171                                }
[171]172                        } catch (NumberFormatException e) {
[4]173                                Console.printerrln("Invalid message type: type not a number");
[1]174                                e.printStackTrace();
175                        }
[171]176                } else if (qName.equals("param")) {
177                        if (currentHandler != null) {
178                                currentHandler.onParameter(atts.getValue("name"),
179                                                atts.getValue("value"));
[1]180                        } else {
[171]181                                currentMessage.addParameter(atts.getValue("name"),
182                                                atts.getValue("value"));
[1]183                        }
184                }
185        }
[171]186
187        /*
188         * (non-Javadoc)
189         *
190         * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
191         * java.lang.String, java.lang.String)
192         */
[1]193        @Override
[171]194        public void endElement(String uri, String localName, String qName)
195                        throws SAXException {
196                if (qName.equals("msg")) {
197                        if (currentHandler != null) {
[1]198                                currentHandler.onEndElement();
199                                currentHandler = null;
200                        } else {
201                                try {
202                                        currentMessage.setTarget(WindowTree.getInstance());
203                                        sequenceSplitter.addMessage(currentMessage);
204                                } catch (InvalidParameterException e) {
[171]205                                        Console.traceln(e.getMessage() + " WindowsMessage "
206                                                        + currentMessage + " ignored.");
207                                }
[1]208                        }
[171]209                } else if (qName.equals("session")) {
[1]210                        sequenceSplitter.endSession();
[566]211                        List<Event> seq = sequenceSplitter.getSequence();
[403]212                        if( seq!=null && !seq.isEmpty() ) {
213                                sequences.add(seq);
214                        }
[1]215                        Console.traceln("end of session");
216                }
217        }
[171]218
219        /**
220         * <p>
[297]221         * Parses a given log file created by the MFCMonitor and adds its contents
222         * to the collection of event sequences.
[171]223         * </p>
224         *
225         * @param filename
226         *            name and path of the log file
227         */
[1]228        public void parseFile(String filename) {
[171]229                if (filename == null) {
[1]230                        throw new InvalidParameterException("filename must not be null");
231                }
[171]232
[1]233                SAXParserFactory spf = SAXParserFactory.newInstance();
234                spf.setValidating(true);
[171]235
[1]236                SAXParser saxParser = null;
237                InputSource inputSource = null;
238                try {
239                        saxParser = spf.newSAXParser();
[171]240                        inputSource = new InputSource(new InputStreamReader(
[418]241                                        new FileInputStream(filename)));//, "UTF-8"));
242                //} catch (UnsupportedEncodingException e) {
243                //      e.printStackTrace();
[1]244                } catch (ParserConfigurationException e) {
245                        e.printStackTrace();
246                } catch (SAXException e) {
247                        e.printStackTrace();
248                } catch (FileNotFoundException e) {
249                        e.printStackTrace();
250                }
[171]251                if (inputSource != null) {
252                        inputSource.setSystemId("file://"
253                                        + new File(filename).getAbsolutePath());
254                        try {
255                                if (saxParser == null) {
256                                        throw new RuntimeException("SAXParser creation failed");
257                                }
[1]258                                saxParser.parse(inputSource, this);
[171]259                        } catch (SAXParseException e) {
260                                Console.printerrln("Failure parsing file in line "
261                                                + e.getLineNumber() + ", column " + e.getColumnNumber()
262                                                + ".");
263                                e.printStackTrace();
[1]264                        } catch (SAXException e) {
265                                e.printStackTrace();
266                        } catch (IOException e) {
267                                e.printStackTrace();
268                        }
269                }
[171]270                if (countMessageOccurences) {
[1]271                        Console.println("Message statistics:");
[171]272                        Console.println(typeCounter.toString()
273                                        .replace(" ", StringTools.ENDLINE)
274                                        .replaceAll("[\\{\\}]", ""));
[1]275                }
276        }
277}
Note: See TracBrowser for help on using the repository browser.