Package org.eclipse.persistence.internal.oxm.record

Source Code of org.eclipse.persistence.internal.oxm.record.XMLEventReaderReader$IndexedAttributeList

/*******************************************************************************
* Copyright (c) 1998, 2009 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     mmacivor - September 14/2009 - 2.0 - Initial implementation
******************************************************************************/
package org.eclipse.persistence.internal.oxm.record;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.Comment;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.ProcessingInstruction;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.eclipse.persistence.oxm.XMLConstants;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.LexicalHandler;

/**
* Convert and XMLEventReader into SAX events.
*/
public class XMLEventReaderReader extends XMLReader {

    private ContentHandler contentHandler;
    private LexicalHandler lexicalHandler;
    private ErrorHandler errorHandler;
    private int depth = 0;
    //Required because the EndElement fails to properly won't give the list of namespaces going out of
    //scope in some STAX implementations
    private HashMap<Integer, ArrayList<Namespace>> namespaces;

    public XMLEventReaderReader() {
        this.namespaces = new HashMap<Integer, ArrayList<Namespace>>();
    }

    @Override
    public ContentHandler getContentHandler() {
        return contentHandler;
    }

    @Override
    public void setContentHandler(ContentHandler aContentHandler) {
        this.contentHandler = aContentHandler;
    }

    @Override
    public ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    @Override
    public void setErrorHandler(ErrorHandler anErrorHandler) {
        this.errorHandler = anErrorHandler;
    }

    @Override
    public void setProperty (String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
        if(name.equals("http://xml.org/sax/properties/lexical-handler")) {
            lexicalHandler = (LexicalHandler)value;
        }
    }

    @Override
    public void parse(InputSource input) throws SAXException {
        if(input instanceof XMLEventReaderInputSource) {
            XMLEventReader xmlEventReader = ((XMLEventReaderInputSource) input).getXmlEventReader();
            parse(xmlEventReader);
        }
    }

    @Override
    public void parse(InputSource input, SAXUnmarshallerHandler saxUnmarshallerHandler) throws SAXException {
        if(input instanceof XMLEventReaderInputSource) {
            XMLEventReader xmlEventReader = ((XMLEventReaderInputSource) input).getXmlEventReader();
            //saxUnmarshallerHandler.setUnmarshalNamespaceResolver(new UnmarshalNamespaceContext(xmlEventReader));
            parse(xmlEventReader);
        }
    }

    public void parse(String systemId) throws SAXException {}

    private void parse(XMLEventReader xmlEventReader) throws SAXException {
        try {
            getContentHandler().startDocument();
            XMLEvent firstEvent = xmlEventReader.nextEvent();
            parseEvent(firstEvent);   
            while(depth > 0 && xmlEventReader.hasNext()) {
                XMLEvent xmlEvent = (XMLEvent)xmlEventReader.nextEvent();
                parseEvent(xmlEvent);                           
            }
            getContentHandler().endDocument();
        } catch(XMLStreamException ex) {
            throw new RuntimeException(ex);
        }
    }
   
