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.stax;
018    
019    import javax.xml.XMLConstants;
020    import javax.xml.stream.XMLStreamConstants;
021    import javax.xml.stream.XMLStreamException;
022    import javax.xml.stream.XMLStreamReader;
023    import javax.xml.transform.sax.SAXSource;
024    
025    import org.xml.sax.Attributes;
026    import org.xml.sax.ContentHandler;
027    import org.xml.sax.DTDHandler;
028    import org.xml.sax.EntityResolver;
029    import org.xml.sax.ErrorHandler;
030    import org.xml.sax.InputSource;
031    import org.xml.sax.SAXException;
032    import org.xml.sax.SAXNotRecognizedException;
033    import org.xml.sax.SAXNotSupportedException;
034    import org.xml.sax.SAXParseException;
035    import org.xml.sax.XMLReader;
036    import org.xml.sax.helpers.AttributesImpl;
037    
038    public class StaxSource extends SAXSource implements XMLReader {
039    
040        private XMLStreamReader streamReader;
041    
042        private ContentHandler contentHandler;
043    
044        public StaxSource(XMLStreamReader streamReader) {
045            this.streamReader = streamReader;
046            setInputSource(new InputSource());
047        }
048    
049        public XMLReader getXMLReader() {
050            return this;
051        }
052    
053        public XMLStreamReader getStreamReader() {
054            return streamReader;
055        }
056    
057        protected void parse() throws SAXException {
058            try {
059                contentHandler.startDocument();
060                while (true) {
061                    switch (streamReader.getEventType()) {
062                    case XMLStreamConstants.ATTRIBUTE:
063                    case XMLStreamConstants.CDATA:
064                        break;
065                    case XMLStreamConstants.CHARACTERS:
066                        if (!streamReader.isWhiteSpace()) {
067                            
068                            int length = streamReader.getTextLength();
069                            int start = streamReader.getTextStart();
070                            char[] chars = streamReader.getTextCharacters();
071                            contentHandler.characters(chars, start, length);
072                            /*
073                            for (int textLength = streamReader.getTextLength(); textLength > 0; textLength -= chars.length) {
074                                int l = Math.min(textLength, chars.length);
075                                streamReader.getTextCharacters(0, chars, 0, l);
076                                contentHandler.characters(chars, 0, l);
077                            }
078                            */
079                        }
080                        break;
081                    case XMLStreamConstants.COMMENT:
082                    case XMLStreamConstants.DTD:
083                        break;
084                    case XMLStreamConstants.END_DOCUMENT:
085                        contentHandler.endDocument();
086                        return;
087                    case XMLStreamConstants.END_ELEMENT: {
088                        String uri = streamReader.getNamespaceURI();
089                        String localName = streamReader.getLocalName();
090                        String prefix = streamReader.getPrefix();
091                        String qname = prefix != null && prefix.length() > 0 ? prefix + ":" + localName : localName;
092                        contentHandler.endElement(uri, localName, qname);
093                        for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
094                            //contentHandler.endPrefixMapping(streamReader.getNamespaceURI(i));
095                        }
096                        break;
097                    }
098                    case XMLStreamConstants.ENTITY_DECLARATION:
099                    case XMLStreamConstants.ENTITY_REFERENCE:
100                    case XMLStreamConstants.NAMESPACE:
101                    case XMLStreamConstants.NOTATION_DECLARATION:
102                    case XMLStreamConstants.PROCESSING_INSTRUCTION:
103                    case XMLStreamConstants.SPACE:
104                    case XMLStreamConstants.START_DOCUMENT:
105                        break;
106                    case XMLStreamConstants.START_ELEMENT: {
107                        for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
108                            //contentHandler.startPrefixMapping(streamReader.getNamespacePrefix(i),
109                            //                                  streamReader.getNamespaceURI(i));
110                        }
111                        String uri = streamReader.getNamespaceURI();
112                        String localName = streamReader.getLocalName();
113                        String prefix = streamReader.getPrefix();
114                        String qname = prefix != null && prefix.length() > 0 ? prefix + ":" + localName : localName;
115                        contentHandler.startElement(uri != null ? uri : XMLConstants.NULL_NS_URI, localName, qname, getAttributes());
116                        break;
117                    }
118                    }
119                    streamReader.next();
120                }
121            } catch (XMLStreamException e) {
122                if (e.getLocation() != null) {
123                    throw new SAXParseException(e.getMessage(), null, null, e.getLocation().getLineNumber(), e.getLocation()
124                            .getColumnNumber(), e);
125                } else {
126                    throw new SAXParseException(e.getMessage(), null, null, -1, -1, e);
127                }
128            }
129        }
130    
131        protected String getQualifiedName() {
132            String prefix = streamReader.getPrefix();
133            if (prefix != null && prefix.length() > 0) {
134                return prefix + ":" + streamReader.getLocalName();
135            } else {
136                return streamReader.getLocalName();
137            }
138        }
139    
140        protected Attributes getAttributes() {
141            AttributesImpl attrs = new AttributesImpl();
142            // Adding namespace declaration as attributes is necessary because
143            // the xalan implementation that ships with SUN JDK 1.4 is bugged
144            // and does not handle the startPrefixMapping method
145            for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
146                String prefix = streamReader.getNamespacePrefix(i);
147                String uri = streamReader.getNamespaceURI(i);
148                if (uri == null) {
149                    uri = "";
150                }
151                // Default namespace
152                if (prefix == null || prefix.length() == 0) {
153                    attrs.addAttribute(XMLConstants.DEFAULT_NS_PREFIX, 
154                                       null, 
155                                       XMLConstants.XMLNS_ATTRIBUTE, 
156                                       "CDATA", 
157                                       uri);
158                } else {
159                    attrs.addAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, 
160                                       prefix, 
161                                       XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix, 
162                                       "CDATA", 
163                                       uri);
164                }
165            }
166            for (int i = 0; i < streamReader.getAttributeCount(); i++) {
167                String uri = streamReader.getAttributeNamespace(i);
168                String localName = streamReader.getAttributeLocalName(i);
169                String prefix = streamReader.getAttributePrefix(i);
170                String qName;
171                if (prefix != null && prefix.length() > 0) {
172                    qName = prefix + ':' + localName;
173                } else {
174                    qName = localName;
175                }
176                String type = streamReader.getAttributeType(i);
177                String value = streamReader.getAttributeValue(i);
178                if (value == null) {
179                    value = "";
180                }
181                attrs.addAttribute(uri, localName, qName, type, value);
182            }
183            return attrs;
184        }
185    
186        public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
187            return false;
188        }
189    
190        public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
191        }
192    
193        public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
194            return null;
195        }
196    
197        public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
198        }
199    
200        public void setEntityResolver(EntityResolver resolver) {
201        }
202    
203        public EntityResolver getEntityResolver() {
204            return null;
205        }
206    
207        public void setDTDHandler(DTDHandler handler) {
208        }
209    
210        public DTDHandler getDTDHandler() {
211            return null;
212        }
213    
214        public void setContentHandler(ContentHandler handler) {
215            this.contentHandler = handler;
216        }
217    
218        public ContentHandler getContentHandler() {
219            return this.contentHandler;
220        }
221    
222        public void setErrorHandler(ErrorHandler handler) {
223        }
224    
225        public ErrorHandler getErrorHandler() {
226            return null;
227        }
228    
229        public void parse(InputSource input) throws SAXException {
230            StaxSource.this.parse();
231        }
232    
233        public void parse(String systemId) throws SAXException {
234            StaxSource.this.parse();
235        }
236    
237    }