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 */
017package org.apache.camel.converter.jaxp;
018
019import javax.xml.stream.XMLStreamConstants;
020import javax.xml.stream.XMLStreamException;
021import javax.xml.stream.XMLStreamReader;
022import javax.xml.transform.sax.SAXSource;
023
024import org.xml.sax.Attributes;
025import org.xml.sax.ContentHandler;
026import org.xml.sax.DTDHandler;
027import org.xml.sax.EntityResolver;
028import org.xml.sax.ErrorHandler;
029import org.xml.sax.InputSource;
030import org.xml.sax.SAXException;
031import org.xml.sax.SAXNotRecognizedException;
032import org.xml.sax.SAXNotSupportedException;
033import org.xml.sax.SAXParseException;
034import org.xml.sax.XMLReader;
035import org.xml.sax.ext.LexicalHandler;
036import org.xml.sax.helpers.AttributesImpl;
037
038/**
039 * A streaming {@link javax.xml.transform.sax.SAXSource}
040 */
041public class StaxSource extends SAXSource implements XMLReader {
042
043    private XMLStreamReader streamReader;
044
045    private ContentHandler contentHandler;
046
047    private LexicalHandler lexicalHandler;
048
049    public StaxSource(XMLStreamReader streamReader) {
050        this.streamReader = streamReader;
051        setInputSource(new InputSource());
052    }
053
054    public XMLReader getXMLReader() {
055        return this;
056    }
057
058    public XMLStreamReader getXMLStreamReader() {
059        return streamReader;
060    }
061
062    protected void parse() throws SAXException {
063        try {
064            while (true) {
065                switch (streamReader.getEventType()) {
066                // Attributes are handled in START_ELEMENT
067                case XMLStreamConstants.ATTRIBUTE:
068                    break;
069                case XMLStreamConstants.CDATA:
070                {
071                    if (lexicalHandler != null) {
072                        lexicalHandler.startCDATA();
073                    }
074                    int length = streamReader.getTextLength();
075                    int start = streamReader.getTextStart();
076                    char[] chars = streamReader.getTextCharacters();
077                    contentHandler.characters(chars, start, length);
078                    if (lexicalHandler != null) {
079                        lexicalHandler.endCDATA();
080                    }
081                    break;
082                }
083                case XMLStreamConstants.CHARACTERS:
084                {
085                    int length = streamReader.getTextLength();
086                    int start = streamReader.getTextStart();
087                    char[] chars = streamReader.getTextCharacters();
088                    contentHandler.characters(chars, start, length);
089                    break;
090                }
091                case XMLStreamConstants.SPACE:
092                {
093                    int length = streamReader.getTextLength();
094                    int start = streamReader.getTextStart();
095                    char[] chars = streamReader.getTextCharacters();
096                    contentHandler.ignorableWhitespace(chars, start, length);
097                    break;
098                }
099                case XMLStreamConstants.COMMENT:
100                    if (lexicalHandler != null) {
101                        int length = streamReader.getTextLength();
102                        int start = streamReader.getTextStart();
103                        char[] chars = streamReader.getTextCharacters();
104                        lexicalHandler.comment(chars, start, length);
105                    }
106                    break;
107                case XMLStreamConstants.DTD:
108                    break;
109                case XMLStreamConstants.END_DOCUMENT:
110                    contentHandler.endDocument();
111                    return;
112                case XMLStreamConstants.END_ELEMENT: {
113                    String uri = streamReader.getNamespaceURI();
114                    String localName = streamReader.getLocalName();
115                    String prefix = streamReader.getPrefix();
116                    String qname = prefix != null && prefix.length() > 0
117                        ? prefix + ":" + localName : localName;
118                    contentHandler.endElement(uri, localName, qname);
119                    // namespaces
120                    for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
121                        String nsPrefix = streamReader.getNamespacePrefix(i);
122                        String nsUri = streamReader.getNamespaceURI(i);
123                        if (nsUri == null) {
124                            nsUri = "";
125                        }
126                        contentHandler.endPrefixMapping(nsPrefix);
127                    }
128                    break;
129                }
130                case XMLStreamConstants.ENTITY_DECLARATION:
131                case XMLStreamConstants.ENTITY_REFERENCE:
132                case XMLStreamConstants.NAMESPACE:
133                case XMLStreamConstants.NOTATION_DECLARATION:
134                    break;
135                case XMLStreamConstants.PROCESSING_INSTRUCTION:
136                    break;
137                case XMLStreamConstants.START_DOCUMENT:
138                    contentHandler.startDocument();
139                    break;
140                case XMLStreamConstants.START_ELEMENT: {
141                    String uri = streamReader.getNamespaceURI();
142                    String localName = streamReader.getLocalName();
143                    String prefix = streamReader.getPrefix();
144                    String qname = prefix != null && prefix.length() > 0
145                        ? prefix + ":" + localName : localName;
146                    // namespaces
147                    for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
148                        String nsPrefix = streamReader.getNamespacePrefix(i);
149                        String nsUri = streamReader.getNamespaceURI(i);
150                        if (nsUri == null) {
151                            nsUri = "";
152                        }
153                        contentHandler.startPrefixMapping(nsPrefix, nsUri);
154                    }
155                    contentHandler.startElement(uri == null ? "" : uri, localName, qname, getAttributes());
156                    break;
157                }
158                default:
159                    break;
160                }
161                if (!streamReader.hasNext()) {
162                    return;
163                }
164                streamReader.next();
165            }
166        } catch (XMLStreamException e) {
167            SAXParseException spe;
168            if (e.getLocation() != null) {
169                spe = new SAXParseException(e.getMessage(), null, null,
170                                            e.getLocation().getLineNumber(),
171                                            e.getLocation().getColumnNumber(), e);
172            } else {
173                spe = new SAXParseException(e.getMessage(), null, null, -1, -1, e);
174            }
175            spe.initCause(e);
176            throw spe;
177        }
178    }
179
180    protected String getQualifiedName() {
181        String prefix = streamReader.getPrefix();
182        if (prefix != null && prefix.length() > 0) {
183            return prefix + ":" + streamReader.getLocalName();
184        } else {
185            return streamReader.getLocalName();
186        }
187    }
188
189    protected Attributes getAttributes() {
190        AttributesImpl attrs = new AttributesImpl();
191
192        for (int i = 0; i < streamReader.getAttributeCount(); i++) {
193            String uri = streamReader.getAttributeNamespace(i);
194            String localName = streamReader.getAttributeLocalName(i);
195            String prefix = streamReader.getAttributePrefix(i);
196            String qName;
197            if (prefix != null && prefix.length() > 0) {
198                qName = prefix + ':' + localName;
199            } else {
200                qName = localName;
201            }
202            String type = streamReader.getAttributeType(i);
203            String value = streamReader.getAttributeValue(i);
204            if (value == null) {
205                value = "";
206            }
207
208            attrs.addAttribute(uri == null ? "" : uri, localName, qName, type, value);
209        }
210        return attrs;
211    }
212
213    public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
214        return false;
215    }
216
217    public void setFeature(String name, boolean value)
218        throws SAXNotRecognizedException, SAXNotSupportedException {
219    }
220
221    public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
222        return null;
223    }
224
225    public void setProperty(String name, Object value)
226        throws SAXNotRecognizedException, SAXNotSupportedException {
227        if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
228            lexicalHandler = (LexicalHandler) value;
229        } else {
230            throw new SAXNotRecognizedException(name);
231        }
232    }
233
234    public void setEntityResolver(EntityResolver resolver) {
235    }
236
237    public EntityResolver getEntityResolver() {
238        return null;
239    }
240
241    public void setDTDHandler(DTDHandler handler) {
242    }
243
244    public DTDHandler getDTDHandler() {
245        return null;
246    }
247
248    public void setContentHandler(ContentHandler handler) {
249        this.contentHandler = handler;
250        if (handler instanceof LexicalHandler
251            && lexicalHandler == null) {
252            lexicalHandler = (LexicalHandler)handler;
253        }
254    }
255
256    public ContentHandler getContentHandler() {
257        return this.contentHandler;
258    }
259
260    public void setErrorHandler(ErrorHandler handler) {
261    }
262
263    public ErrorHandler getErrorHandler() {
264        return null;
265    }
266
267    public void parse(InputSource input) throws SAXException {
268        StaxSource.this.parse();
269    }
270
271    public void parse(String systemId) throws SAXException {
272        StaxSource.this.parse();
273    }
274
275}