// Copyright 2012 Georg-August-Universität Göttingen, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
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.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xml.sax.SAXException;
import de.ugoe.cs.autoquest.eventcore.Event;
import de.ugoe.cs.autoquest.eventcore.IEventType;
import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModelException;
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.HTMLDocumentSpec;
import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElement;
import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElementSpec;
import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLPageElement;
import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLPageElementSpec;
import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLServerSpec;
/**
*
* 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 and a GUI model
*
*
* @author Fabian Glaser, Patrick Harms
* @version 1.0
*
*/
public class HTMLLogParser extends AbstractDefaultLogParser {
/**
*
* the pattern used for parsing HTML GUI element paths
*
* a map containing replacement specifications for ids of GUI elements
*
*/
private Map idReplacements;
/**
*
* TODO: comment
*
*
* @param parseParams
*/
public HTMLLogParser(Map> parseParams) {
this.parseParams = parseParams;
for (String paramKey : parseParams.keySet()) {
if (!"clearId".equals(paramKey) && !"clearIndex".equals(paramKey) &&
!"idReplacements".equals(paramKey))
{
throw new IllegalArgumentException("unknown parse parameter key " + paramKey);
}
}
}
/* (non-Javadoc)
* @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleGUIElement(String, Map)
*/
@Override
protected boolean handleGUIElement(String id, Map parameters)
throws SAXException
{
HTMLGUIElementSpec specification = null;
String parentId = parameters.get("parent");
HTMLGUIElement parent = (HTMLGUIElement) super.getGUIElementTree().find(parentId);
if (parameters.containsKey("host")) {
// this is a server specification
int port = 80;
String portStr = parameters.get("port");
if (portStr != null) {
port = Integer.parseInt(portStr);
}
specification = new HTMLServerSpec(parameters.get("host"), port);
}
else if (parameters.containsKey("path")) {
// this is a document specification
if (parent != null) {
if (!(parent.getSpecification() instanceof HTMLServerSpec)) {
throw new SAXException
("invalid log: parent GUI element of a document is not of type server");
}
specification = new HTMLDocumentSpec
((HTMLServerSpec) parent.getSpecification(), parameters.get("path"),
parameters.get("query"), parameters.get("title"));
}
else if (parentId == null) {
throw new SAXException("invalid log: a document has no parent id");
}
}
else if (parameters.containsKey("tagname")) {
String tagName = parameters.get("tagname");
if (!tagNameMustBeConsidered(tagName)) {
return true;
}
if (parent != null) {
IGUIElement document = parent;
while ((document != null) &&
(!(document.getSpecification() instanceof HTMLDocumentSpec)))
{
document = document.getParent();
}
if (document == null) {
throw new SAXException
("invalid log: parent hierarchy of a page element does not contain a " +
"document");
}
int index = -1;
String indexStr = parameters.get("index");
if ((indexStr != null) && (!"".equals(indexStr))) {
index = Integer.parseInt(indexStr);
}
String htmlId = parameters.get("htmlid");
if (clearIndex(tagName, index, htmlId, parent)) {
index = -1;
}
String idReplacement = replaceHTMLId(tagName, index, htmlId, parent);
if (idReplacement != null) {
htmlId = idReplacement;
}
else if (clearHTMLId(tagName, index, htmlId, parent)) {
htmlId = null;
}
if ((htmlId == null) && (index == -1)) {
// set at least a default index, if all is to be ignored.
index = 0;
}
specification = new HTMLPageElementSpec
((HTMLDocumentSpec) document.getSpecification(), tagName, htmlId, index);
}
else if (parentId == null) {
throw new SAXException("invalid log: a page element has no parent id");
}
}
else {
throw new SAXException("invalid log: unknown GUI element");
}
if (specification != null) {
try {
super.getGUIElementTree().add(id, parentId, specification);
}
catch (GUIModelException e) {
throw new SAXException("could not handle GUI element with id " +
id + ": " + e.getMessage(), e);
}
return true;
}
else {
return false;
}
}
/**
*