001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.helpers;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.io.StringReader;
024:
025: import javax.xml.parsers.DocumentBuilder;
026: import javax.xml.parsers.DocumentBuilderFactory;
027: import javax.xml.parsers.ParserConfigurationException;
028: import javax.xml.transform.OutputKeys;
029: import javax.xml.transform.Transformer;
030: import javax.xml.transform.TransformerException;
031: import javax.xml.transform.TransformerFactory;
032: import javax.xml.transform.dom.DOMSource;
033: import javax.xml.transform.stream.StreamResult;
034: import javax.xml.transform.stream.StreamSource;
035:
036: import org.w3c.dom.Document;
037: import org.w3c.dom.Element;
038: import org.w3c.dom.NamedNodeMap;
039: import org.w3c.dom.Node;
040:
041: import org.xml.sax.EntityResolver;
042: import org.xml.sax.InputSource;
043: import org.xml.sax.SAXException;
044:
045: /**
046: * Few simple utils to read DOM. This is originally from the Jakarta Commons
047: * Modeler.
048: *
049: * @author Costin Manolache
050: */
051: public final class DOMUtils {
052: static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory
053: .newInstance();
054: static DocumentBuilder builder;
055:
056: private DOMUtils() {
057: }
058:
059: private static synchronized DocumentBuilder getBuilder()
060: throws ParserConfigurationException {
061: if (builder == null) {
062: FACTORY.setNamespaceAware(true);
063: builder = FACTORY.newDocumentBuilder();
064: }
065: return builder;
066: }
067:
068: /**
069: * Get the trimed text content of a node or null if there is no text
070: */
071: public static String getContent(Node n) {
072: if (n == null) {
073: return null;
074: }
075:
076: Node n1 = DOMUtils.getChild(n, Node.TEXT_NODE);
077:
078: if (n1 == null) {
079: return null;
080: }
081:
082: return n1.getNodeValue().trim();
083: }
084:
085: /**
086: * Get the raw text content of a node or null if there is no text
087: */
088: public static String getRawContent(Node n) {
089: if (n == null) {
090: return null;
091: }
092:
093: Node n1 = DOMUtils.getChild(n, Node.TEXT_NODE);
094:
095: if (n1 == null) {
096: return null;
097: }
098:
099: return n1.getNodeValue();
100: }
101:
102: /**
103: * Get the first element child.
104: *
105: * @param parent lookup direct childs
106: * @param name name of the element. If null return the first element.
107: */
108: public static Node getChild(Node parent, String name) {
109: if (parent == null) {
110: return null;
111: }
112:
113: Node first = parent.getFirstChild();
114: if (first == null) {
115: return null;
116: }
117:
118: for (Node node = first; node != null; node = node
119: .getNextSibling()) {
120: // System.out.println("getNode: " + name + " " +
121: // node.getNodeName());
122: if (node.getNodeType() != Node.ELEMENT_NODE) {
123: continue;
124: }
125: if (name != null && name.equals(node.getNodeName())) {
126: return node;
127: }
128: if (name == null) {
129: return node;
130: }
131: }
132: return null;
133: }
134:
135: public static String getAttribute(Node element, String attName) {
136: NamedNodeMap attrs = element.getAttributes();
137: if (attrs == null) {
138: return null;
139: }
140: Node attN = attrs.getNamedItem(attName);
141: if (attN == null) {
142: return null;
143: }
144: return attN.getNodeValue();
145: }
146:
147: public static void setAttribute(Node node, String attName,
148: String val) {
149: NamedNodeMap attributes = node.getAttributes();
150: Node attNode = node.getOwnerDocument().createAttribute(attName);
151: attNode.setNodeValue(val);
152: attributes.setNamedItem(attNode);
153: }
154:
155: public static void removeAttribute(Node node, String attName) {
156: NamedNodeMap attributes = node.getAttributes();
157: attributes.removeNamedItem(attName);
158: }
159:
160: /**
161: * Set or replace the text value
162: */
163: public static void setText(Node node, String val) {
164: Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
165: if (chld == null) {
166: Node textN = node.getOwnerDocument().createTextNode(val);
167: node.appendChild(textN);
168: return;
169: }
170: // change the value
171: chld.setNodeValue(val);
172: }
173:
174: /**
175: * Find the first direct child with a given attribute.
176: *
177: * @param parent
178: * @param elemName name of the element, or null for any
179: * @param attName attribute we're looking for
180: * @param attVal attribute value or null if we just want any
181: */
182: public static Node findChildWithAtt(Node parent, String elemName,
183: String attName, String attVal) {
184:
185: Node child = DOMUtils.getChild(parent, Node.ELEMENT_NODE);
186: if (attVal == null) {
187: while (child != null
188: && (elemName == null || elemName.equals(child
189: .getNodeName()))
190: && DOMUtils.getAttribute(child, attName) != null) {
191: child = getNext(child, elemName, Node.ELEMENT_NODE);
192: }
193: } else {
194: while (child != null
195: && (elemName == null || elemName.equals(child
196: .getNodeName()))
197: && !attVal.equals(DOMUtils.getAttribute(child,
198: attName))) {
199: child = getNext(child, elemName, Node.ELEMENT_NODE);
200: }
201: }
202: return child;
203: }
204:
205: /**
206: * Get the first child's content ( ie it's included TEXT node ).
207: */
208: public static String getChildContent(Node parent, String name) {
209: Node first = parent.getFirstChild();
210: if (first == null) {
211: return null;
212: }
213: for (Node node = first; node != null; node = node
214: .getNextSibling()) {
215: // System.out.println("getNode: " + name + " " +
216: // node.getNodeName());
217: if (name.equals(node.getNodeName())) {
218: return getContent(node);
219: }
220: }
221: return null;
222: }
223:
224: /**
225: * Get the first direct child with a given type
226: */
227: public static Element getFirstElement(Node parent) {
228: Node n = parent.getFirstChild();
229: while (n != null && Node.ELEMENT_NODE != n.getNodeType()) {
230: n = n.getNextSibling();
231: }
232: if (n == null) {
233: return null;
234: }
235: return (Element) n;
236: }
237:
238: /**
239: * Get the first direct child with a given type
240: */
241: public static Node getChild(Node parent, int type) {
242: Node n = parent.getFirstChild();
243: while (n != null && type != n.getNodeType()) {
244: n = n.getNextSibling();
245: }
246: if (n == null) {
247: return null;
248: }
249: return n;
250: }
251:
252: /**
253: * Get the next sibling with the same name and type
254: */
255: public static Node getNext(Node current) {
256: String name = current.getNodeName();
257: int type = current.getNodeType();
258: return getNext(current, name, type);
259: }
260:
261: /**
262: * Return the next sibling with a given name and type
263: */
264: public static Node getNext(Node current, String name, int type) {
265: Node first = current.getNextSibling();
266: if (first == null) {
267: return null;
268: }
269:
270: for (Node node = first; node != null; node = node
271: .getNextSibling()) {
272:
273: if (type >= 0 && node.getNodeType() != type) {
274: continue;
275: }
276: // System.out.println("getNode: " + name + " " +
277: // node.getNodeName());
278: if (name == null) {
279: return node;
280: }
281: if (name.equals(node.getNodeName())) {
282: return node;
283: }
284: }
285: return null;
286: }
287:
288: public static class NullResolver implements EntityResolver {
289: public InputSource resolveEntity(String publicId,
290: String systemId) throws SAXException, IOException {
291: return new InputSource(new StringReader(""));
292: }
293: }
294:
295: /**
296: * Read XML as DOM.
297: */
298: public static Document readXml(InputStream is) throws SAXException,
299: IOException, ParserConfigurationException {
300: DocumentBuilderFactory dbf = DocumentBuilderFactory
301: .newInstance();
302:
303: dbf.setValidating(false);
304: dbf.setIgnoringComments(false);
305: dbf.setIgnoringElementContentWhitespace(true);
306: dbf.setNamespaceAware(true);
307: // dbf.setCoalescing(true);
308: // dbf.setExpandEntityReferences(true);
309:
310: DocumentBuilder db = null;
311: db = dbf.newDocumentBuilder();
312: db.setEntityResolver(new NullResolver());
313:
314: // db.setErrorHandler( new MyErrorHandler());
315:
316: return db.parse(is);
317: }
318:
319: public static Document readXml(StreamSource is)
320: throws SAXException, IOException,
321: ParserConfigurationException {
322:
323: DocumentBuilderFactory dbf = DocumentBuilderFactory
324: .newInstance();
325:
326: dbf.setValidating(false);
327: dbf.setIgnoringComments(false);
328: dbf.setIgnoringElementContentWhitespace(true);
329: dbf.setNamespaceAware(true);
330: // dbf.setCoalescing(true);
331: // dbf.setExpandEntityReferences(true);
332:
333: DocumentBuilder db = null;
334: db = dbf.newDocumentBuilder();
335: db.setEntityResolver(new NullResolver());
336:
337: // db.setErrorHandler( new MyErrorHandler());
338: InputSource is2 = new InputSource();
339: is2.setSystemId(is.getSystemId());
340: is2.setByteStream(is.getInputStream());
341: is2.setCharacterStream(is.getReader());
342:
343: return db.parse(is2);
344: }
345:
346: public static void writeXml(Node n, OutputStream os)
347: throws TransformerException {
348: TransformerFactory tf = TransformerFactory.newInstance();
349: // identity
350: Transformer t = tf.newTransformer();
351: t.setOutputProperty(OutputKeys.INDENT, "yes");
352: t.transform(new DOMSource(n), new StreamResult(os));
353: }
354:
355: public static DocumentBuilder createDocumentBuilder() {
356: try {
357: return FACTORY.newDocumentBuilder();
358: } catch (ParserConfigurationException e) {
359: throw new RuntimeException("Couldn't find a DOM parser.", e);
360: }
361: }
362:
363: public static Document createDocument() {
364: try {
365: return getBuilder().newDocument();
366: } catch (ParserConfigurationException e) {
367: throw new RuntimeException("Couldn't find a DOM parser.", e);
368: }
369: }
370:
371: public static String getUniquePrefix(Element el, String ns) {
372: // TODO Auto-generated method stub
373: return null;
374: }
375:
376: public static String getPrefixRecursive(Element el, String ns) {
377: String prefix = getPrefix(el, ns);
378: if (prefix == null && el.getParentNode() instanceof Element) {
379: prefix = getPrefixRecursive((Element) el.getParentNode(),
380: ns);
381: }
382: return prefix;
383: }
384:
385: public static String getPrefix(Element el, String ns) {
386: NamedNodeMap atts = el.getAttributes();
387: for (int i = 0; i < atts.getLength(); i++) {
388: Node node = atts.item(i);
389: String name = node.getNodeName();
390: if (ns.equals(node.getNodeValue())
391: && (name != null && ("xmlns".equals(name) || name
392: .startsWith("xmlns:")))) {
393: return node.getPrefix();
394: }
395: }
396: return null;
397: }
398:
399: public static String createNamespace(Element el, String ns) {
400: String p = "ns1";
401: int i = 1;
402: while (getPrefix(el, ns) != null) {
403: p = "ns" + i;
404: i++;
405: }
406: el.setAttribute("xmlns:" + p, ns);
407: return p;
408: }
409:
410: public static String getNamespace(Element el, String pre) {
411: NamedNodeMap atts = el.getAttributes();
412: for (int i = 0; i < atts.getLength(); i++) {
413: Node node = atts.item(i);
414: String name = node.getLocalName();
415: String pre2 = node.getPrefix();
416: if (pre.equals(name) && "xmlns".equals(pre2)) {
417: return node.getNodeValue();
418: } else if (pre.length() == 0 && "xmlns".equals(name)
419: && pre2.length() == 0) {
420: return node.getNodeValue();
421: }
422: }
423:
424: Node parent = el.getParentNode();
425: if (parent instanceof Element) {
426: return getNamespace((Element) parent, pre);
427: }
428:
429: return null;
430: }
431: }
|