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.soap.util;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021:
022: import javax.xml.XMLConstants;
023: import javax.xml.namespace.QName;
024: import javax.xml.parsers.DocumentBuilderFactory;
025: import javax.xml.parsers.ParserConfigurationException;
026: import javax.xml.transform.Source;
027: import javax.xml.transform.Transformer;
028: import javax.xml.transform.TransformerConfigurationException;
029: import javax.xml.transform.TransformerException;
030: import javax.xml.transform.TransformerFactory;
031: import javax.xml.transform.dom.DOMResult;
032:
033: import org.apache.servicemix.soap.api.Fault;
034: import org.w3c.dom.Document;
035: import org.w3c.dom.Element;
036: import org.w3c.dom.Node;
037: import org.w3c.dom.NodeList;
038: import org.xml.sax.SAXException;
039:
040: /**
041: * DOM related utilities.
042: *
043: * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
044: */
045: public class DomUtil {
046:
047: private static DocumentBuilderFactory documentBuilderFactory;
048: private static TransformerFactory transformerFactory;
049:
050: public static Document createDocument() {
051: try {
052: return getDocumentBuilderFactory().newDocumentBuilder()
053: .newDocument();
054: } catch (ParserConfigurationException e) {
055: throw new Fault(e);
056: }
057: }
058:
059: public static Document parse(InputStream is) {
060: try {
061: return getDocumentBuilderFactory().newDocumentBuilder()
062: .parse(is);
063: } catch (SAXException e) {
064: throw new Fault(e);
065: } catch (IOException e) {
066: throw new Fault(e);
067: } catch (ParserConfigurationException e) {
068: throw new Fault(e);
069: }
070: }
071:
072: public static Document parse(Source source) {
073: try {
074: Document doc = createDocument();
075: DOMResult result = new DOMResult(doc);
076: Transformer transformer = getTransformerFactory()
077: .newTransformer();
078: transformer.transform(source, result);
079: return doc;
080: } catch (TransformerConfigurationException e) {
081: throw new Fault(e);
082: } catch (TransformerException e) {
083: throw new Fault(e);
084: }
085: }
086:
087: public static DocumentBuilderFactory getDocumentBuilderFactory() {
088: if (documentBuilderFactory == null) {
089: DocumentBuilderFactory f = DocumentBuilderFactory
090: .newInstance();
091: f.setNamespaceAware(true);
092: documentBuilderFactory = f;
093: }
094: return documentBuilderFactory;
095: }
096:
097: public static TransformerFactory getTransformerFactory() {
098: if (transformerFactory == null) {
099: transformerFactory = TransformerFactory.newInstance();
100: }
101: return transformerFactory;
102: }
103:
104: /**
105: * Get the first child element
106: * @param parent
107: * @return
108: */
109: public static Element getFirstChildElement(Node parent) {
110: NodeList childs = parent.getChildNodes();
111: for (int i = 0; i < childs.getLength(); i++) {
112: Node child = childs.item(i);
113: if (child instanceof Element) {
114: return (Element) child;
115: }
116: }
117: return null;
118: }
119:
120: /**
121: * Returns the text of the element
122: */
123: public static String getElementText(Element element) {
124: StringBuffer buffer = new StringBuffer();
125: NodeList nodeList = element.getChildNodes();
126: for (int i = 0, size = nodeList.getLength(); i < size; i++) {
127: Node node = nodeList.item(i);
128: if (node.getNodeType() == Node.TEXT_NODE
129: || node.getNodeType() == Node.CDATA_SECTION_NODE) {
130: buffer.append(node.getNodeValue());
131: }
132: }
133: return buffer.toString();
134: }
135:
136: /**
137: * Get the next sibling element
138: * @param el
139: * @return
140: */
141: public static Element getNextSiblingElement(Element el) {
142: for (Node n = el.getNextSibling(); n != null; n = n
143: .getNextSibling()) {
144: if (n instanceof Element) {
145: return (Element) n;
146: }
147: }
148: return null;
149: }
150:
151: public static Element createElement(Node parent, QName name) {
152: Document doc = parent instanceof Document ? (Document) parent
153: : parent.getOwnerDocument();
154: Element element;
155: if (name.getPrefix() != null && name.getPrefix().length() > 0) {
156: element = doc.createElementNS(name.getNamespaceURI(), name
157: .getPrefix()
158: + ":" + name.getLocalPart());
159: String attr = recursiveGetAttributeValue(parent,
160: XMLConstants.XMLNS_ATTRIBUTE + ":"
161: + name.getPrefix());
162: if (attr == null || !attr.equals(name.getNamespaceURI())) {
163: element.setAttribute(XMLConstants.XMLNS_ATTRIBUTE + ":"
164: + name.getPrefix(), name.getNamespaceURI());
165: }
166: } else if (name.getNamespaceURI() != null
167: && name.getNamespaceURI().length() > 0) {
168: element = doc.createElementNS(name.getNamespaceURI(), name
169: .getLocalPart());
170: String attr = recursiveGetAttributeValue(parent,
171: XMLConstants.XMLNS_ATTRIBUTE);
172: if (attr == null || !attr.equals(name.getNamespaceURI())) {
173: element.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, name
174: .getNamespaceURI());
175: }
176: } else {
177: element = doc.createElementNS(null, name.getLocalPart());
178: String attr = recursiveGetAttributeValue(parent,
179: XMLConstants.XMLNS_ATTRIBUTE);
180: if (attr == null || attr.length() > 0) {
181: element.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, "");
182: }
183: }
184: parent.appendChild(element);
185: return element;
186: }
187:
188: /**
189: * Creates a QName instance from the given namespace context for the given qualifiedName
190: *
191: * @param element the element to use as the namespace context
192: * @param qualifiedName the fully qualified name
193: * @return the QName which matches the qualifiedName
194: */
195: public static QName createQName(Element element,
196: String qualifiedName) {
197: int index = qualifiedName.indexOf(':');
198: if (index >= 0) {
199: String prefix = qualifiedName.substring(0, index);
200: String localName = qualifiedName.substring(index + 1);
201: String uri = recursiveGetAttributeValue(element,
202: XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix);
203: return new QName(uri, localName, prefix);
204: } else {
205: String uri = recursiveGetAttributeValue(element,
206: XMLConstants.XMLNS_ATTRIBUTE);
207: if (uri != null) {
208: return new QName(uri, qualifiedName);
209: }
210: return new QName(qualifiedName);
211: }
212: }
213:
214: /**
215: * Recursive method to find a given attribute value
216: */
217: public static String recursiveGetAttributeValue(Node parent,
218: String attributeName) {
219: if (parent instanceof Element) {
220: Element element = (Element) parent;
221: String answer = element.getAttribute(attributeName);
222: if (answer == null || answer.length() == 0) {
223: Node parentNode = element.getParentNode();
224: if (parentNode instanceof Element) {
225: return recursiveGetAttributeValue(
226: (Element) parentNode, attributeName);
227: }
228: }
229: return answer;
230: } else {
231: return null;
232: }
233: }
234:
235: protected static String getUniquePrefix(Element element) {
236: int n = 1;
237: while (true) {
238: String nsPrefix = "ns" + n;
239: if (recursiveGetAttributeValue(element,
240: XMLConstants.XMLNS_ATTRIBUTE + ":" + nsPrefix) == null) {
241: return nsPrefix;
242: }
243: n++;
244: }
245: }
246:
247: public static QName getQName(Element el) {
248: if (el == null) {
249: return null;
250: } else if (el.getPrefix() != null) {
251: return new QName(el.getNamespaceURI(), el.getLocalName(),
252: el.getPrefix());
253: } else {
254: return new QName(el.getNamespaceURI(), el.getLocalName());
255: }
256: }
257:
258: }
|