    private void parseEvent(XMLEvent xmlEvent) throws SAXException {
        if(null == getContentHandler()) {
            return;
        }
        switch (xmlEvent.getEventType()) {
            case XMLEvent.ATTRIBUTE:  {
                break;
            }
            case XMLEvent.CDATA: {
                Characters characters = xmlEvent.asCharacters();
                if(null == lexicalHandler) {
                    getContentHandler().characters(characters.getData().toCharArray(), 0, characters.getData().length());
                } else {
                    lexicalHandler.startCDATA();
                    getContentHandler().characters(characters.getData().toCharArray(), 0, characters.getData().length());
                    lexicalHandler.endCDATA();
                }
                break;
            }
            case XMLEvent.CHARACTERS: {
                Characters characters = xmlEvent.asCharacters();
                getContentHandler().characters(characters.getData().toCharArray(), 0, characters.getData().length());
                break;
            }
            case XMLEvent.COMMENT: {
                if(null != lexicalHandler) {
                    Comment comment = (Comment)xmlEvent;
                    lexicalHandler.comment(comment.getText().toCharArray(), 0, comment.getText().length());
                }
                break;
            }
            case XMLEvent.DTD: {
                break;
            }
            case XMLEvent.END_DOCUMENT: {
                depth--;
                return;
            }
            case XMLEvent.END_ELEMENT: {
                ArrayList declaredNs = this.namespaces.get(new Integer(depth));
                depth--;
                EndElement endElement = xmlEvent.asEndElement();

                QName name = endElement.getName();
                String prefix = endElement.getName().getPrefix();
                if(null == prefix || prefix.length() == 0) {
                    getContentHandler().endElement(name.getNamespaceURI(), name.getLocalPart(), name.getLocalPart());                   
                } else {
                    getContentHandler().endElement(name.getNamespaceURI(), name.getLocalPart(), prefix + XMLConstants.COLON + name.getLocalPart());                   
                }
                if(declaredNs != null) {
                    Iterator iter = declaredNs.iterator();
                    while(iter.hasNext()) {
                        Namespace next = (Namespace)iter.next();
                        getContentHandler().endPrefixMapping(next.getPrefix());
                    }
                }               
                break;
            }
            case XMLEvent.ENTITY_DECLARATION: {
                break;
            }
            case XMLEvent.ENTITY_REFERENCE: {
                break;
            }
            case XMLEvent.NAMESPACE: {
                break;
            }
            case XMLEvent.NOTATION_DECLARATION: {
                break;
            }
            case XMLEvent.PROCESSING_INSTRUCTION: {
                ProcessingInstruction pi = (ProcessingInstruction)xmlEvent;
                getContentHandler().processingInstruction(pi.getTarget(), pi.getData());
                break;
            }
            case XMLEvent.SPACE: {
                char[] characters = xmlEvent.asCharacters().getData().toCharArray();
                getContentHandler().characters(characters, 0, characters.length);
                break;
            }
            case XMLEvent.START_DOCUMENT: {
                depth++;
                break;
            }
            case XMLEvent.START_ELEMENT: {
                depth++;
                StartElement startElement = xmlEvent.asStartElement();
                Iterator namespaces = startElement.getNamespaces();
                ArrayList<Namespace> declaredNs = null;
                if(namespaces.hasNext()) {
                    declaredNs = new ArrayList<Namespace>();
                }
                while(namespaces.hasNext()) {
                    Namespace next = (Namespace)namespaces.next();
                    getContentHandler().startPrefixMapping(next.getPrefix(), next.getNamespaceURI());
                    declaredNs.add(next);
                }
                if(declaredNs != null) {
                    this.namespaces.put(new Integer(depth), declaredNs);
                }
                QName qName = startElement.getName();
                String prefix = qName.getPrefix();
                if(null == prefix || prefix.length() == 0) {
                    getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), qName.getLocalPart(), new IndexedAttributeList(startElement.getAttributes(), startElement.getNamespaces()));                   
                } else {
                    getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), prefix + XMLConstants.COLON + qName.getLocalPart(), new IndexedAttributeList(startElement.getAttributes(), startElement.getNamespaces()));                   
                }
                break;
            }
        }      
    }

    private static class IndexedAttributeList implements Attributes {

        private List<Attribute> attributes;

        public IndexedAttributeList(Iterator attrs, Iterator namespaces) {
            this.attributes = new ArrayList<Attribute>();
            while(namespaces.hasNext()) {
                Namespace next = (Namespace)namespaces.next();
                String uri = XMLConstants.XMLNS_URL;
                String localName = next.getPrefix();
                String qName;
                if(null == localName || localName.length() == 0) {
                    localName = XMLConstants.XMLNS;
                    qName = XMLConstants.XMLNS;
                } else {
                    qName = XMLConstants.XMLNS + XMLConstants.COLON + localName;
                }
                String value = next.getNamespaceURI();
                attributes.add(new Attribute(uri, localName, qName, value));
            }

            while(attrs.hasNext()) {
                javax.xml.stream.events.Attribute next = (javax.xml.stream.events.Attribute)attrs.next();
                String uri = next.getName().getNamespaceURI();
                String localName = next.getName().getLocalPart();
                String prefix = next.getName().getPrefix();
                String qName;
                if(null == prefix || prefix.length() == 0) {
                    qName = localName;
                } else {
                    qName = prefix + XMLConstants.COLON + localName;
                }
                String value = next.getValue();
                attributes.add(new Attribute(uri, localName, qName, value));
            }
        }

        public int getIndex(String qName) {
            if(null == qName) {
                return -1;
            }
            int index = 0;
            for(Attribute attribute : attributes) {
                if(qName.equals(attribute.getName())) {
                    return index;
                }
                index++;
            }
            return -1;
        }

        public int getIndex(String uri, String localName) {
            if(null == localName) {
                return -1;
            }
            int index = 0;
            for(Attribute attribute : attributes) {
                QName testQName = new QName(uri, localName);
                if(attribute.getQName().equals(testQName)) {
                    return index;
                }
                index++;
            }
            return -1;
        }

        public int getLength() {
            return attributes.size();
        }

        public String getLocalName(int index) {
            return attributes.get(index).getQName().getLocalPart();
        }

        public String getQName(int index) {
            return attributes.get(index).getName();
        }

        public String getType(int index) {
            return XMLConstants.CDATA;
        }

        public String getType(String name) {
            return XMLConstants.CDATA;
        }

        public String getType(String uri, String localName) {
            return XMLConstants.CDATA;
        }

        public String getURI(int index) {
            return attributes.get(index).getQName().getNamespaceURI();
        }

        public String getValue(int index) {
            return attributes.get(index).getValue();
        }

        public String getValue(String qName) {
            int index = getIndex(qName);
            if(-1 == index) {
                return null;
            }
            return attributes.get(index).getValue();
        }

        public String getValue(String uri, String localName) {
            int index = getIndex(uri, localName);
            if(-1 == index) {
                return null;
            }
            return attributes.get(index).getValue();
        }

    }

    private static class Attribute {

        private QName qName;
        private String name;
        private String value;

        public Attribute(String uri, String localName, String name, String value) {
            this.qName = new QName(uri, localName);
            this.name = name;
            this.value = value;
        }

        public QName getQName() {
            return qName;
        }

        public String getName() {
            return name;
        }
       
        public String getValue() {
            return value;
        }

    }
}
TOP

Related Classes of org.eclipse.persistence.internal.oxm.record.XMLEventReaderReader$IndexedAttributeList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.