source: release-kits/lirk3/bin/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 8.2 KB
Line 
1/*
2 * Copyright 2001-2002,2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.optional.junit;
18
19import java.util.Vector;
20import org.w3c.dom.Attr;
21import org.w3c.dom.CDATASection;
22import org.w3c.dom.Comment;
23import org.w3c.dom.DOMException;
24import org.w3c.dom.Document;
25import org.w3c.dom.Element;
26import org.w3c.dom.NamedNodeMap;
27import org.w3c.dom.Node;
28import org.w3c.dom.NodeList;
29import org.w3c.dom.ProcessingInstruction;
30import org.w3c.dom.Text;
31
32/**
33 * Some utilities that might be useful when manipulating DOM trees.
34 *
35 */
36public final class DOMUtil {
37
38 /** unused constructor */
39 private DOMUtil() {
40 }
41
42 /**
43 * Filter interface to be applied when iterating over a DOM tree.
44 * Just think of it like a <tt>FileFilter</tt> clone.
45 */
46 public interface NodeFilter {
47 /**
48 * @param node the node to check for acceptance.
49 * @return <tt>true</tt> if the node is accepted by this filter,
50 * otherwise <tt>false</tt>
51 */
52 boolean accept(Node node);
53 }
54
55 /**
56 * list a set of node that match a specific filter. The list can be made
57 * recursively or not.
58 * @param parent the parent node to search from
59 * @param filter the filter that children should match.
60 * @param recurse <tt>true</tt> if you want the list to be made recursively
61 * otherwise <tt>false</tt>.
62 */
63 public static NodeList listChildNodes(Node parent, NodeFilter filter, boolean recurse) {
64 NodeListImpl matches = new NodeListImpl();
65 NodeList children = parent.getChildNodes();
66 if (children != null) {
67 final int len = children.getLength();
68 for (int i = 0; i < len; i++) {
69 Node child = children.item(i);
70 if (filter.accept(child)) {
71 matches.addElement(child);
72 }
73 if (recurse) {
74 NodeList recmatches = listChildNodes(child, filter, recurse);
75 final int reclength = matches.getLength();
76 for (int j = 0; j < reclength; j++) {
77 matches.addElement(recmatches.item(i));
78 }
79 }
80 }
81 }
82 return matches;
83 }
84
85 /** custom implementation of a nodelist */
86 public static class NodeListImpl extends Vector implements NodeList {
87 public int getLength() {
88 return size();
89 }
90 public Node item(int i) {
91 try {
92 return (Node) elementAt(i);
93 } catch (ArrayIndexOutOfBoundsException e) {
94 return null; // conforming to NodeList interface
95 }
96 }
97 }
98
99 /**
100 * return the attribute value of an element.
101 * @param node the node to get the attribute from.
102 * @param name the name of the attribute we are looking for the value.
103 * @return the value of the requested attribute or <tt>null</tt> if the
104 * attribute was not found or if <tt>node</tt> is not an <tt>Element</tt>.
105 */
106 public static String getNodeAttribute(Node node, String name) {
107 if (node instanceof Element) {
108 Element element = (Element) node;
109 return element.getAttribute(name);
110 }
111 return null;
112 }
113
114
115 /**
116 * Iterate over the children of a given node and return the first node
117 * that has a specific name.
118 * @param parent the node to search child from. Can be <tt>null</tt>.
119 * @param tagname the child name we are looking for. Cannot be <tt>null</tt>.
120 * @return the first child that matches the given name or <tt>null</tt> if
121 * the parent is <tt>null</tt> or if a child does not match the
122 * given name.
123 */
124 public static Element getChildByTagName (Node parent, String tagname) {
125 if (parent == null) {
126 return null;
127 }
128 NodeList childList = parent.getChildNodes();
129 final int len = childList.getLength();
130 for (int i = 0; i < len; i++) {
131 Node child = childList.item(i);
132 if (child != null && child.getNodeType() == Node.ELEMENT_NODE
133 && child.getNodeName().equals(tagname)) {
134 return (Element) child;
135 }
136 }
137 return null;
138 }
139
140 /**
141 * Simple tree walker that will clone recursively a node. This is to
142 * avoid using parser-specific API such as Sun's <tt>changeNodeOwner</tt>
143 * when we are dealing with DOM L1 implementations since <tt>cloneNode(boolean)</tt>
144 * will not change the owner document.
145 * <tt>changeNodeOwner</tt> is much faster and avoid the costly cloning process.
146 * <tt>importNode</tt> is in the DOM L2 interface.
147 * @param parent the node parent to which we should do the import to.
148 * @param child the node to clone recursively. Its clone will be
149 * appended to <tt>parent</tt>.
150 * @return the cloned node that is appended to <tt>parent</tt>
151 */
152 public static final Node importNode(Node parent, Node child) {
153 Node copy = null;
154 final Document doc = parent.getOwnerDocument();
155
156 switch (child.getNodeType()) {
157 case Node.CDATA_SECTION_NODE:
158 copy = doc.createCDATASection(((CDATASection) child).getData());
159 break;
160 case Node.COMMENT_NODE:
161 copy = doc.createComment(((Comment) child).getData());
162 break;
163 case Node.DOCUMENT_FRAGMENT_NODE:
164 copy = doc.createDocumentFragment();
165 break;
166 case Node.ELEMENT_NODE:
167 final Element elem = doc.createElement(((Element) child).getTagName());
168 copy = elem;
169 final NamedNodeMap attributes = child.getAttributes();
170 if (attributes != null) {
171 final int size = attributes.getLength();
172 for (int i = 0; i < size; i++) {
173 final Attr attr = (Attr) attributes.item(i);
174 elem.setAttribute(attr.getName(), attr.getValue());
175 }
176 }
177 break;
178 case Node.ENTITY_REFERENCE_NODE:
179 copy = doc.createEntityReference(child.getNodeName());
180 break;
181 case Node.PROCESSING_INSTRUCTION_NODE:
182 final ProcessingInstruction pi = (ProcessingInstruction) child;
183 copy = doc.createProcessingInstruction(pi.getTarget(), pi.getData());
184 break;
185 case Node.TEXT_NODE:
186 copy = doc.createTextNode(((Text) child).getData());
187 break;
188 default:
189 // this should never happen
190 throw new IllegalStateException("Invalid node type: " + child.getNodeType());
191 }
192
193 // okay we have a copy of the child, now the child becomes the parent
194 // and we are iterating recursively over its children.
195 try {
196 final NodeList children = child.getChildNodes();
197 if (children != null) {
198 final int size = children.getLength();
199 for (int i = 0; i < size; i++) {
200 final Node newChild = children.item(i);
201 if (newChild != null) {
202 importNode(copy, newChild);
203 }
204 }
205 }
206 } catch (DOMException ignored) {
207 }
208
209 // bingo append it. (this should normally not be done here)
210 parent.appendChild(copy);
211 return copy;
212 }
213}
Note: See TracBrowser for help on using the repository browser.