source: trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlGUIElementManager.java @ 1076

Last change on this file since 1076 was 1076, checked in by pharms, 11 years ago
  • removed TODOs
File size: 8.0 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.htmlmonitor;
16
17import java.security.MessageDigest;
18import java.util.HashMap;
19import java.util.LinkedList;
20import java.util.List;
21import java.util.Map;
22
23import org.apache.commons.codec.binary.Base64;
24
25/**
26 * <p>
27 * This class is used to calculate unique ids for GUI elements and to reuse GUI element objects.
28 * For this it provides appropriate create methods. If there is already a GUI element for the
29 * given parameters, it is reused. Otherwise, a new one is instantiated with a unique id and
30 * returned.
31 * </p>
32 *
33 * @author Patrick Harms
34 */
35class HtmlGUIElementManager {
36
37    /**
38     * an internal map for GUI elements and their respective ids.
39     */
40    private Map<String, HtmlGUIElement> idMap = new HashMap<String, HtmlGUIElement>();
41   
42    /** */
43    private Map<String, List<HtmlPageElement>> domPathMap =
44          new HashMap<String, List<HtmlPageElement>>();
45   
46    /**
47     * <p>
48     * creates a new or reuses an existing GUI element representing a server
49     * </p>
50     *
51     * @param name the name of the server to represent (must not be null)
52     * @param port the port on the server via which the communication is done
53     *
54     * @return a new or reuses an existing GUI element representing a server
55     */
56    HtmlServer createHtmlServer(String name, int port) {
57        if (name == null) {
58            throw new IllegalArgumentException("name must not be null");
59        }
60       
61        String id = calculateId(name, Integer.toString(port));
62       
63        HtmlGUIElement server = idMap.get(id);
64       
65        if (server == null) {
66            server = new HtmlServer(id, name, port);
67            idMap.put(id, server);
68        }
69        else if (!(server instanceof HtmlServer)) {
70            throw new RuntimeException
71                ("id conflict: calculated the same id for two different GUI elements");
72        }
73       
74        return (HtmlServer) server;
75    }
76   
77    /**
78     * <p>
79     * creates a new or reuses an existing GUI element representing a document (web page)
80     * </p>
81     *
82     * @param server the server on which the document resides (must not be null)
83     * @param path   the path of the document on the web server (every following the server spec
84     *               in the URL, must not be null)
85     * @param query  the query part of the URL pointing to the document
86     * @param title  the title of the document if available
87     *
88     * @return a new or reuses an existing GUI element representing a document
89     */
90    HtmlDocument createHtmlDocument(HtmlServer server, String path, String query, String title) {
91        if (server == null) {
92            throw new IllegalArgumentException("server must not be null");
93        }
94        if (path == null) {
95            throw new IllegalArgumentException("path must not be null");
96        }
97
98        String id = calculateId(server.getId(), path, query, title);
99       
100        HtmlGUIElement document = idMap.get(id);
101
102        if (document == null) {
103            document = new HtmlDocument(id, server, path, query, title);
104            idMap.put(id, document);
105        }
106        else if (!(document instanceof HtmlDocument)) {
107            throw new RuntimeException
108                ("id conflict: calculated the same id for two different GUI elements");
109        }
110       
111        return (HtmlDocument) document;
112    }
113
114    /**
115     * <p>
116     * creates a new or reuses an existing GUI element representing an HTML tag in a document
117     * </p>
118     *
119     * @param document the document to which the HTML tag belongs (must not be null)
120     * @param parent   the parent tag, if any
121     * @param tagName  the name of the HTML tag (must not be null)
122     * @param htmlId   the document wide unique id of the tag, if available
123     * @param index    if no HTML id is present, the index of the tag regarding all children in
124     *                 the same parent having the same tag name.
125     *
126     * @return a new or reuses an existing GUI element representing an HTML tag
127     */
128    HtmlPageElement createHtmlPageElement(HtmlDocument    document,
129                                          HtmlPageElement parent,
130                                          String          tagName,
131                                          String          htmlId,
132                                          Integer         index)
133    {
134        if (document == null) {
135            throw new IllegalArgumentException("document must not be null");
136        }
137        if (tagName == null) {
138            throw new IllegalArgumentException("document must not be null");
139        }
140
141        String id = calculateId
142            (document.getId(), parent != null ? parent.getDOMPath() : null, tagName, htmlId,
143             index != null ? index.toString() : "-1");
144
145        HtmlGUIElement pageElement = idMap.get(id);
146
147        if (pageElement == null) {
148            pageElement = new HtmlPageElement(id, document, parent, tagName, htmlId, index);
149            idMap.put(id, pageElement);
150        }
151        else if (!(pageElement instanceof HtmlPageElement)) {
152            throw new RuntimeException
153                ("id conflict: calculated the same id for two different GUI elements");
154        }
155           
156        List<HtmlPageElement> candidates =
157            domPathMap.get(((HtmlPageElement) pageElement).getDOMPath());
158       
159        if (candidates == null) {
160            candidates = new LinkedList<HtmlPageElement>();
161            domPathMap.put(((HtmlPageElement) pageElement).getDOMPath(), candidates);
162        }
163       
164        if (!candidates.contains(pageElement)) {
165            candidates.add((HtmlPageElement) pageElement);
166        }
167
168        return (HtmlPageElement) pageElement;
169    }
170
171    /**
172     * <p>
173     * determines the HTML tag belonging to the given document and residing in the document at the
174     * location denoted by the path. The path must be equal to the return value of the
175     * {@link HtmlPageElement#getDOMPath()} method.
176     * </p>
177     *
178     * @param document the document to which the searched tag belongs
179     * @param domPath  the path through the DOM where the searched tag resists
180     *
181     * @return the appropriate HTML tag or null, if none is known
182     */
183    HtmlPageElement getPageElement(HtmlDocument document, String domPath) {
184        List<HtmlPageElement> candidates = domPathMap.get(domPath);
185       
186        if (candidates != null) {
187            for (HtmlPageElement candidate : candidates) {
188                if (document.equals(candidate.getDocument())) {
189                    return candidate;
190                }
191            }
192        }
193       
194        return null;
195    }
196
197    /**
198     * <p>
199     * calculates a unique id for the given string fragments using SHA-512 and Base64 encoding.
200     * </p>
201     *
202     * @param fragments strings to be used for calculating a unique id
203     *
204     * @return a Base64 encoded unique id for the provided fragments
205     */
206    private String calculateId(String... fragments) {
207        try {
208            MessageDigest md = MessageDigest.getInstance("SHA-512");
209           
210            for (String fragment : fragments) {
211                if (fragment != null) {
212                    md.update(fragment.getBytes("UTF-8"));
213                }
214            }
215           
216            return Base64.encodeBase64String(md.digest());
217        }
218        catch (Exception e) {
219            throw new IllegalStateException("Java VM does not support this code");
220        }
221    }
222
223}
Note: See TracBrowser for help on using the repository browser.