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