KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > junit > DOMUtil


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.junit;
19
20 import java.util.Vector JavaDoc;
21 import org.w3c.dom.Attr JavaDoc;
22 import org.w3c.dom.CDATASection JavaDoc;
23 import org.w3c.dom.Comment JavaDoc;
24 import org.w3c.dom.DOMException JavaDoc;
25 import org.w3c.dom.Document JavaDoc;
26 import org.w3c.dom.Element JavaDoc;
27 import org.w3c.dom.NamedNodeMap JavaDoc;
28 import org.w3c.dom.Node JavaDoc;
29 import org.w3c.dom.NodeList JavaDoc;
30 import org.w3c.dom.ProcessingInstruction JavaDoc;
31 import org.w3c.dom.Text JavaDoc;
32
33 /**
34  * Some utilities that might be useful when manipulating DOM trees.
35  *
36  */

37 public final class DOMUtil {
38
39     /** unused constructor */
40     private DOMUtil() {
41     }
42
43     /**
44      * Filter interface to be applied when iterating over a DOM tree.
45      * Just think of it like a <tt>FileFilter</tt> clone.
46      */

47     public interface NodeFilter {
48         /**
49          * @param node the node to check for acceptance.
50          * @return <tt>true</tt> if the node is accepted by this filter,
51          * otherwise <tt>false</tt>
52          */

53         boolean accept(Node JavaDoc node);
54     }
55
56     /**
57      * list a set of node that match a specific filter. The list can be made
58      * recursively or not.
59      * @param parent the parent node to search from
60      * @param filter the filter that children should match.
61      * @param recurse <tt>true</tt> if you want the list to be made recursively
62      * otherwise <tt>false</tt>.
63      * @return the node list that matches the filter.
64      */

65     public static NodeList JavaDoc listChildNodes(Node JavaDoc parent, NodeFilter filter, boolean recurse) {
66         NodeListImpl matches = new NodeListImpl();
67         NodeList JavaDoc children = parent.getChildNodes();
68         if (children != null) {
69             final int len = children.getLength();
70             for (int i = 0; i < len; i++) {
71                 Node JavaDoc child = children.item(i);
72                 if (filter.accept(child)) {
73                     matches.addElement(child);
74                 }
75                 if (recurse) {
76                     NodeList JavaDoc recmatches = listChildNodes(child, filter, recurse);
77                     final int reclength = recmatches.getLength();
78                     for (int j = 0; j < reclength; j++) {
79                         matches.addElement(recmatches.item(i));
80                     }
81                 }
82             }
83         }
84         return matches;
85     }
86
87     /** custom implementation of a nodelist */
88     public static class NodeListImpl extends Vector JavaDoc implements NodeList JavaDoc {
89         /**
90          * Get the number of nodes in the list.
91          * @return the length of the list.
92          */

93         public int getLength() {
94             return size();
95         }
96         /**
97          * Get a particular node.
98          * @param i the index of the node to get.
99          * @return the node if the index is in bounds, null otherwise.
100          */

101         public Node JavaDoc item(int i) {
102             try {
103                 return (Node JavaDoc) elementAt(i);
104             } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
105                 return null; // conforming to NodeList interface
106
}
107         }
108     }
109
110     /**
111      * return the attribute value of an element.
112      * @param node the node to get the attribute from.
113      * @param name the name of the attribute we are looking for the value.
114      * @return the value of the requested attribute or <tt>null</tt> if the
115      * attribute was not found or if <tt>node</tt> is not an <tt>Element</tt>.
116      */

117     public static String JavaDoc getNodeAttribute(Node JavaDoc node, String JavaDoc name) {
118         if (node instanceof Element JavaDoc) {
119             Element JavaDoc element = (Element JavaDoc) node;
120             return element.getAttribute(name);
121         }
122         return null;
123     }
124
125
126     /**
127      * Iterate over the children of a given node and return the first node
128      * that has a specific name.
129      * @param parent the node to search child from. Can be <tt>null</tt>.
130      * @param tagname the child name we are looking for. Cannot be <tt>null</tt>.
131      * @return the first child that matches the given name or <tt>null</tt> if
132      * the parent is <tt>null</tt> or if a child does not match the
133      * given name.
134      */

