| /* |
| * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.org.apache.xalan.internal.xsltc.trax; |
| |
| import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl; |
| import java.io.IOException; |
| import javax.xml.namespace.QName; |
| import javax.xml.stream.XMLStreamConstants; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamReader; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.DTDHandler; |
| import org.xml.sax.EntityResolver; |
| import org.xml.sax.ErrorHandler; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| import org.xml.sax.XMLReader; |
| import org.xml.sax.ext.LexicalHandler; |
| import org.xml.sax.ext.Locator2; |
| import org.xml.sax.helpers.AttributesImpl; |
| |
| |
| |
| /** |
| * @author Padmaja Vedula |
| * @author Sunitha Reddy |
| */ |
| public class StAXStream2SAX implements XMLReader, Locator { |
| |
| //private final static String EMPTYSTRING = ""; |
| //private static final String XMLNS_PREFIX = "xmlns"; |
| |
| // StAX Stream source |
| private final XMLStreamReader staxStreamReader; |
| |
| //private Node _dom = null; |
| private ContentHandler _sax = null; |
| private LexicalHandler _lex = null; |
| private SAXImpl _saxImpl = null; |
| |
| public StAXStream2SAX(XMLStreamReader staxSrc) { |
| staxStreamReader = staxSrc; |
| } |
| |
| public ContentHandler getContentHandler() { |
| return _sax; |
| } |
| |
| public void setContentHandler(ContentHandler handler) throws |
| NullPointerException |
| { |
| _sax = handler; |
| if (handler instanceof LexicalHandler) { |
| _lex = (LexicalHandler) handler; |
| } |
| |
| if (handler instanceof SAXImpl) { |
| _saxImpl = (SAXImpl)handler; |
| } |
| } |
| |
| |
| public void parse(InputSource unused) throws IOException, SAXException { |
| try { |
| bridge(); |
| } catch (XMLStreamException e) { |
| throw new SAXException(e); |
| } |
| } |
| |
| |
| //Main Work Starts Here. |
| public void parse() throws IOException, SAXException, XMLStreamException { |
| bridge(); |
| } |
| |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void parse(String sysId) throws IOException, SAXException { |
| throw new IOException("This method is not yet implemented."); |
| } |
| |
| |
| public void bridge() throws XMLStreamException { |
| |
| try { |
| // remembers the nest level of elements to know when we are done. |
| int depth=0; |
| |
| // skip over START_DOCUMENT |
| int event = staxStreamReader.getEventType(); |
| if (event == XMLStreamConstants.START_DOCUMENT) { |
| event = staxStreamReader.next(); |
| } |
| |
| // If not a START_ELEMENT (e.g., a DTD), skip to next tag |
| if (event != XMLStreamConstants.START_ELEMENT) { |
| event = staxStreamReader.nextTag(); |
| // An error if a START_ELEMENT isn't found now |
| if (event != XMLStreamConstants.START_ELEMENT) { |
| throw new IllegalStateException("The current event is " + |
| "not START_ELEMENT\n but" + event); |
| } |
| } |
| |
| handleStartDocument(); |
| |
| do { |
| // These are all of the events listed in the javadoc for |
| // XMLEvent. |
| // The spec only really describes 11 of them. |
| switch (event) { |
| case XMLStreamConstants.START_ELEMENT : |
| depth++; |
| handleStartElement(); |
| break; |
| case XMLStreamConstants.END_ELEMENT : |
| handleEndElement(); |
| depth--; |
| break; |
| case XMLStreamConstants.CHARACTERS : |
| handleCharacters(); |
| break; |
| case XMLStreamConstants.ENTITY_REFERENCE : |
| handleEntityReference(); |
| break; |
| case XMLStreamConstants.PROCESSING_INSTRUCTION : |
| handlePI(); |
| break; |
| case XMLStreamConstants.COMMENT : |
| handleComment(); |
| break; |
| case XMLStreamConstants.DTD : |
| handleDTD(); |
| break; |
| case XMLStreamConstants.ATTRIBUTE : |
| handleAttribute(); |
| break; |
| case XMLStreamConstants.NAMESPACE : |
| handleNamespace(); |
| break; |
| case XMLStreamConstants.CDATA : |
| handleCDATA(); |
| break; |
| case XMLStreamConstants.ENTITY_DECLARATION : |
| handleEntityDecl(); |
| break; |
| case XMLStreamConstants.NOTATION_DECLARATION : |
| handleNotationDecl(); |
| break; |
| case XMLStreamConstants.SPACE : |
| handleSpace(); |
| break; |
| default : |
| throw new InternalError("processing event: " + event); |
| } |
| |
| event=staxStreamReader.next(); |
| } while (depth!=0); |
| |
| handleEndDocument(); |
| } catch (SAXException e) { |
| throw new XMLStreamException(e); |
| } |
| } |
| |
| private void handleEndDocument() throws SAXException { |
| _sax.endDocument(); |
| } |
| |
| private void handleStartDocument() throws SAXException { |
| _sax.setDocumentLocator(new Locator2() { |
| public int getColumnNumber() { |
| return staxStreamReader.getLocation().getColumnNumber(); |
| } |
| public int getLineNumber() { |
| return staxStreamReader.getLocation().getLineNumber(); |
| } |
| public String getPublicId() { |
| return staxStreamReader.getLocation().getPublicId(); |
| } |
| public String getSystemId() { |
| return staxStreamReader.getLocation().getSystemId(); |
| } |
| public String getXMLVersion() { |
| return staxStreamReader.getVersion(); |
| } |
| public String getEncoding() { |
| return staxStreamReader.getEncoding(); |
| } |
| }); |
| _sax.startDocument(); |
| } |
| |
| private void handlePI() throws XMLStreamException { |
| try { |
| _sax.processingInstruction( |
| staxStreamReader.getPITarget(), |
| staxStreamReader.getPIData()); |
| } catch (SAXException e) { |
| throw new XMLStreamException(e); |
| } |
| } |
| |
| private void handleCharacters() throws XMLStreamException { |
| |
| // workaround for bugid 5046319 - switch over to commented section |
| // below when it is fixed. |
| int textLength = staxStreamReader.getTextLength(); |
| char[] chars = new char[textLength]; |
| |
| staxStreamReader.getTextCharacters(0, chars, 0, textLength); |
| |
| try { |
| _sax.characters(chars, 0, chars.length); |
| } catch (SAXException e) { |
| throw new XMLStreamException(e); |
| } |
| |
| |
| // int start = 0; |
| // int len; |
| // do { |
| // len = staxStreamReader.getTextCharacters(start, buf, 0, buf.length); |
| // start += len; |
| // try { |
| // _sax.characters(buf, 0, len); |
| // } catch (SAXException e) { |
| // throw new XMLStreamException(e); |
| // } |
| // } while (len == buf.length); |
| } |
| |
| private void handleEndElement() throws XMLStreamException { |
| QName qName = staxStreamReader.getName(); |
| |
| try { |
| //construct prefix:localName from qName |
| String qname = ""; |
| if (qName.getPrefix() != null && qName.getPrefix().trim().length() != 0){ |
| qname = qName.getPrefix() + ":"; |
| } |
| qname += qName.getLocalPart(); |
| |
| // fire endElement |
| _sax.endElement( |
| qName.getNamespaceURI(), |
| qName.getLocalPart(), |
| qname); |
| |
| // end namespace bindings |
| int nsCount = staxStreamReader.getNamespaceCount(); |
| for (int i = nsCount - 1; i >= 0; i--) { |
| String prefix = staxStreamReader.getNamespacePrefix(i); |
| if (prefix == null) { // true for default namespace |
| prefix = ""; |
| } |
| _sax.endPrefixMapping(prefix); |
| } |
| } catch (SAXException e) { |
| throw new XMLStreamException(e); |
| } |
| } |
| |
| private void handleStartElement() throws XMLStreamException { |
| |
| try { |
| // start namespace bindings |
| int nsCount = staxStreamReader.getNamespaceCount(); |
| for (int i = 0; i < nsCount; i++) { |
| String prefix = staxStreamReader.getNamespacePrefix(i); |
| if (prefix == null) { // true for default namespace |
| prefix = ""; |
| } |
| _sax.startPrefixMapping( |
| prefix, |
| staxStreamReader.getNamespaceURI(i)); |
| } |
| |
| // fire startElement |
| QName qName = staxStreamReader.getName(); |
| String prefix = qName.getPrefix(); |
| String rawname; |
| if(prefix==null || prefix.length()==0) |
| rawname = qName.getLocalPart(); |
| else |
| rawname = prefix + ':' + qName.getLocalPart(); |
| Attributes attrs = getAttributes(); |
| _sax.startElement( |
| qName.getNamespaceURI(), |
| qName.getLocalPart(), |
| rawname, |
| attrs); |
| } catch (SAXException e) { |
| throw new XMLStreamException(e); |
| } |
| } |
| |
| /** |
| * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE |
| * StAXevent. |
| * |
| * @return the StAX attributes converted to an org.xml.sax.Attributes |
| */ |
| private Attributes getAttributes() { |
| AttributesImpl attrs = new AttributesImpl(); |
| |
| int eventType = staxStreamReader.getEventType(); |
| if (eventType != XMLStreamConstants.ATTRIBUTE |
| && eventType != XMLStreamConstants.START_ELEMENT) { |
| throw new InternalError( |
| "getAttributes() attempting to process: " + eventType); |
| } |
| |
| // in SAX, namespace declarations are not part of attributes by default. |
| // (there's a property to control that, but as far as we are concerned |
| // we don't use it.) So don't add xmlns:* to attributes. |
| |
| // gather non-namespace attrs |
| for (int i = 0; i < staxStreamReader.getAttributeCount(); i++) { |
| String uri = staxStreamReader.getAttributeNamespace(i); |
| if(uri==null) uri=""; |
| String localName = staxStreamReader.getAttributeLocalName(i); |
| String prefix = staxStreamReader.getAttributePrefix(i); |
| String qName; |
| if(prefix==null || prefix.length()==0) |
| qName = localName; |
| else |
| qName = prefix + ':' + localName; |
| String type = staxStreamReader.getAttributeType(i); |
| String value = staxStreamReader.getAttributeValue(i); |
| |
| attrs.addAttribute(uri, localName, qName, type, value); |
| } |
| |
| return attrs; |
| } |
| |
| private void handleNamespace() { |
| // no-op ??? |
| // namespace events don't normally occur outside of a startElement |
| // or endElement |
| } |
| |
| private void handleAttribute() { |
| // no-op ??? |
| // attribute events don't normally occur outside of a startElement |
| // or endElement |
| } |
| |
| private void handleDTD() { |
| // no-op ??? |
| // it seems like we need to pass this info along, but how? |
| } |
| |
| private void handleComment() { |
| // no-op ??? |
| } |
| |
| private void handleEntityReference() { |
| // no-op ??? |
| } |
| |
| private void handleSpace() { |
| // no-op ??? |
| // this event is listed in the javadoc, but not in the spec. |
| } |
| |
| private void handleNotationDecl() { |
| // no-op ??? |
| // this event is listed in the javadoc, but not in the spec. |
| } |
| |
| private void handleEntityDecl() { |
| // no-op ??? |
| // this event is listed in the javadoc, but not in the spec. |
| } |
| |
| private void handleCDATA() { |
| // no-op ??? |
| // this event is listed in the javadoc, but not in the spec. |
| } |
| |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public DTDHandler getDTDHandler() { |
| return null; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public ErrorHandler getErrorHandler() { |
| return null; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public boolean getFeature(String name) throws SAXNotRecognizedException, |
| SAXNotSupportedException |
| { |
| return false; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void setFeature(String name, boolean value) throws |
| SAXNotRecognizedException, SAXNotSupportedException |
| { |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void setDTDHandler(DTDHandler handler) throws NullPointerException { |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void setEntityResolver(EntityResolver resolver) throws |
| NullPointerException |
| { |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public EntityResolver getEntityResolver() { |
| return null; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void setErrorHandler(ErrorHandler handler) throws |
| NullPointerException |
| { |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public void setProperty(String name, Object value) throws |
| SAXNotRecognizedException, SAXNotSupportedException { |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public Object getProperty(String name) throws SAXNotRecognizedException, |
| SAXNotSupportedException |
| { |
| return null; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public int getColumnNumber() { |
| return 0; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public int getLineNumber() { |
| return 0; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public String getPublicId() { |
| return null; |
| } |
| |
| /** |
| * This class is only used internally so this method should never |
| * be called. |
| */ |
| public String getSystemId() { |
| return null; |
| } |
| |
| } |