1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codehaus.xfire.util;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.io.StringReader;
22
23 import javax.xml.parsers.DocumentBuilder;
24 import javax.xml.parsers.DocumentBuilderFactory;
25 import javax.xml.parsers.ParserConfigurationException;
26 import javax.xml.transform.OutputKeys;
27 import javax.xml.transform.Transformer;
28 import javax.xml.transform.TransformerException;
29 import javax.xml.transform.TransformerFactory;
30 import javax.xml.transform.dom.DOMSource;
31 import javax.xml.transform.stream.StreamResult;
32
33 import org.codehaus.xfire.XFireRuntimeException;
34 import org.w3c.dom.Document;
35 import org.w3c.dom.NamedNodeMap;
36 import org.w3c.dom.Node;
37 import org.xml.sax.EntityResolver;
38 import org.xml.sax.InputSource;
39 import org.xml.sax.SAXException;
40
41 /***
42 * Few simple utils to read DOM. This is originally from the Jakarta Commons
43 * Modeler.
44 *
45 * @author Costin Manolache
46 */
47 public class DOMUtils
48 {
49 /***
50 * Get the trimed text content of a node or null if there is no text
51 */
52 public static String getContent(Node n)
53 {
54 if (n == null)
55 return null;
56 Node n1 = DOMUtils.getChild(n, Node.TEXT_NODE);
57
58 if (n1 == null)
59 return null;
60
61 String s1 = n1.getNodeValue();
62 return s1.trim();
63 }
64
65 /***
66 * Get the first element child.
67 *
68 * @param parent
69 * lookup direct childs
70 * @param name
71 * name of the element. If null return the first element.
72 */
73 public static Node getChild(Node parent, String name)
74 {
75 if (parent == null)
76 return null;
77 Node first = parent.getFirstChild();
78 if (first == null)
79 return null;
80
81 for (Node node = first; node != null; node = node.getNextSibling())
82 {
83
84
85 if (node.getNodeType() != Node.ELEMENT_NODE)
86 continue;
87 if (name != null && name.equals(node.getNodeName()))
88 {
89 return node;
90 }
91 if (name == null)
92 {
93 return node;
94 }
95 }
96 return null;
97 }
98
99 public static String getAttribute(Node element, String attName)
100 {
101 NamedNodeMap attrs = element.getAttributes();
102 if (attrs == null)
103 return null;
104 Node attN = attrs.getNamedItem(attName);
105 if (attN == null)
106 return null;
107 return attN.getNodeValue();
108 }
109
110 public static void setAttribute(Node node, String attName, String val)
111 {
112 NamedNodeMap attributes = node.getAttributes();
113 Node attNode = node.getOwnerDocument().createAttribute(attName);
114 attNode.setNodeValue(val);
115 attributes.setNamedItem(attNode);
116 }
117
118 public static void removeAttribute(Node node, String attName)
119 {
120 NamedNodeMap attributes = node.getAttributes();
121 attributes.removeNamedItem(attName);
122 }
123
124 /***
125 * Set or replace the text value
126 */
127 public static void setText(Node node, String val)
128 {
129 Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
130 if (chld == null)
131 {
132 Node textN = node.getOwnerDocument().createTextNode(val);
133 node.appendChild(textN);
134 return;
135 }
136
137 chld.setNodeValue(val);
138 }
139
140 /***
141 * Find the first direct child with a given attribute.
142 *
143 * @param parent
144 * @param elemName
145 * name of the element, or null for any
146 * @param attName
147 * attribute we're looking for
148 * @param attVal
149 * attribute value or null if we just want any
150 */
151 public static Node findChildWithAtt(Node parent, String elemName,
152 String attName, String attVal)
153 {
154
155 Node child = DOMUtils.getChild(parent, Node.ELEMENT_NODE);
156 if (attVal == null)
157 {
158 while (child != null
159 && (elemName == null || elemName
160 .equals(child.getNodeName()))
161 && DOMUtils.getAttribute(child, attName) != null)
162 {
163 child = getNext(child, elemName, Node.ELEMENT_NODE);
164 }
165 }
166 else
167 {
168 while (child != null
169 && (elemName == null || elemName
170 .equals(child.getNodeName()))
171 && !attVal.equals(DOMUtils.getAttribute(child, attName)))
172 {
173 child = getNext(child, elemName, Node.ELEMENT_NODE);
174 }
175 }
176 return child;
177 }
178
179 /***
180 * Get the first child's content ( ie it's included TEXT node ).
181 */
182 public static String getChildContent(Node parent, String name)
183 {
184 Node first = parent.getFirstChild();
185 if (first == null)
186 return null;
187 for (Node node = first; node != null; node = node.getNextSibling())
188 {
189
190
191 if (name.equals(node.getNodeName()))
192 {
193 return getContent(node);
194 }
195 }
196 return null;
197 }
198
199 /***
200 * Get the first direct child with a given type
201 */
202 public static Node getChild(Node parent, int type)
203 {
204 Node n = parent.getFirstChild();
205 while (n != null && type != n.getNodeType())
206 {
207 n = n.getNextSibling();
208 }
209 if (n == null)
210 return null;
211 return n;
212 }
213
214 /***
215 * Get the next sibling with the same name and type
216 */
217 public static Node getNext(Node current)
218 {
219 String name = current.getNodeName();
220 int type = current.getNodeType();
221 return getNext(current, name, type);
222 }
223
224 /***
225 * Return the next sibling with a given name and type
226 */
227 public static Node getNext(Node current, String name, int type)
228 {
229 Node first = current.getNextSibling();
230 if (first == null)
231 return null;
232
233 for (Node node = first; node != null; node = node.getNextSibling())
234 {
235
236 if (type >= 0 && node.getNodeType() != type)
237 continue;
238
239
240 if (name == null)
241 return node;
242 if (name.equals(node.getNodeName()))
243 {
244 return node;
245 }
246 }
247 return null;
248 }
249
250 public static class NullResolver implements EntityResolver
251 {
252 public InputSource resolveEntity(String publicId, String systemId)
253 throws SAXException, IOException
254 {
255 return new InputSource(new StringReader(""));
256 }
257 }
258
259 /***
260 * Read XML as DOM.
261 */
262 public static Document readXml(InputStream is) throws SAXException,
263 IOException, ParserConfigurationException
264 {
265 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
266
267 dbf.setValidating(false);
268 dbf.setIgnoringComments(false);
269 dbf.setIgnoringElementContentWhitespace(true);
270 dbf.setNamespaceAware(true);
271
272
273
274 DocumentBuilder db = null;
275 db = dbf.newDocumentBuilder();
276 db.setEntityResolver(new NullResolver());
277
278
279
280 Document doc = db.parse(is);
281 return doc;
282 }
283
284 public static void writeXml(Node n, OutputStream os)
285 throws TransformerException
286 {
287 TransformerFactory tf = TransformerFactory.newInstance();
288
289 Transformer t = tf.newTransformer();
290 t.setOutputProperty(OutputKeys.INDENT, "yes");
291 t.transform(new DOMSource(n), new StreamResult(os));
292 }
293
294 public static Document createDocument()
295 {
296 try
297 {
298 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
299 DocumentBuilder b = factory.newDocumentBuilder();
300
301 return b.newDocument();
302 }
303 catch (ParserConfigurationException e)
304 {
305 throw new XFireRuntimeException("Couldn't find a DOM parser.", e);
306 }
307 }
308 }