001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.servicemix.jbi.util;
018:
019: import java.io.StringWriter;
020: import java.util.Queue;
021: import java.util.concurrent.ConcurrentLinkedQueue;
022:
023: import javax.xml.namespace.QName;
024: import javax.xml.parsers.DocumentBuilder;
025: import javax.xml.parsers.DocumentBuilderFactory;
026: import javax.xml.parsers.ParserConfigurationException;
027: import javax.xml.transform.OutputKeys;
028: import javax.xml.transform.Transformer;
029: import javax.xml.transform.TransformerException;
030: import javax.xml.transform.TransformerFactory;
031: import javax.xml.transform.dom.DOMSource;
032: import javax.xml.transform.stream.StreamResult;
033:
034: import org.w3c.dom.Attr;
035: import org.w3c.dom.Document;
036: import org.w3c.dom.Element;
037: import org.w3c.dom.NamedNodeMap;
038: import org.w3c.dom.Node;
039: import org.w3c.dom.NodeList;
040:
041: import org.apache.commons.logging.Log;
042: import org.apache.commons.logging.LogFactory;
043:
044: /**
045: * A collection of W3C DOM helper methods
046: *
047: * @version $Revision: 564607 $
048: */
049: public final class DOMUtil {
050:
051: private static final Log LOG = LogFactory.getLog(DOMUtil.class);
052: private static DocumentBuilderFactory dbf;
053: private static Queue builders = new ConcurrentLinkedQueue();
054:
055: private DOMUtil() {
056: }
057:
058: /**
059: * Returns the text of the element
060: */
061: public static String getElementText(Element element) {
062: StringBuffer buffer = new StringBuffer();
063: NodeList nodeList = element.getChildNodes();
064: for (int i = 0; i < nodeList.getLength(); i++) {
065: Node node = nodeList.item(i);
066: if (node.getNodeType() == Node.TEXT_NODE
067: || node.getNodeType() == Node.CDATA_SECTION_NODE) {
068: buffer.append(node.getNodeValue());
069: }
070: }
071: return buffer.toString();
072: }
073:
074: /**
075: * Moves the content of the given element to the given element
076: */
077: public static void moveContent(Element from, Element to) {
078: // lets move the child nodes across
079: NodeList childNodes = from.getChildNodes();
080: while (childNodes.getLength() > 0) {
081: Node node = childNodes.item(0);
082: from.removeChild(node);
083: to.appendChild(node);
084: }
085: }
086:
087: /**
088: * Copy the attribues on one element to the other
089: */
090: public static void copyAttributes(Element from, Element to) {
091: // lets copy across all the remainingattributes
092: NamedNodeMap attributes = from.getAttributes();
093: for (int i = 0; i < attributes.getLength(); i++) {
094: Attr node = (Attr) attributes.item(i);
095: to.setAttributeNS(node.getNamespaceURI(), node.getName(),
096: node.getValue());
097: }
098: }
099:
100: /**
101: * A helper method useful for debugging and logging which will convert the given DOM node into XML text
102: */
103: public static String asXML(Node node) throws TransformerException {
104: Transformer transformer = TransformerFactory.newInstance()
105: .newTransformer();
106: StringWriter buffer = new StringWriter();
107: transformer.transform(new DOMSource(node), new StreamResult(
108: buffer));
109: return buffer.toString();
110: }
111:
112: /**
113: * A helper method useful for debugging and logging which will convert the given DOM node into XML text
114: */
115: public static String asIndentedXML(Node node)
116: throws TransformerException {
117: Transformer transformer = TransformerFactory.newInstance()
118: .newTransformer();
119: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
120: StringWriter buffer = new StringWriter();
121: transformer.transform(new DOMSource(node), new StreamResult(
122: buffer));
123: return buffer.toString();
124: }
125:
126: /**
127: * Adds the child element with the given text
128: */
129: public static void addChildElement(Element element, String name,
130: Object textValue) {
131: Document document = element.getOwnerDocument();
132: Element child = document.createElement(name);
133: element.appendChild(child);
134: if (textValue != null) {
135: String text = textValue.toString();
136: child.appendChild(document.createTextNode(text));
137: }
138: }
139:
140: /**
141: * Creates a QName instance from the given namespace context for the given qualifiedName
142: *
143: * @param element the element to use as the namespace context
144: * @param qualifiedName the fully qualified name
145: * @return the QName which matches the qualifiedName
146: */
147: public static QName createQName(Element element,
148: String qualifiedName) {
149: int index = qualifiedName.indexOf(':');
150: if (index >= 0) {
151: String prefix = qualifiedName.substring(0, index);
152: String localName = qualifiedName.substring(index + 1);
153: String uri = recursiveGetAttributeValue(element, "xmlns:"
154: + prefix);
155: return new QName(uri, localName, prefix);
156: } else {
157: String uri = recursiveGetAttributeValue(element, "xmlns");
158: if (uri != null) {
159: return new QName(uri, qualifiedName);
160: }
161: return new QName(qualifiedName);
162: }
163: }
164:
165: /**
166: * Recursive method to find a given attribute value
167: */
168: public static String recursiveGetAttributeValue(Element element,
169: String attributeName) {
170: String answer = null;
171: try {
172: answer = element.getAttribute(attributeName);
173: } catch (Exception e) {
174: if (LOG.isTraceEnabled()) {
175: LOG.trace("Caught exception looking up attribute: "
176: + attributeName + " on element: " + element
177: + ". Cause: " + e, e);
178: }
179: }
180: if (answer == null || answer.length() == 0) {
181: Node parentNode = element.getParentNode();
182: if (parentNode instanceof Element) {
183: return recursiveGetAttributeValue((Element) parentNode,
184: attributeName);
185: }
186: }
187: return answer;
188: }
189:
190: /**
191: * Get the first child element
192: * @param parent
193: * @return
194: */
195: public static Element getFirstChildElement(Node parent) {
196: NodeList childs = parent.getChildNodes();
197: for (int i = 0; i < childs.getLength(); i++) {
198: Node child = childs.item(i);
199: if (child instanceof Element) {
200: return (Element) child;
201: }
202: }
203: return null;
204: }
205:
206: /**
207: * Get the next sibling element
208: * @param el
209: * @return
210: */
211: public static Element getNextSiblingElement(Element el) {
212: for (Node n = el.getNextSibling(); n != null; n = n
213: .getNextSibling()) {
214: if (n instanceof Element) {
215: return (Element) n;
216: }
217: }
218: return null;
219: }
220:
221: /**
222: * Build a QName from the element name
223: * @param el
224: * @return
225: */
226: public static QName getQName(Element el) {
227: if (el == null) {
228: return null;
229: } else if (el.getPrefix() != null) {
230: return new QName(el.getNamespaceURI(), el.getLocalName(),
231: el.getPrefix());
232: } else {
233: return new QName(el.getNamespaceURI(), el.getLocalName());
234: }
235: }
236:
237: public static DocumentBuilder getBuilder()
238: throws ParserConfigurationException {
239: DocumentBuilder builder = (DocumentBuilder) builders.poll();
240: if (builder == null) {
241: if (dbf == null) {
242: dbf = DocumentBuilderFactory.newInstance();
243: dbf.setNamespaceAware(true);
244: }
245: builder = dbf.newDocumentBuilder();
246: }
247: return builder;
248: }
249:
250: public static void releaseBuilder(DocumentBuilder builder) {
251: builders.add(builder);
252: }
253:
254: /**
255: * Return a new document, ready to populate.
256: * @return
257: * @throws ParserConfigurationException
258: */
259: public static Document newDocument()
260: throws ParserConfigurationException {
261: DocumentBuilder builder = getBuilder();
262: Document doc = builder.newDocument();
263: releaseBuilder(builder);
264: return doc;
265: }
266:
267: }
|