source: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/NewHTMLLogParser.java @ 1051

Last change on this file since 1051 was 1051, checked in by pharms, 11 years ago
  • renamed usageObserved to isUsed
  • renamed markAsUsed to markUsed
  • added markUsed to default GUI element interface
  • Property svn:mime-type set to text/plain
File size: 11.2 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.html;
16
17import java.io.File;
18import java.io.FileInputStream;
19import java.io.FileNotFoundException;
20import java.io.IOException;
21import java.io.InputStreamReader;
22import java.io.UnsupportedEncodingException;
23import java.util.Collection;
24import java.util.HashMap;
25import java.util.LinkedList;
26import java.util.List;
27import java.util.Map;
28
29import javax.xml.parsers.ParserConfigurationException;
30import javax.xml.parsers.SAXParser;
31import javax.xml.parsers.SAXParserFactory;
32
33import org.xml.sax.Attributes;
34import org.xml.sax.InputSource;
35import org.xml.sax.SAXException;
36import org.xml.sax.SAXParseException;
37import org.xml.sax.helpers.DefaultHandler;
38
39import de.ugoe.cs.autoquest.eventcore.Event;
40import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementTree;
41import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
42import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
43import de.ugoe.cs.autoquest.plugin.html.eventcore.HTMLEventTypeFactory;
44import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElement;
45import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElementSpec;
46import de.ugoe.cs.util.console.Console;
47
48/**
49 * <p>
50 * This class provides the functionality to parse XML log files generated by the HTMLMonitor of
51 * autoquest. The result of parsing a file is a collection of event sequences.
52 * </p>
53 *
54 * @author Fabian Glaser
55 * @version 1.0
56 *
57 */
58public class NewHTMLLogParser extends DefaultHandler {
59    /**
60     * <p>
61     * Constructor. Creates a new HTMLLogParser.
62     * </p>
63     */
64    public NewHTMLLogParser() {
65        sequences = new LinkedList<List<Event>>();
66    }
67
68    /**
69     * <p>
70     * Collection of event sequences that is contained in the parsed log file.
71     * </p>
72     */
73    private Collection<List<Event>> sequences;
74   
75    /**
76     * <p>
77     * Internal handle to the parsed GUI structure, stored in a GUIElementTree
78     * </p>
79     */
80    private GUIElementTree<String> currentGUIElementTree;
81   
82    /**
83     * <p>
84     * Path of the GUI element currently being parsed.
85     * </p>
86     */
87    private String currentGUIElementPath;
88   
89    /**
90     * <p>
91     * Path of the parent of the GUI element currently being parsed.
92     * </p>
93     */
94    private String currentParentPath;
95   
96    /**
97     * <p>
98     * Source of the GUI element currently being parsed.
99     * </p>
100     */
101    private String currentEventSource;
102   
103    /**
104     * <p>
105     * Timestamp of the event currently being parsed.
106     * </p>
107     */
108    private Long currentEventTimestamp;
109   
110    /**
111     * <p>
112     * Internal handle to the parameters of the event currently being parsed.
113     * </p>
114     */
115    private Map<String, String> currentEventParameters;
116   
117    /**
118     * <p>
119     * Internal handle to the sequence currently being parsed.
120     * </p>
121     */
122    private List<Event> currentSequence;
123   
124    /**
125     * <p>
126     * Internal handle to type of the event currently being parsed.
127     * </p>
128     */
129    private String currentEventType;
130   
131    /**
132     * <p>
133     * Class of the GUI element currently being parsed.
134     * </p>
135     */
136    private String currentGUIElementClass;
137   
138    /**
139     * <p>
140     * Index of the GUI element currently being parsed.
141     * </p>
142     */
143    private String currentGUIElementIndex;
144   
145    /**
146     * Internal handle to the specification of the GUI element currently being parsed.
147     */
148    private HTMLGUIElementSpec currentGUIElementSpec;
149   
150    /**
151     * <p>
152     * internal handle to the GUI element of the previous event to be potentially reused for the
153     * current
154     * </p>
155     */
156    private IGUIElement lastGUIElement;
157   
158    /**
159     * <p>
160     * Parses a log file written by the HTMLMonitor and creates a collection of event sequences.
161     * </p>
162     *
163     * @param filename
164     *          name and path of the log file
165     */
166    public void parseFile(String filename) {
167        if (filename == null){
168            throw new IllegalArgumentException("filename must not be null");
169        }
170       
171        parseFile(new File(filename));
172    }
173    /**
174     * <p>
175     * Parses a log file written by the HTMLMonitor and creates a collection of event sequences.
176     * </p>
177     * @param file
178     *          file to be parsed
179     */
180    public void parseFile(File file) {
181        if (file == null){
182            throw new IllegalArgumentException("file must not be null");
183        }
184        SAXParserFactory spf = SAXParserFactory.newInstance();
185        spf.setValidating(true);
186        SAXParser saxParser = null;
187        InputSource inputSource = null;
188        try{
189            saxParser = spf.newSAXParser();
190            inputSource =
191                    new InputSource(new InputStreamReader(new FileInputStream(file), "UTF-8"));
192        }
193        catch (UnsupportedEncodingException e){
194            Console.printerr("Error parsing file " + file.getName());
195            Console.logException(e);
196            return;
197        }
198        catch (ParserConfigurationException e){
199            Console.printerr("Error parsing file " + file.getName());
200            Console.logException(e);
201            return;
202        }
203        catch (SAXException e){
204            Console.printerr("Error parsing file " + file.getName());
205            Console.logException(e);
206        }
207        catch (FileNotFoundException e){
208            Console.printerr("Error parsing file " + file.getName());
209            Console.logException(e);
210        }
211        if (inputSource != null){
212           inputSource.setSystemId("file://" + file.getAbsolutePath());
213           try{
214               if (saxParser == null){
215                   throw new RuntimeException("SaxParser creation failed");
216               }
217               saxParser.parse(inputSource, this);
218           }
219           catch (SAXParseException e){
220               Console.printerrln("Failure parsing file in line " + e.getLineNumber() +
221                                  ", column " + e.getColumnNumber() + ".");
222               Console.logException(e);
223           }
224           catch (SAXException e){
225               Console.printerr("Error parsing file " + file.getName());
226               Console.logException(e);
227               return;
228           }
229           catch (IOException e){
230               Console.printerr("Error parsing file " + file.getName());
231               Console.logException(e);
232               return;
233           }
234        } 
235    }
236
237    /* (non-Javadoc)
238     * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
239     */
240    @Override
241    public void startElement(String uri, String localName, String qName, Attributes atts)
242        throws SAXException
243    {
244        if (qName.equals("session")) {
245             currentSequence = new LinkedList<Event>();
246             if (currentGUIElementTree == null)
247                     currentGUIElementTree = new GUIElementTree<String>();
248        }
249        else if (qName.equals("component")) {
250            currentGUIElementPath = atts.getValue("path");
251        }
252        else if (qName.equals("event")) {
253            currentEventType = atts.getValue("type");
254            currentEventParameters = new HashMap<String, String>();
255        }
256        else if (qName.equals("param")){
257            String paramName = atts.getValue("name");
258            if (currentGUIElementPath != null){
259                if ("parent".equals(paramName)){
260                    currentParentPath = atts.getValue("value");
261                }
262                if ("class".equals(paramName)){
263                    currentGUIElementClass = atts.getValue("value");
264                }
265                if ("index".equals(paramName)){
266                    currentGUIElementIndex = atts.getValue("value");
267                }
268            }
269            else if (currentEventType != null){
270                if ("target".equals(paramName)){
271                    currentEventSource = atts.getValue("value");
272                }
273                if ("timestamp".equals(paramName)){
274                    currentEventTimestamp = Long.parseLong(atts.getValue("value"));
275                }
276                currentEventParameters.put(paramName, atts.getValue("value"));
277            }
278            else{
279                throw new SAXException("param tag found where it should not be.");
280            }
281        }
282        else{
283            throw new SAXException("unknown tag found: " + qName);
284        }
285
286    }
287
288    /* (non-Javadoc)
289     * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
290     */
291    @Override
292    public void endElement(String uri, String localName, String qName) throws SAXException {
293        if (qName.equals("session")) {
294            if (currentSequence != null && !currentSequence.isEmpty()){
295                sequences.add(currentSequence);
296            }
297            currentSequence = null;
298        }
299        else if (qName.equals("component") && currentGUIElementPath != null) {
300            HTMLGUIElementSpec guiElementSpec = new HTMLGUIElementSpec(currentGUIElementClass);
301            currentGUIElementTree.add(currentGUIElementPath, currentParentPath, guiElementSpec);
302           
303            currentParentPath = null;
304            currentGUIElementPath = null;
305        }
306        else if (qName.equals("event")) {
307            IGUIElement currentGUIElement;
308            currentGUIElement = currentGUIElementTree.find(currentEventSource);
309           
310            Event event = new Event(HTMLEventTypeFactory.
311                                    getInstance().getEventType(currentEventType, currentEventParameters),
312                                    (currentGUIElement == null ? lastGUIElement : currentGUIElement));
313           
314            event.setTimestamp(currentEventTimestamp);
315            HTMLGUIElement currentEventTarget = (HTMLGUIElement) event.getTarget();
316            currentEventTarget.markUsed();
317            currentSequence.add(event);
318           
319            currentEventSource = null;
320            currentEventTimestamp = -1l;
321            currentEventParameters = null;
322            currentEventType = null;
323           
324            if (currentGUIElement != null){
325                lastGUIElement = currentGUIElement;
326            }
327           
328            currentGUIElement = null;
329        }
330    }
331   
332    /**
333     * <p>
334     * Returns a collection of event sequences that was obtained from parsing log files.
335     * </p>
336     * @return
337     */
338    public Collection<List<Event>> getSequences(){
339        return sequences;
340    }
341   
342    /**
343     * <p>
344     * Returns the GUI model that is obtained from parsing log files.
345     * </p>
346     *
347     * @return GUIModel
348     */
349    public GUIModel getGuiModel(){
350        return currentGUIElementTree.getGUIModel();
351    }
352
353}
Note: See TracBrowser for help on using the repository browser.