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}