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.camel.converter.jaxp;
018    
019    import java.io.ByteArrayInputStream;
020    import java.io.InputStream;
021    import java.io.UnsupportedEncodingException;
022    import java.util.ArrayList;
023    import java.util.Iterator;
024    import java.util.List;
025    
026    import javax.xml.transform.TransformerException;
027    
028    import org.w3c.dom.Attr;
029    import org.w3c.dom.Element;
030    import org.w3c.dom.Node;
031    import org.w3c.dom.NodeList;
032    import org.w3c.dom.Text;
033    
034    import org.apache.camel.Converter;
035    import org.apache.camel.Exchange;
036    import org.apache.camel.util.IOHelper;
037    import org.apache.camel.util.ObjectHelper;
038    
039    /**
040     * Converts from some DOM types to Java types
041     *
042     * @version 
043     */
044    @Converter
045    public final class DomConverter {
046        private final XmlConverter xml;
047    
048        public DomConverter() {
049            xml = new XmlConverter();
050        }
051    
052        @Converter
053        public String toString(NodeList nodeList, Exchange exchange) throws TransformerException {
054            // converting NodeList to String is more tricky
055            // sometimes the NodeList is a Node which we can then leverage
056            // the XML converter to turn into XML incl. tags
057    
058            StringBuilder buffer = new StringBuilder();
059    
060            // use XML converter at first since it preserves tag names
061            boolean found = false;
062            if (nodeList instanceof Node) {
063                Node node = (Node) nodeList;
064                String s = toString(node, exchange);
065                if (ObjectHelper.isNotEmpty(s)) {
066                    found = true;
067                    buffer.append(s);
068                }
069            } else {
070                // use XML converter at first since it preserves tag names
071                int size = nodeList.getLength();
072                for (int i = 0; i < size; i++) {
073                    Node node = nodeList.item(i);
074                    String s = toString(node, exchange);
075                    if (ObjectHelper.isNotEmpty(s)) {
076                        found = true;
077                        buffer.append(s);
078                    }
079                }
080            }
081    
082            // and eventually we must fallback to append without tags, such as when you have
083            // used an xpath to select an attribute or text() or something
084            if (!found) {
085                append(buffer, nodeList);
086            }
087    
088            return buffer.toString();
089        }
090        
091        private String toString(Node node, Exchange exchange) throws TransformerException {
092            String s;
093            if (node instanceof Text) {
094                Text textnode = (Text) node;
095                
096                StringBuilder b = new StringBuilder();
097                b.append(textnode.getNodeValue());
098                textnode = (Text) textnode.getNextSibling();
099                while (textnode != null) {
100                    b.append(textnode.getNodeValue());
101                    textnode = (Text) textnode.getNextSibling();
102                }
103                s = b.toString();
104            } else {
105                s = xml.toString(node, exchange);
106                
107            }
108            return s;
109        }
110    
111        @Converter
112        public static Integer toInteger(NodeList nodeList) {
113            StringBuilder buffer = new StringBuilder();
114            append(buffer, nodeList);
115            String s = buffer.toString();
116            return Integer.valueOf(s);
117        }
118    
119        @Converter
120        public static Long toLong(NodeList nodeList) {
121            StringBuilder buffer = new StringBuilder();
122            append(buffer, nodeList);
123            String s = buffer.toString();
124            return Long.valueOf(s);
125        }
126    
127        @Converter
128        public static List<?> toList(NodeList nodeList) {
129            List<Object> answer = new ArrayList<Object>();
130            Iterator<Object> it = ObjectHelper.createIterator(nodeList);
131            while (it.hasNext()) {
132                answer.add(it.next());
133            }
134            return answer;
135        }
136    
137        @Converter
138        public InputStream toInputStream(NodeList nodeList, Exchange exchange) throws TransformerException, UnsupportedEncodingException {
139            return new ByteArrayInputStream(toByteArray(nodeList, exchange));
140        }
141    
142        @Converter
143        public byte[] toByteArray(NodeList nodeList, Exchange exchange) throws TransformerException, UnsupportedEncodingException {
144            String data = toString(nodeList, exchange);
145            return data.getBytes(IOHelper.getCharsetName(exchange));
146        }
147    
148        private static void append(StringBuilder buffer, NodeList nodeList) {
149            int size = nodeList.getLength();
150            for (int i = 0; i < size; i++) {
151                append(buffer, nodeList.item(i));
152            }
153        }
154    
155        private static void append(StringBuilder buffer, Node node) {
156            if (node instanceof Text) {
157                Text text = (Text) node;
158                buffer.append(text.getTextContent());
159            } else if (node instanceof Attr) {
160                Attr attribute = (Attr) node;
161                buffer.append(attribute.getTextContent());
162            } else if (node instanceof Element) {
163                Element element = (Element) node;
164                append(buffer, element.getChildNodes());
165            }
166        }
167    }