KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > HashMapElement


1 /*
2  * @(#)HashMapElement.java 1.36 02/03/21
3  *
4  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package org.enhydra.xml;
8
9 import java.util.ArrayList JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.List JavaDoc;
13
14 import org.w3c.dom.DOMException JavaDoc;
15 import org.w3c.dom.Document JavaDoc;
16 import org.w3c.dom.Element JavaDoc;
17 import org.w3c.dom.Node JavaDoc;
18 import org.w3c.dom.NodeList JavaDoc;
19
20 /**
21  * @author Tweety
22  *
23  * A class representing a node in a meta-data tree, which implements
24  * the <a HREF="../../../../api/org/w3c/dom/Element.html">
25  *
26  * <p> Namespaces are ignored in this implementation. The terms "tag
27  * name" and "node name" are always considered to be synonymous.
28  *
29  * @version 1.0
30  */

31 public class HashMapElement extends ElementImpl {
32
33
34     /**
35      * All <code>Element<code> type children of this <code>Element<code>
36      */

37     protected HashMap JavaDoc children = null;
38
39
40     /**
41      * Constructs an empty <code>HashMapElement</code>.
42      */

43     public HashMapElement() {
44         super();
45         children = new HashMap JavaDoc();
46     }
47
48
49     /**
50      * Constructs a <code>HashMapElement</code> from the given node,
51      * without creating entire children subtree.
52      *
53      * @param element, as a <code>HashMapElement</code>.
54      */

55     public HashMapElement(HashMapElement element) {
56         super(element);
57         children = element.children;
58     }
59
60
61     /**
62      * Constructs an <code>HashMapElement</code> with the given
63      * document owner and node name.
64      *
65      * @param ownerDoc the document owner of the node, as a <code>Document</code>.
66      * @param nodeName the name of the node, as a <code>String</code>.
67      */

68     public HashMapElement(Document JavaDoc ownerDoc, String JavaDoc name) {
69         super(ownerDoc, name);
70         this.children = new HashMap JavaDoc();
71     }
72
73
74     /**
75      * Constructs an <code>HashMapElement</code> with the given
76      * document owner, node name, node type and node value.
77      *
78      * @param ownerDoc the document owner of the node, as a <code>Document</code>.
79      * @param nodeName the name of the node, as a <code>String</code>.
80      * @param type the type of the node, as a <code>short</code>.
81      * @param value the value of the node, as a <code>String</code>.
82      */

83     protected HashMapElement(Document JavaDoc ownerDoc, String JavaDoc nodeName, short type, String JavaDoc value) {
84         super(ownerDoc, nodeName, type, value);
85     }
86
87
88     /**
89      * Constructs an <code>HashMapElement</code> from a given node
90      * (creates the children subtree too), as a <code>Node</code>
91      *
92      * @param node, as a <code>Node</code>.
93      */

94     public HashMapElement(Node JavaDoc node) {
95         this(node, true);
96     }
97
98     /**
99      * Constructs an <code>HashMapElement</code> from a given node,
100      * as a <code>Node</code>, and deep as <code>boolean</code>.
101      *
102      * @param node, as a <code>Node</code>.
103      * @param deep if <code>true</code>, recursively clone the subtree
104      * under the specified node; if <code>false</code>, clone only the
105      * node itself.
106      */

107     public HashMapElement(Node JavaDoc node, boolean deep) {
108         super(node, false);
109         children = new HashMap JavaDoc();
110         if (deep)
111             initNodeImplChildren(node);
112     }
113
114
115     /**
116      * Creates new instance of the HashMapElement class from the given <code>Node</code>.
117      *
118      * @param node, as a <code>Node</code>.
119      *
120      * @return new instance of the HashMapElement class.
121      */

122     protected Node JavaDoc newElementInstance(Node JavaDoc node) {
123         return new HashMapElement(node);
124     }
125
126   /**
127      * Creates new instance of <code>HashMapElement</code> from a given document
128      * as a <code>Document</code>.
129      *
130      * @param document document.
131      *
132      * @return new <code>Element</code> node as a root of the <code>Document</code>.
133      */

134     public static Element JavaDoc newInstance(Document JavaDoc document) {
135         Node JavaDoc root = document.getDocumentElement();
136         return new HashMapElement(root);
137     }
138
139     /**
140      * Inserts the node <code>newChild</code> before the existing
141      * child node <code>refChild</code>. If <code>refChild</code> is
142      * <code>null</code>, insert <code>newChild</code> at the end of
143      * the list of children.
144      *
145      * @param newChild the <code>Node</code> to insert.
146      * @param refChild the reference <code>Node</code>.
147      *
148      * @return the node being inserted.
149      *
150      * @exception IllegalArgumentException if <code>newChild</code> is
151      * <code>null</code>.
152      */

153     public Node JavaDoc insertBefore(Node JavaDoc newChild, Node JavaDoc refChild) {
154         super.insertBefore(newChild, refChild);
155
156         if (newChild.getNodeType() == ELEMENT_NODE) {
157             HashMapElement newChildNode = (HashMapElement) newChild;
158
159             List JavaDoc list = (List JavaDoc) children.get(newChildNode.getTagName());
160             if (list == null)
161                 list = new ArrayList JavaDoc();
162             list.add(newChildNode);
163             children.put(newChildNode.getTagName(), list);
164         }
165         return newChild;
166     }
167
168
169     /**
170      * Replaces the child node <code>oldChild</code> with
171      * <code>newChild</code> in the list of children, and returns the
172      * <code>oldChild</code> node.
173      *
174      * @param newChild the <code>Node</code> to insert.
175      * @param oldChild the <code>Node</code> to be replaced.
176      *
177      * @return the node replaced.
178      *
179      * @exception IllegalArgumentException if <code>newChild</code> is
180      * <code>null</code>.
181      */

182     public Node JavaDoc replaceChild(Node JavaDoc newChild, Node JavaDoc oldChild) {
183         super.replaceChild(newChild, oldChild);
184
185         if (oldChild.getNodeType() == ELEMENT_NODE) {
186             HashMapElement oldChildNode = (HashMapElement) oldChild;
187             List JavaDoc list = (List JavaDoc) children.get(oldChildNode.getTagName());
188             if (list != null) {
189                 int index = list.indexOf(oldChildNode);
190                 if (index != -1)
191                     list.remove(index);
192                 if (list.size() == 0)
193                     children.remove(oldChildNode.getTagName());
194             }
195         }
196         if (newChild.getNodeType() == ELEMENT_NODE) {
197             HashMapElement newChildNode = (HashMapElement) newChild;
198             List JavaDoc list = (List JavaDoc) children.get(newChildNode.getTagName());
199             if (list == null)
200                 list = new ArrayList JavaDoc();
201             list.add(newChildNode);
202             children.put(newChildNode.getTagName(), list);
203         }
204
205         return oldChild;
206     }
207
208
209     /**
210      * Removes the child node indicated by <code>oldChild</code> from
211      * the list of children, and returns it.
212      *
213      * @param oldChild the <code>Node</code> to be removed.
214      *
215      * @return the node removed.
216      *
217      * @exception IllegalArgumentException if <code>oldChild</code> is
218      * <code>null</code>.
219      */

220     public Node JavaDoc removeChild(Node JavaDoc oldChild) {
221         super.removeChild(oldChild);
222
223         if (oldChild.getNodeType() == ELEMENT_NODE) {
224             HashMapElement oldChildNode = (HashMapElement) oldChild;
225
226             List JavaDoc list = (List JavaDoc) children.get(oldChildNode.getTagName());
227             if (list != null) {
228                 int index = list.indexOf(oldChildNode);
229                 if (index != -1)
230                     list.remove(index);
231                 if (list.size() == 0)
232                     children.remove(oldChildNode.getTagName());
233             }
234         }
235         return oldChild;
236     }
237
238
239     /**
240      * Returns a duplicate of this node. The duplicate node has no
241      * parent (<code>getParentNode</code> returns <code>null</code>).
242      * If a shallow clone is being performed (<code>deep</code> is
243      * <code>false</code>), the new node will not have any children or
244      * siblings. If a deep clone is being performed, the new node
245      * will form the root of a complete cloned subtree.
246      *
247      * @param deep if <code>true</code>, recursively clone the subtree
248      * under the specified node; if <code>false</code>, clone only the
249      * node itself.
250      *
251      * @return the duplicate node.
252      */

253     public Node JavaDoc cloneNode(boolean deep) {
254         return new HashMapElement(this, deep);
255     }
256
257
258
259     /**
260      * Returns all <code>Element</code> nodes with given name,
261      * searching by all sub nodes from this node.
262      *
263      * @param name tag name.
264      *
265      * @return all <code>Element</code> vith given name as <code>NodeList</code>.
266      */

267     public NodeList JavaDoc getElementsByTagName(String JavaDoc name) {
268         List JavaDoc list = new ArrayList JavaDoc();
269
270         // added for new search
271
if (nodeName.equals(name)) {
272             list.add(this);
273         }
274
275         getElementsByTagName(name, list);
276         return new NodeListImpl(list);
277     }
278
279
280     private void getElementsByTagName(String JavaDoc name, List JavaDoc list) {
281         if (numChildren == 0)
282             return;
283         List JavaDoc fList = (List JavaDoc) children.get(name);
284         if (fList != null);
285         list.addAll(fList);
286         for (Iterator JavaDoc iter = children.values().iterator(); iter.hasNext();) {
287             fList = (List JavaDoc) iter.next();
288             for (int i = 0; i < fList.size(); i++) {
289                 ((HashMapElement) fList.get(i)).getElementsByTagName(
290                     name,
291                     list);
292             }
293         }
294     }
295
296
297     /**
298      * Returns <code>true</code> if this node has child nodes.
299      *
300      * @return <code>true</code> if this node has children.
301      */

302     public boolean hasElementChildNodes() {
303         return children.size() > 0;
304     }
305
306
307     /**
308      * Returns the list of all children nodes with the given tag name.
309      *
310      * @param name tag name.
311      *
312      * @return the list of all children nodes with the given tag name.
313      */

314     public NodeList JavaDoc getChildrenByTagName(String JavaDoc name) {
315         List JavaDoc list = (List JavaDoc) this.children.get(name);
316         if (list != null)
317             return new NodeListImpl(list);
318         return null;
319     }
320
321
322     /**
323      * Returns the first child <code>Element</code> with the given tag name.
324      *
325      * @param name tag name.
326      *
327      * @return the first child <code>Element</code> with the given tag name.
328      */

329     public Element JavaDoc getFirstChildByTagName(String JavaDoc name) {
330         NodeList JavaDoc children = getChildrenByTagName(name);
331         if (children != null && children.getLength() > 0)
332             return (HashMapElement) children.item(0);
333         return null;
334     }
335
336
337     /**
338      * Returns the next <code>Element</code> node (if exists) with the same tag name.
339      *
340      * @return the next <code>Element</code> node (if exists) with the same tag name.
341      */

342     public Element JavaDoc getNextSameNameNode() {
343         try {
344             HashMapElement parent = (HashMapElement) this.getParentNode();
345             List JavaDoc tagList = (List JavaDoc) parent.children.get(this.nodeName);
346             int index = tagList.indexOf(this);
347             if (++index <= tagList.size())
348                 return (HashMapElement) tagList.get(index);
349         } catch (NullPointerException JavaDoc e) {
350             throw new NodeDOMException(
351                 DOMException.NOT_FOUND_ERR,
352                 "Root node doesn't have a successor");
353         }
354         return null;
355     }
356
357
358     /**
359      * Returns the concatenation of values of all text type children.
360      *
361      * @return the concatenation of values of all text type children.
362      */

363     public String JavaDoc getText() {
364         String JavaDoc text = "";
365         Node JavaDoc child = this.getFirstChild();
366         while (child != null) {
367             if (child.getNodeType() == Node.TEXT_NODE)
368                 text += child.getNodeValue();
369             child = child.getNextSibling();
370         }
371         if (!text.equals(""))
372             return text;
373         return null;
374     }
375
376
377     /**
378      * Set the value of the first text child node to the given text,
379      * and remove all other text child nodes.
380      *
381      * @param text new text.
382      */

383     public void setText(String JavaDoc text) {
384         Node JavaDoc child = this.getFirstChild();
385         if (child != null) {
386             child.setNodeValue(text);
387             child = child.getNextSibling();
388             while (child != null) {
389                 if (child.getNodeType() == Node.TEXT_NODE) {
390                     Node JavaDoc temp = child;
391                     child = child.getNextSibling();
392                     this.removeChild(temp);
393                 } else {
394                     child = child.getNextSibling();
395                 }
396             }
397         }
398     }
399
400
401 }
Popular Tags