FileDocCategorySizeDatePackage
XMLStreamReaderToContentHandler.javaAPI DocGlassfish v2 API12864Fri May 04 22:30:28 BST 2007com.sun.enterprise.jbi.serviceengine.util

XMLStreamReaderToContentHandler

public class XMLStreamReaderToContentHandler extends Object
This is a simple utility class that adapts StAX events from an {@link XMLStreamReader} to SAX events on a {@link ContentHandler}, bridging between the two parser technologies.
author
Ryan.Shoemaker@Sun.COM
version
1.0

Fields Summary
private final XMLStreamReader
staxStreamReader
private final ContentHandler
saxHandler
private boolean
eagerQuit
Constructors Summary
public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, boolean eagerQuit)
Construct a new StAX to SAX adapter that will convert a StAX event stream into a SAX event stream.

param
staxCore StAX event source
param
saxCore SAXevent sink

        this.staxStreamReader = staxCore;
        this.saxHandler = saxCore;
        this.eagerQuit = eagerQuit;
    
Methods Summary
public voidbridge()


        try {
            // remembers the nest level of elements to know when we are done.
            int depth=0;

            // if the parser is at the start tag, proceed to the first element
            int event = staxStreamReader.getEventType();
            if(event == XMLStreamConstants.START_DOCUMENT) {
                // nextTag doesn't correctly handle DTDs
                while( !staxStreamReader.isStartElement() )
                    event = staxStreamReader.next();
            }


            if( event!=XMLStreamConstants.START_ELEMENT)
                throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);

            handleStartDocument();

            OUTER:
            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--;
                        if(depth==0 && eagerQuit)
                            break OUTER;
                        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 static java.lang.StringfixNull(java.lang.String s)

        if(s==null)     return "";
        else            return s;
    
private org.xml.sax.AttributesgetAttributes()
Get the attributes associated with the given START_ELEMENT or ATTRIBUTE StAXevent.

return
the StAX attributes converted to an org.xml.sax.Attributes

        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 voidhandleAttribute()

        // no-op ???
        // attribute events don't normally occur outside of a startElement
        // or endElement
    
private voidhandleCDATA()

        // no-op ???
        // this event is listed in the javadoc, but not in the spec.
    
private voidhandleCharacters()

        try {
            saxHandler.characters(
                staxStreamReader.getTextCharacters(),
                staxStreamReader.getTextStart(),
                staxStreamReader.getTextLength() );
        } catch (SAXException e) {
            throw new XMLStreamException(e);
        }
    
private voidhandleComment()

        // no-op ???
    
private voidhandleDTD()

        // no-op ???
        // it seems like we need to pass this info along, but how?
    
private voidhandleEndDocument()

        saxHandler.endDocument();
    
private voidhandleEndElement()

        QName qName = staxStreamReader.getName();

        try {
            // fire endElement
            saxHandler.endElement(
                qName.getNamespaceURI(),
                qName.getLocalPart(),
                qName.toString());

            // 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 = "";
                }
                saxHandler.endPrefixMapping(prefix);
            }
        } catch (SAXException e) {
            throw new XMLStreamException(e);
        }
    
private voidhandleEntityDecl()

        // no-op ???
        // this event is listed in the javadoc, but not in the spec.
    
private voidhandleEntityReference()

        // no-op ???
    
private voidhandleNamespace()

        // no-op ???
        // namespace events don't normally occur outside of a startElement
        // or endElement
    
private voidhandleNotationDecl()

        // no-op ???
        // this event is listed in the javadoc, but not in the spec.
    
private voidhandlePI()

        try {
            saxHandler.processingInstruction(
                staxStreamReader.getPITarget(),
                staxStreamReader.getPIData());
        } catch (SAXException e) {
            throw new XMLStreamException(e);
        }
    
private voidhandleSpace()

        // no-op ???
        // this event is listed in the javadoc, but not in the spec.
    
private voidhandleStartDocument()

        saxHandler.setDocumentLocator(new Locator() {
            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();
            }
        });
        saxHandler.startDocument();
    
private voidhandleStartElement()


        try {
            // start namespace bindings
            int nsCount = staxStreamReader.getNamespaceCount();
            for (int i = 0; i < nsCount; i++) {
                saxHandler.startPrefixMapping(
                    fixNull(staxStreamReader.getNamespacePrefix(i)),
                    fixNull(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();
            saxHandler.startElement(
                qName.getNamespaceURI(),
                qName.getLocalPart(),
                rawname,
                attrs);
        } catch (SAXException e) {
            throw new XMLStreamException(e);
        }