135     public static Element JavaDoc getChildByTagName (Node JavaDoc parent, String JavaDoc tagname) {
136         if (parent == null) {
137             return null;
138         }
139         NodeList JavaDoc childList = parent.getChildNodes();
140         final int len = childList.getLength();
141         for (int i = 0; i < len; i++) {
142             Node JavaDoc child = childList.item(i);
143             if (child != null && child.getNodeType() == Node.ELEMENT_NODE
144                 && child.getNodeName().equals(tagname)) {
145                 return (Element JavaDoc) child;
146             }
147         }
148         return null;
149     }
150
151     /**
152      * Simple tree walker that will clone recursively a node. This is to
153      * avoid using parser-specific API such as Sun's <tt>changeNodeOwner</tt>
154      * when we are dealing with DOM L1 implementations since <tt>cloneNode(boolean)</tt>
155      * will not change the owner document.
156      * <tt>changeNodeOwner</tt> is much faster and avoid the costly cloning process.
157      * <tt>importNode</tt> is in the DOM L2 interface.
158      * @param parent the node parent to which we should do the import to.
159      * @param child the node to clone recursively. Its clone will be
160      * appended to <tt>parent</tt>.
161      * @return the cloned node that is appended to <tt>parent</tt>
162      */

163     public static Node JavaDoc importNode(Node JavaDoc parent, Node JavaDoc child) {
164         Node JavaDoc copy = null;
165         final Document JavaDoc doc = parent.getOwnerDocument();
166
167         switch (child.getNodeType()) {
168         case Node.CDATA_SECTION_NODE:
169             copy = doc.createCDATASection(((CDATASection JavaDoc) child).getData());
170             break;
171         case Node.COMMENT_NODE:
172             copy = doc.createComment(((Comment JavaDoc) child).getData());
173             break;
174         case Node.DOCUMENT_FRAGMENT_NODE:
175             copy = doc.createDocumentFragment();
176             break;
177         case Node.ELEMENT_NODE:
178             final Element JavaDoc elem = doc.createElement(((Element JavaDoc) child).getTagName());
179             copy = elem;
180             final NamedNodeMap JavaDoc attributes = child.getAttributes();
181             if (attributes != null) {
182                 final int size = attributes.getLength();
183                 for (int i = 0; i < size; i++) {
184                     final Attr JavaDoc attr = (Attr JavaDoc) attributes.item(i);
185                     elem.setAttribute(attr.getName(), attr.getValue());
186                 }
187             }
188             break;
189         case Node.ENTITY_REFERENCE_NODE:
190             copy = doc.createEntityReference(child.getNodeName());
191             break;
192         case Node.PROCESSING_INSTRUCTION_NODE:
193             final ProcessingInstruction JavaDoc pi = (ProcessingInstruction JavaDoc) child;
194             copy = doc.createProcessingInstruction(pi.getTarget(), pi.getData());
195             break;
196         case Node.TEXT_NODE:
197             copy = doc.createTextNode(((Text JavaDoc) child).getData());
198             break;
199         default:
200             // this should never happen
201
throw new IllegalStateException JavaDoc("Invalid node type: " + child.getNodeType());
202         }
203
204         // okay we have a copy of the child, now the child becomes the parent
205
// and we are iterating recursively over its children.
206
try {
207             final NodeList JavaDoc children = child.getChildNodes();
208             if (children != null) {
209                 final int size = children.getLength();
210                 for (int i = 0; i < size; i++) {
211                     final Node JavaDoc newChild = children.item(i);
212                     if (newChild != null) {
213                         importNode(copy, newChild);
214                     }
215                 }
216             }
217         } catch (DOMException JavaDoc ignored) {
218             // Ignore
219
}
220
221         // bingo append it. (this should normally not be done here)
222
parent.appendChild(copy);
223         return copy;
224     }
225 }
226
Popular Tags