View Javadoc

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 }