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

Last change on this file since 1069 was 1069, checked in by pharms, 11 years ago
  • support of new HTML logging format
  • Property svn:mime-type set to text/plain
File size: 9.9 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.util.List;
18import java.util.Map;
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
21
22import org.xml.sax.SAXException;
23
24import de.ugoe.cs.autoquest.eventcore.Event;
25import de.ugoe.cs.autoquest.eventcore.IEventType;
26import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
27import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
28import de.ugoe.cs.autoquest.plugin.html.eventcore.HTMLEventTypeFactory;
29import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLDocumentSpec;
30import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElement;
31import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLGUIElementSpec;
32import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLPageElementSpec;
33import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLServerSpec;
34
35/**
36 * <p>
37 * This class provides the functionality to parse XML log files generated by the HTMLMonitor of
38 * AutoQUEST. The result of parsing a file is a collection of event sequences and a GUI model
39 * </p>
40 *
41 * @author Fabian Glaser, Patrick Harms
42 * @version 1.0
43 *
44 */
45public class HTMLLogParser extends AbstractDefaultLogParser {
46   
47    /**
48     *
49     */
50    private Pattern htmlElementPattern =
51        Pattern.compile("(\\w+)(\\[(\\d+)\\]|\\(htmlId=([\\w-]+)\\))");
52
53    /* (non-Javadoc)
54     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleGUIElement(java.lang.String, java.util.Map)
55     */
56    @Override
57    protected boolean handleGUIElement(String id, Map<String, String> parameters)
58        throws SAXException
59    {
60        HTMLGUIElementSpec specification = null;
61       
62        String parentId = parameters.get("parent");
63        IGUIElement parent = super.getGUIElementTree().find(parentId);
64
65        if (parameters.containsKey("host")) {
66            // this is a server specification
67            int port = 80;
68            String portStr = parameters.get(port);
69           
70            if (portStr != null) {
71                port = Integer.parseInt(portStr);
72            }
73           
74            specification = new HTMLServerSpec(parameters.get("host"), port);
75        }
76        else if (parameters.containsKey("path")) {
77            // this is a document specification
78           
79            if (parent != null) {
80                if (!(parent.getSpecification() instanceof HTMLServerSpec)) {
81                    throw new SAXException
82                        ("invalid log: parent GUI element of a document is not of type server");
83                }
84               
85                specification = new HTMLDocumentSpec
86                    ((HTMLServerSpec) parent.getSpecification(), parameters.get("path"),
87                     parameters.get("query"), parameters.get("title"));
88            }
89            else if (parentId == null) {
90                throw new SAXException("invalid log: a document has no parent id");
91            }
92        }
93        else if (parameters.containsKey("tagname")) {
94            String tagName = parameters.get("tagname");
95           
96            if (!tagNameMustBeConsidered(tagName)) {
97                return true;
98            }
99
100            if (parent != null) {
101                IGUIElement document = parent;
102               
103                while ((document != null) &&
104                       (!(document.getSpecification() instanceof HTMLDocumentSpec)))
105                {
106                    document = document.getParent();
107                }
108               
109                if (document == null) {
110                    throw new SAXException
111                        ("invalid log: parent hierarchy of a page element does not contain a " +
112                         "document");
113                }
114               
115                int index = -1;
116                String indexStr = parameters.get("index");
117
118                if ((indexStr != null) && (!"".equals(indexStr))) {
119                    index = Integer.parseInt(indexStr);
120                }
121
122                specification = new HTMLPageElementSpec
123                    ((HTMLDocumentSpec) document.getSpecification(), tagName,
124                     parameters.get("htmlid"), index);
125            }
126            else if (parentId == null) {
127                throw new SAXException("invalid log: a page element has no parent id");
128            }
129        }
130        else {
131            throw new SAXException("invalid log: unknown GUI element");
132        }
133
134        if (specification != null) {
135            super.getGUIElementTree().add(id, parentId, specification);
136            return true;
137        }
138        else {
139            return false;
140        }
141    }
142
143    /* (non-Javadoc)
144     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleEvent(java.lang.String, java.util.Map)
145     */
146    @Override
147    protected boolean handleEvent(String type, Map<String, String> parameters) throws SAXException {
148        String targetId = parameters.get("target");
149       
150        if (targetId == null) {
151            String targetDocument = parameters.get("targetDocument");
152            String targetDOMPath = parameters.get("targetDOMPath");
153           
154            if ((targetDocument == null) || (targetDOMPath == null)) {
155                throw new SAXException("event has no target defined");
156            }
157           
158            targetId = determineTargetId(targetDocument, targetDOMPath);
159           
160            if (targetId == null) {
161                // the target id can not be determined yet
162                return false;
163            }
164        }
165       
166        IGUIElement target = super.getGUIElementTree().find(targetId);
167       
168        if (target == null) {
169            // event not processable yet
170            return false;
171        }
172
173        IEventType eventType =
174            HTMLEventTypeFactory.getInstance().getEventType(type, parameters, target);
175       
176        Event event = new Event(eventType, target);
177
178        String timestampStr = parameters.get("timestamp");
179       
180        if (timestampStr != null) {
181            event.setTimestamp(Long.parseLong(timestampStr));
182        }
183
184        ((HTMLGUIElement) event.getTarget()).markUsed();
185       
186        super.addToSequence(event);
187
188        return true;
189    }
190
191    /**
192     * <p>
193     * TODO: comment
194     * </p>
195     *
196     * @param targetDocument
197     * @param targetDOMPath
198     * @return
199     */
200    private String determineTargetId(String targetDocument, String targetDOMPath)
201        throws SAXException
202    {
203        IGUIElement document = super.getGUIElementTree().find(targetDocument);
204       
205        if (document == null) {
206            return null;
207        }
208       
209        if (!(document.getSpecification() instanceof HTMLDocumentSpec)) {
210            throw new SAXException("an id that should refer to an HTML document refers to" +
211                                   "something else");
212        }
213       
214        GUIModel model = super.getGUIElementTree().getGUIModel();
215        IGUIElement child = document;
216        String[] pathElements = targetDOMPath.split("/");
217        int pathIndex = 0;
218       
219        HTMLPageElementSpec compareSpec;
220        String tagName;
221        int index;
222        String htmlId;
223       
224        while ((pathIndex < pathElements.length) && (child != null)) {
225            if ((pathElements[pathIndex] != null) && (!"".equals(pathElements[pathIndex]))) {           
226                Matcher matcher = htmlElementPattern.matcher(pathElements[pathIndex]);
227                if (!matcher.matches()) {
228                    throw new SAXException
229                        ("could not parse target DOM path element " + pathElements[pathIndex]);
230                }
231
232                tagName = matcher.group(1);
233                String indexStr = matcher.group(3);
234                htmlId = matcher.group(4);
235
236                index = -1;
237                if ((indexStr != null) && (!"".equals(indexStr))) {
238                    index = Integer.parseInt(indexStr);
239                }
240
241                compareSpec = new HTMLPageElementSpec
242                    ((HTMLDocumentSpec) document.getSpecification(), tagName, htmlId, index);
243
244                List<IGUIElement> children = model.getChildren(child);
245                child = null;
246
247                for (IGUIElement candidate : children) {
248                    if (compareSpec.getSimilarity(candidate.getSpecification())) {
249                        child = candidate;
250                        break;
251                    }
252                }
253            }
254           
255            pathIndex++;
256        }
257       
258        if (child != null) {
259            return super.getGUIElementTree().find(child);
260        }
261        else {
262            return null;
263        }
264    }
265
266    /**
267     * <p>
268     * checks if tags with the provided name must be handled in the GUI model. As an example,
269     * it is not necessary to handle "head" tags and anything included in them.
270     * </p>
271     *
272     * @param tagName
273     * @return
274     */
275    private boolean tagNameMustBeConsidered(String tagName) {
276        return
277            !"head".equals(tagName) && !"title".equals(tagName) && !"script".equals(tagName) &&
278            !"style".equals(tagName) && !"link".equals(tagName) && !"meta".equals(tagName) &&
279            !"iframe".equals(tagName) && !"input_hidden".equals(tagName) &&
280            !"option".equals(tagName) && !"tt".equals(tagName) && !"br".equals(tagName) &&
281            !"colgroup".equals(tagName) && !"col".equals(tagName);
282
283    }
284
285}
Note: See TracBrowser for help on using the repository browser.