1 /**********************************************
2 * Copyright (C) 2010 Lukas Laag
3 * This file is part of lib-gwt-svg.
4 *
5 * libgwtsvg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * libgwtsvg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with libgwtsvg. If not, see http://www.gnu.org/licenses/
17 **********************************************/
18 /*
19 * Copyright (c) 2004 World Wide Web Consortium,
20 *
21 * (Massachusetts Institute of Technology, European Research Consortium for
22 * Informatics and Mathematics, Keio University). All Rights Reserved. This
23 * work is distributed under the W3C(r) Software License [1] in the hope that
24 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
25 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 *
27 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
28 */
29 package org.vectomatic.dom.svg;
30
31 import org.vectomatic.dom.svg.utils.DOMHelper;
32 import org.w3c.dom.DOMException;
33
34 import com.google.gwt.core.client.JavaScriptException;
35 import com.google.gwt.dom.client.Document;
36 import com.google.gwt.dom.client.Element;
37
38 /**
39 * Wrapper class for DOM Document
40 * @author laaglu
41 */
42 public class OMDocument extends OMNode {
43 /**
44 * Constructor
45 * @param document The wrapped document
46 */
47 protected OMDocument(Document document) {
48 super(document);
49 }
50
51 /**
52 * Returns the wrapped {@link com.google.gwt.dom.client.Document}
53 * @return the wrapped {@link com.google.gwt.dom.client.Document}
54 */
55 public Document getDocument() {
56 return ot.cast();
57 }
58
59 // Implementation of the dom::Document W3C IDL interface
60
61 /**
62 * Creates an {@link OMElement} of the given qualified name and namespace URI.
63 * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
64 * , applications must use the value <code>null</code> as the
65 * namespaceURI parameter for methods if they wish to have no namespace.
66 * @param namespaceURI The namespace URI of the element to create.
67 * @param qualifiedName The qualified name of the element type to
68 * instantiate.
69 * @return A new {@link OMElement} object with the following
70 * attributes:
71 * <table border='1' cellpadding='3'>
72 * <tr>
73 * <th>Attribute</th>
74 * <th>Value</th>
75 * </tr>
76 * <tr>
77 * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td>
78 * <td valign='top' rowspan='1' colspan='1'>
79 * <code>qualifiedName</code></td>
80 * </tr>
81 * <tr>
82 * <td valign='top' rowspan='1' colspan='1'><code>Node.namespaceURI</code></td>
83 * <td valign='top' rowspan='1' colspan='1'>
84 * <code>namespaceURI</code></td>
85 * </tr>
86 * <tr>
87 * <td valign='top' rowspan='1' colspan='1'><code>Node.prefix</code></td>
88 * <td valign='top' rowspan='1' colspan='1'>prefix, extracted
89 * from <code>qualifiedName</code>, or <code>null</code> if there is
90 * no prefix</td>
91 * </tr>
92 * <tr>
93 * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td>
94 * <td valign='top' rowspan='1' colspan='1'>local name, extracted from
95 * <code>qualifiedName</code></td>
96 * </tr>
97 * <tr>
98 * <td valign='top' rowspan='1' colspan='1'><code>Element.tagName</code></td>
99 * <td valign='top' rowspan='1' colspan='1'>
100 * <code>qualifiedName</code></td>
101 * </tr>
102 * </table>
103 * @exception DOMException
104 * INVALID_CHARACTER_ERR: Raised if the specified
105 * <code>qualifiedName</code> is not an XML name according to the XML
106 * version in use specified in the <code>Document.xmlVersion</code>
107 * attribute.
108 * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is a
109 * malformed qualified name, if the <code>qualifiedName</code> has a
110 * prefix and the <code>namespaceURI</code> is <code>null</code>, or
111 * if the <code>qualifiedName</code> has a prefix that is "xml" and
112 * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'>
113 * http://www.w3.org/XML/1998/namespace</a>" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
114 * , or if the <code>qualifiedName</code> or its prefix is "xmlns" and
115 * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if the <code>namespaceURI</code> is "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>" and neither the <code>qualifiedName</code> nor its prefix is "xmlns".
116 * <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not
117 * support the <code>"XML"</code> feature, since namespaces were
118 * defined by XML.
119 */
120 public final OMElement createElementNS(String namespaceURI, String qualifiedName) throws JavaScriptException {
121 return OMNode.convert(DOMHelper.createElementNS(((Document)ot), namespaceURI, qualifiedName));
122 }
123 /**
124 * Creates a new {@link OMText} node and initializes it
125 * with the specified data. The node is not attached to the
126 * DOM tree.
127 * @param data The string to initialize the text node
128 * @return The newly created {@link OMText} node
129 */
130 public final OMText createTextNode(String data) {
131 return OMNode.convert(((Document)ot).createTextNode(data));
132 }
133 /**
134 * Returns a <code>OMNodeList</code> of all the <code>OMElements</code> in
135 * document order with a given tag name and are contained in the
136 * document.
137 * @param tagname The name of the tag to match on. The special value "*"
138 * matches all tags. For XML, the <code>tagname</code> parameter is
139 * case-sensitive, otherwise it depends on the case-sensitivity of the
140 * markup language in use.
141 * @return A new <code>OMNodeList</code> object containing all the matched
142 * <code>Elements</code>.
143 */
144 public final <T extends OMElement> OMNodeList<T> getElementsByTagName(String tagname) {
145 return OMNode.convertList(((Document)ot).getElementsByTagName(tagname));
146 }
147 /**
148 * Returns a <code>OMNodeList</code> of all the <code>OMElements</code> with a
149 * given local name and namespace URI in document order.
150 * @param namespaceURI The namespace URI of the elements to match on. The
151 * special value <code>"*"</code> matches all namespaces.
152 * @param localName The local name of the elements to match on. The
153 * special value "*" matches all local names.
154 * @return A new <code>OMNodeList</code> object containing all the matched
155 * <code>Elements</code>.
156 */
157 public final <T extends OMElement> OMNodeList<T> getElementsByTagNameNS(String namespaceURI, String localName) {
158 return OMNode.convertList(DOMHelper.getElementsByTagNameNS(((Document)ot), namespaceURI, localName));
159 }
160 /**
161 * Returns the <code>OMElement</code> that has an ID attribute with the
162 * given value. If no such element exists, this returns <code>null</code>
163 * . If more than one element has an ID attribute with that value, what
164 * is returned is undefined.
165 * <br> The DOM implementation is expected to use the attribute
166 * <code>Attr.isId</code> to determine if an attribute is of type ID.
167 * <p ><b>Note:</b> Attributes with the name "ID" or "id" are not of type
168 * ID unless so defined.
169 * @param elementId The unique <code>id</code> value for an element.
170 * @return The matching element or <code>null</code> if there is none.
171 */
172 public final <T extends OMElement> T getElementById(String elementId) {
173 Element elt = ((Document)ot).getElementById(elementId);
174 return elt != null ? OMNode.<T>convert(elt) : null;
175 }
176
177 /**
178 * This is a convenience attribute that allows direct access to the child
179 * node that is the document element of the document.
180 */
181 public final OMElement getDocumentElement() {
182 return OMNode.convert(((Document)ot).getDocumentElement());
183 }
184
185
186 /**
187 * Imports a node from another document to this document, without altering
188 * or removing the source node from the original document; this method
189 * creates a new copy of the source node. The returned node has no
190 * parent; (<code>parentNode</code> is <code>null</code>).
191 * <br>For all nodes, importing a node creates a node object owned by the
192 * importing document, with attribute values identical to the source
193 * node's <code>nodeName</code> and <code>nodeType</code>, plus the
194 * attributes related to namespaces (<code>prefix</code>,
195 * <code>localName</code>, and <code>namespaceURI</code>). As in the
196 * <code>cloneNode</code> operation, the source node is not altered.
197 * User data associated to the imported node is not carried over.
198 * However, if any <code>UserDataHandlers</code> has been specified
199 * along with the associated data these handlers will be called with the
200 * appropriate parameters before this method returns.
201 * <br>Additional information is copied as appropriate to the
202 * <code>nodeType</code>, attempting to mirror the behavior expected if
203 * a fragment of XML or HTML source was copied from one document to
204 * another, recognizing that the two documents may have different DTDs
205 * in the XML case. The following list describes the specifics for each
206 * type of node.
207 * <dl>
208 * <dt>ATTRIBUTE_NODE</dt>
209 * <dd>The <code>ownerElement</code> attribute
210 * is set to <code>null</code> and the <code>specified</code> flag is
211 * set to <code>true</code> on the generated {@link OMAttr}. The
212 * descendants of the source {@link OMAttr} are recursively imported
213 * and the resulting nodes reassembled to form the corresponding subtree.
214 * Note that the <code>deep</code> parameter has no effect on
215 * {@link OMAttr} nodes; they always carry their children with them
216 * when imported.</dd>
217 * <dt>DOCUMENT_FRAGMENT_NODE</dt>
218 * <dd>If the <code>deep</code> option
219 * was set to <code>true</code>, the descendants of the source
220 * <code>DocumentFragment</code> are recursively imported and the
221 * resulting nodes reassembled under the imported
222 * <code>DocumentFragment</code> to form the corresponding subtree.
223 * Otherwise, this simply generates an empty
224 * <code>DocumentFragment</code>.</dd>
225 * <dt>DOCUMENT_NODE</dt>
226 * <dd><code>Document</code>
227 * nodes cannot be imported.</dd>
228 * <dt>DOCUMENT_TYPE_NODE</dt>
229 * <dd><code>DocumentType</code>
230 * nodes cannot be imported.</dd>
231 * <dt>ELEMENT_NODE</dt>
232 * <dd><em>Specified</em> attribute nodes of the source element are imported, and the generated
233 * {@link OMAttr} nodes are attached to the generated
234 * {@link OMElement}. Default attributes are <em>not</em> copied, though if the document being imported into defines default
235 * attributes for this element name, those are assigned. If the
236 * <code>importNode</code> <code>deep</code> parameter was set to
237 * <code>true</code>, the descendants of the source element are
238 * recursively imported and the resulting nodes reassembled to form the
239 * corresponding subtree.</dd>
240 * <dt>ENTITY_NODE</dt>
241 * <dd><code>Entity</code> nodes can be
242 * imported, however in the current release of the DOM the
243 * <code>DocumentType</code> is readonly. Ability to add these imported
244 * nodes to a <code>DocumentType</code> will be considered for addition
245 * to a future release of the DOM.On import, the <code>publicId</code>,
246 * <code>systemId</code>, and <code>notationName</code> attributes are
247 * copied. If a <code>deep</code> import is requested, the descendants
248 * of the the source <code>Entity</code> are recursively imported and
249 * the resulting nodes reassembled to form the corresponding subtree.</dd>
250 * <dt>
251 * ENTITY_REFERENCE_NODE</dt>
252 * <dd>Only the <code>EntityReference</code> itself is
253 * copied, even if a <code>deep</code> import is requested, since the
254 * source and destination documents might have defined the entity
255 * differently. If the document being imported into provides a
256 * definition for this entity name, its value is assigned.</dd>
257 * <dt>NOTATION_NODE</dt>
258 * <dd>
259 * <code>Notation</code> nodes can be imported, however in the current
260 * release of the DOM the <code>DocumentType</code> is readonly. Ability
261 * to add these imported nodes to a <code>DocumentType</code> will be
262 * considered for addition to a future release of the DOM.On import, the
263 * <code>publicId</code> and <code>systemId</code> attributes are copied.
264 * Note that the <code>deep</code> parameter has no effect on this type
265 * of nodes since they cannot have any children.</dd>
266 * <dt>
267 * PROCESSING_INSTRUCTION_NODE</dt>
268 * <dd>The imported node copies its
269 * <code>target</code> and <code>data</code> values from those of the
270 * source node.Note that the <code>deep</code> parameter has no effect
271 * on this type of nodes since they cannot have any children.</dd>
272 * <dt>TEXT_NODE,
273 * CDATA_SECTION_NODE, COMMENT_NODE</dt>
274 * <dd>These three types of nodes inheriting
275 * from <code>CharacterData</code> copy their <code>data</code> and
276 * <code>length</code> attributes from those of the source node.Note
277 * that the <code>deep</code> parameter has no effect on these types of
278 * nodes since they cannot have any children.</dd>
279 * </dl>
280 * @param importedNode The node to import.
281 * @param deep If <code>true</code>, recursively import the subtree under
282 * the specified node; if <code>false</code>, import only the node
283 * itself, as explained above. This has no effect on nodes that cannot
284 * have any children, and on {@link OMAttr}, and
285 * <code>EntityReference</code> nodes.
286 * @return The imported node that belongs to this <code>Document</code>.
287 * @exception DOMException
288 * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not
289 * supported.
290 * <br>INVALID_CHARACTER_ERR: Raised if one of the imported names is not
291 * an XML name according to the XML version in use specified in the
292 * <code>Document.xmlVersion</code> attribute. This may happen when
293 * importing an XML 1.1 [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] element
294 * into an XML 1.0 document, for instance.
295 */
296 public final OMNode importNode(OMNode importedNode, boolean deep) {
297 return OMNode.convert(DOMHelper.importNode(((Document)ot), importedNode.getNode(), deep));
298 }
299 }