Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/NewHTMLLogParser.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/NewHTMLLogParser.java	(revision 1047)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/NewHTMLLogParser.java	(revision 1047)
@@ -0,0 +1,334 @@
+
+package de.ugoe.cs.autoquest.plugin.html;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementTree;
+import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
+import de.ugoe.cs.autoquest.plugin.html.eventcore.HTMLEventTypeFactory;
+import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElement;
+import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElementSpec;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides the functionality to parse XML log files generated by the HTMLMonitor of
+ * autoquest. The result of parsing a file is a collection of event sequences.
+ * </p>
+ * 
+ * @author Fabian Glaser
+ * @version 1.0
+ * 
+ */
+public class NewHTMLLogParser extends DefaultHandler {
+    /**
+     * <p>
+     * Constructor. Creates a new HTMLLogParser.
+     * </p>
+     */
+    public NewHTMLLogParser() {
+        sequences = new LinkedList<List<Event>>();
+    }
+
+    /**
+     * <p>
+     * Collection of event sequences that is contained in the parsed log file.
+     * </p>
+     */
+    private Collection<List<Event>> sequences;
+    
+    /**
+     * <p>
+     * Internal handle to the parsed GUI structure, stored in a GUIElementTree
+     * </p>
+     */
+    private GUIElementTree<String> currentGUIElementTree;
+    
+    /**
+     * <p>
+     * Path of the GUI element currently being parsed.
+     * </p>
+     */
+    private String currentGUIElementPath;
+    
+    /**
+     * <p>
+     * Path of the parent of the GUI element currently being parsed.
+     * </p>
+     */
+    private String currentParentPath;
+    
+    /**
+     * <p>
+     * Source of the GUI element currently being parsed.
+     * </p>
+     */
+    private String currentEventSource;
+    
+    /**
+     * <p>
+     * Timestamp of the event currently being parsed.
+     * </p>
+     */
+    private Long currentEventTimestamp;
+    
+    /**
+     * <p>
+     * Internal handle to the parameters of the event currently being parsed.
+     * </p>
+     */
+    private Map<String, String> currentEventParameters;
+    
+    /**
+     * <p>
+     * Internal handle to the sequence currently being parsed.
+     * </p>
+     */
+    private List<Event> currentSequence;
+    
+    /**
+     * <p>
+     * Internal handle to type of the event currently being parsed.
+     * </p>
+     */
+    private String currentEventType;
+    
+    /**
+     * <p>
+     * Class of the GUI element currently being parsed.
+     * </p>
+     */
+    private String currentGUIElementClass;
+    
+    /**
+     * <p>
+     * Index of the GUI element currently being parsed.
+     * </p>
+     */
+    private String currentGUIElementIndex;
+    
+    /**
+     * Internal handle to the specification of the GUI element currently being parsed.
+     */
+    private HTMLGUIElementSpec currentGUIElementSpec;
+    
+    /**
+     * <p>
+     * internal handle to the GUI element of the previous event to be potentially reused for the
+     * current
+     * </p>
+     */
+    private IGUIElement lastGUIElement;
+    
+    /**
+     * <p>
+     * Parses a log file written by the HTMLMonitor and creates a collection of event sequences.
+     * </p>
+     * 
+     * @param filename
+     *          name and path of the log file
+     */
+    public void parseFile(String filename) {
+        if (filename == null){
+            throw new IllegalArgumentException("filename must not be null");
+        }
+        
+        parseFile(new File(filename));
+    }
+    /**
+     * <p>
+     * Parses a log file written by the HTMLMonitor and creates a collection of event sequences.
+     * </p>
+     * @param file
+     *          file to be parsed
+     */
+    public void parseFile(File file) {
+        if (file == null){
+            throw new IllegalArgumentException("file must not be null");
+        }
+        SAXParserFactory spf = SAXParserFactory.newInstance();
+        spf.setValidating(true);
+        SAXParser saxParser = null;
+        InputSource inputSource = null;
+        try{
+            saxParser = spf.newSAXParser();
+            inputSource =
+                    new InputSource(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+        }
+        catch (UnsupportedEncodingException e){
+            Console.printerr("Error parsing file " + file.getName());
+            Console.logException(e);
+            return;
+        }
+        catch (ParserConfigurationException e){
+            Console.printerr("Error parsing file " + file.getName());
+            Console.logException(e);
+            return;
+        }
+        catch (SAXException e){
+            Console.printerr("Error parsing file " + file.getName());
+            Console.logException(e);
+        }
+        catch (FileNotFoundException e){
+            Console.printerr("Error parsing file " + file.getName());
+            Console.logException(e);
+        }
+        if (inputSource != null){
+           inputSource.setSystemId("file://" + file.getAbsolutePath());
+           try{
+               if (saxParser == null){
+                   throw new RuntimeException("SaxParser creation failed");
+               }
+               saxParser.parse(inputSource, this);
+           }
+           catch (SAXParseException e){
+               Console.printerrln("Failure parsing file in line " + e.getLineNumber() +
+                                  ", column " + e.getColumnNumber() + ".");
+               Console.logException(e);
+           }
+           catch (SAXException e){
+               Console.printerr("Error parsing file " + file.getName());
+               Console.logException(e);
+               return;
+           }
+           catch (IOException e){
+               Console.printerr("Error parsing file " + file.getName());
+               Console.logException(e);
+               return;
+           }
+        }  
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes atts)
+        throws SAXException
+    {
+        if (qName.equals("session")) {
+             currentSequence = new LinkedList<Event>();
+             if (currentGUIElementTree == null)
+                     currentGUIElementTree = new GUIElementTree<String>();
+        }
+        else if (qName.equals("component")) {
+            currentGUIElementPath = atts.getValue("path");
+        }
+        else if (qName.equals("event")) {
+            currentEventType = atts.getValue("type");
+            currentEventParameters = new HashMap<String, String>();
+        }
+        else if (qName.equals("param")){
+            String paramName = atts.getValue("name");
+            if (currentGUIElementPath != null){
+                if ("parent".equals(paramName)){
+                    currentParentPath = atts.getValue("value");
+                }
+                if ("class".equals(paramName)){
+                    currentGUIElementClass = atts.getValue("value");
+                }
+                if ("index".equals(paramName)){
+                    currentGUIElementIndex = atts.getValue("value");
+                }
+            }
+            else if (currentEventType != null){
+                if ("target".equals(paramName)){
+                    currentEventSource = atts.getValue("value");
+                }
+                if ("timestamp".equals(paramName)){
+                    currentEventTimestamp = Long.parseLong(atts.getValue("value"));
+                }
+                currentEventParameters.put(paramName, atts.getValue("value"));
+            }
+            else{
+                throw new SAXException("param tag found where it should not be.");
+            }
+        }
+        else{
+            throw new SAXException("unknown tag found: " + qName);
+        }
+
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (qName.equals("session")) {
+            if (currentSequence != null && !currentSequence.isEmpty()){
+                sequences.add(currentSequence);
+            }
+            currentSequence = null;
+        }
+        else if (qName.equals("component") && currentGUIElementPath != null) {
+            HTMLGUIElementSpec guiElementSpec = new HTMLGUIElementSpec(currentGUIElementClass);
+            currentGUIElementTree.add(currentGUIElementPath, currentParentPath, guiElementSpec);
+            
+            currentParentPath = null;
+            currentGUIElementPath = null;
+        }
+        else if (qName.equals("event")) {
+            IGUIElement currentGUIElement;
+            currentGUIElement = currentGUIElementTree.find(currentEventSource);
+            
+            Event event = new Event(HTMLEventTypeFactory.
+                                    getInstance().getEventType(currentEventType, currentEventParameters),
+                                    (currentGUIElement == null ? lastGUIElement : currentGUIElement));
+            
+            event.setTimestamp(currentEventTimestamp);
+            HTMLGUIElement currentEventTarget = (HTMLGUIElement) event.getTarget();
+            currentEventTarget.markAsUsed();
+            currentSequence.add(event);
+            
+            currentEventSource = null;
+            currentEventTimestamp = -1l;
+            currentEventParameters = null;
+            currentEventType = null;
+            
+            if (currentGUIElement != null){
+                lastGUIElement = currentGUIElement;
+            }
+            
+            currentGUIElement = null;
+        }
+    }
+   
+    /**
+     * <p>
+     * Returns a collection of event sequences that was obtained from parsing log files.
+     * </p>
+     * @return
+     */
+    public Collection<List<Event>> getSequences(){
+        return sequences;
+    }
+    
+    /**
+     * <p>
+     * Returns the GUI model that is obtained from parsing log files.
+     * </p>
+     * 
+     * @return GUIModel
+     */
+    public GUIModel getGuiModel(){
+        return currentGUIElementTree.getGUIModel();
+    }
+
+}
Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/eventcore/HTMLEventTypeFactory.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/eventcore/HTMLEventTypeFactory.java	(revision 1047)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/eventcore/HTMLEventTypeFactory.java	(revision 1047)
@@ -0,0 +1,83 @@
+
+package de.ugoe.cs.autoquest.plugin.html.eventcore;
+
+import java.util.Map;
+import java.util.logging.Level;
+
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyboardFocusChange;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
+import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
+import de.ugoe.cs.util.console.Console;
+
+public class HTMLEventTypeFactory {
+    private static HTMLEventTypeFactory instance = new HTMLEventTypeFactory();
+
+    private HTMLEventTypeFactory() {}
+
+    public static HTMLEventTypeFactory getInstance() {
+        return instance;
+    }
+
+    public IEventType getEventType(String eventName, Map<String, String> eventParameters) {
+        IInteraction result = null;
+
+        if ("onscroll".equals(eventName)) {
+            int[] coordinates = getCoordinateParameter(eventName, eventParameters);
+            result = new Scroll(coordinates[0], coordinates[1]);
+        }
+        else if ("onclick".equals(eventName)) {
+            int[] coordinates = getCoordinateParameter(eventName, eventParameters);
+            result =
+                new MouseClick(MouseButtonInteraction.Button.LEFT, coordinates[0], coordinates[1]);
+        }
+        else if ("onchange".equals(eventName)) {
+            // TODO: Implement "onchange" event handling
+            Console.traceln(Level.FINE, "Unhandled event of type \"" + eventName + "\"");
+        }
+        else if ("onfocus".equals(eventName)) {
+            result = new KeyboardFocusChange();
+        }
+        else if ("onunload".equals(eventName) || "onbeforeunload".equals(eventName) ||
+            "onpagehide".equals(eventName) || "onpageshow".equals(eventName))
+        {
+            Console.traceln(Level.FINE, "Ignored event name \"" + eventName + "\"");
+        }
+        else {
+            throw new IllegalArgumentException("unknown event name: \"" + eventName + "\"");
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     * 
+     * @param eventName
+     * @param eventParameters
+     * @return
+     */
+    private int[] getCoordinateParameter(String eventName, Map<String, String> eventParameters) {
+        String xCoord = eventParameters.get("X");
+        if (xCoord == null) {
+            throw new IllegalArgumentException("eventParameters do not contain X coordinate.");
+        }
+
+        String yCoord = eventParameters.get("Y");
+        if (yCoord == null) {
+            throw new IllegalArgumentException("eventParameters do not contain Y coordinate.");
+        }
+
+        try {
+            return new int[]
+                { Integer.parseInt(xCoord), Integer.parseInt(yCoord) };
+        }
+        catch (NumberFormatException e) {
+            throw new IllegalArgumentException("the coordinates provided" + " of an " + eventName +
+                " event are no numbers");
+        }
+    }
+}
Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/guimodel/HTMLGUIElementSpec.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/guimodel/HTMLGUIElementSpec.java	(revision 1012)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/guimodel/HTMLGUIElementSpec.java	(revision 1047)
@@ -41,5 +41,5 @@
      * @param id
      */
-    HTMLGUIElementSpec(String type) {
+    public HTMLGUIElementSpec(String type) {
         if (type == null) {
             throw new IllegalArgumentException("type must not be null");
