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
018 package org.apache.camel.component.cxf.util;
019
020 import java.io.InputStream;
021 import java.util.HashMap;
022 import java.util.Map;
023
024 import javax.xml.stream.XMLStreamException;
025 import javax.xml.stream.XMLStreamWriter;
026
027 import org.w3c.dom.Element;
028 import org.w3c.dom.NamedNodeMap;
029 import org.w3c.dom.Node;
030 import org.w3c.dom.NodeList;
031
032 import org.apache.camel.converter.jaxp.XmlConverter;
033 import org.apache.cxf.common.util.StringUtils;
034 import org.apache.cxf.helpers.IOUtils;
035 import org.apache.cxf.io.CachedOutputStream;
036 import org.apache.cxf.staxutils.StaxUtils;
037 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
038
039 public final class CxfUtils {
040
041 private CxfUtils() {
042 // helper class
043 }
044
045 public static String getStringFromInputStream(InputStream in) throws Exception {
046 CachedOutputStream bos = new CachedOutputStream();
047 IOUtils.copy(in, bos);
048 in.close();
049 bos.close();
050 return bos.getOut().toString();
051 }
052
053 public static String elementToString(Element element) throws Exception {
054 Map<String, String> namespaces = new HashMap<String, String>();
055 visitNodesForNameSpace(element, namespaces);
056 W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
057 writeElement(element, writer, namespaces);
058 XmlConverter converter = new XmlConverter();
059 return converter.toString(converter.toDOMSource(writer.getDocument()), null);
060 }
061
062 private static void writeElement(Element e,
063 XMLStreamWriter writer,
064 Map<String, String> namespaces)
065 throws XMLStreamException {
066 String prefix = e.getPrefix();
067 String ns = e.getNamespaceURI();
068 String localName = e.getLocalName();
069
070 if (prefix == null) {
071 prefix = "";
072 }
073 if (localName == null) {
074 localName = e.getNodeName();
075
076 if (localName == null) {
077 throw new IllegalStateException("Element's local name cannot be null!");
078 }
079 }
080
081 String decUri = writer.getNamespaceContext().getNamespaceURI(prefix);
082 boolean declareNamespace = decUri == null || !decUri.equals(ns);
083
084 if (ns == null || ns.length() == 0) {
085 writer.writeStartElement(localName);
086 if (StringUtils.isEmpty(decUri)) {
087 declareNamespace = false;
088 }
089 } else {
090 writer.writeStartElement(prefix, localName, ns);
091 }
092
093 NamedNodeMap attrs = e.getAttributes();
094 for (int i = 0; i < attrs.getLength(); i++) {
095 Node attr = attrs.item(i);
096
097 String name = attr.getLocalName();
098 String attrPrefix = attr.getPrefix();
099 if (attrPrefix == null) {
100 attrPrefix = "";
101 }
102 if (name == null) {
103 name = attr.getNodeName();
104 }
105
106 if ("xmlns".equals(attrPrefix)) {
107 writer.writeNamespace(name, attr.getNodeValue());
108 if (name.equals(prefix) && attr.getNodeValue().equals(ns)) {
109 declareNamespace = false;
110 }
111 } else {
112 if ("xmlns".equals(name) && "".equals(attrPrefix)) {
113 writer.writeNamespace("", attr.getNodeValue());
114 if (attr.getNodeValue().equals(ns)) {
115 declareNamespace = false;
116 } else if (StringUtils.isEmpty(attr.getNodeValue())
117 && StringUtils.isEmpty(ns)) {
118 declareNamespace = false;
119 }
120 } else {
121 String attns = attr.getNamespaceURI();
122 String value = attr.getNodeValue();
123 if (attns == null || attns.length() == 0) {
124 writer.writeAttribute(name, value);
125 } else if (attrPrefix == null || attrPrefix.length() == 0) {
126 writer.writeAttribute(attns, name, value);
127 } else {
128 writer.writeAttribute(attrPrefix, attns, name, value);
129 }
130 }
131 }
132 }
133
134 if (declareNamespace) {
135 if (ns == null) {
136 writer.writeNamespace(prefix, "");
137 } else {
138 writer.writeNamespace(prefix, ns);
139 }
140 }
141
142 if (namespaces != null && namespaces.size() > 0) {
143 for (String key : namespaces.keySet()) {
144 String namespaceURI = namespaces.get(key);
145 writer.writeNamespace(key, namespaceURI);
146 }
147 }
148
149 Node nd = e.getFirstChild();
150 while (nd != null) {
151 StaxUtils.writeNode(nd, writer, false);
152 nd = nd.getNextSibling();
153 }
154
155 writer.writeEndElement();
156 }
157
158 private static void visitNodesForNameSpace(Node node, Map<String, String> namespaces) {
159 if (node instanceof Element) {
160 Element element = (Element)node;
161 if (element.getPrefix() != null && element.getNamespaceURI() != null) {
162 namespaces.put(element.getPrefix(), element.getNamespaceURI());
163 }
164 if (node.getChildNodes() != null) {
165 NodeList nodelist = node.getChildNodes();
166 for (int i = 0; i < nodelist.getLength(); i++) {
167 visitNodesForNameSpace(nodelist.item(i), namespaces);
168 }
169 }
170 }
171 }
172 }