/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. 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:
*     bdoughan - June 24/2009 - 2.0 - Initial implementation
******************************************************************************/
package org.eclipse.persistence.internal.oxm.record;

import javax.xml.stream.XMLStreamReader;

import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.record.namespaces.UnmarshalNamespaceContext;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Locator2;

/**
 * Convert an XMLStreamReader into SAX events.
 */
public class XMLStreamReaderReader extends XMLReaderAdapter {

    private int depth = 0;
    private UnmarshalNamespaceContext unmarshalNamespaceContext;
    private XMLStreamReaderAttributes indexedAttributeList;
    private boolean qNameAware;
    private XMLStreamReader xmlStreamReader;

    public XMLStreamReaderReader() {
        unmarshalNamespaceContext = new UnmarshalNamespaceContext();
        indexedAttributeList = new XMLStreamReaderAttributes();
    }

    public XMLStreamReaderReader(Unmarshaller xmlUnmarshaller) {
        super(xmlUnmarshaller);
        unmarshalNamespaceContext = new UnmarshalNamespaceContext();
        indexedAttributeList = new XMLStreamReaderAttributes();
    }
    
    public Locator getLocator(){
    	if(locator == null){
    		locator = new StreamReaderLocator(xmlStreamReader);
    	}
    	return locator;
    }

    @Override
    public void setContentHandler (ContentHandler handler) {   
        if(handler instanceof UnmarshalRecord){
            ((UnmarshalRecord)handler).setUnmarshalNamespaceResolver(unmarshalNamespaceContext);
            qNameAware = false;
            if(null == validatingContentHandler) {
            	this.contentHandler = (UnmarshalRecord) handler;
            }else{
            	 validatingContentHandler.setContentHandler(handler);
            }
        }else if(handler instanceof SAXUnmarshallerHandler){
            ((SAXUnmarshallerHandler)handler).setUnmarshalNamespaceResolver(unmarshalNamespaceContext);
            qNameAware = true;
            if(null == validatingContentHandler) {
            	this.contentHandler = (SAXUnmarshallerHandler) handler;
            }else{
            	 validatingContentHandler.setContentHandler(handler);
            }
        } else {
        	super.setContentHandler(handler);
            qNameAware = true;
        }               
    }

    @Override
    public void parse(InputSource input) throws SAXException {
        if(null == contentHandler) {
            return;
        }
        if(input instanceof XMLStreamReaderInputSource) {
            XMLStreamReader xmlStreamReader = ((XMLStreamReaderInputSource) input).getXmlStreamReader();
            parse(xmlStreamReader);
        }
    }
  
    public void parse(XMLStreamReader xmlStreamReader) throws SAXException {
    	this.xmlStreamReader = xmlStreamReader;
        unmarshalNamespaceContext.setXmlStreamReader(xmlStreamReader);
        indexedAttributeList.setXmlStreamReader(xmlStreamReader);
        try {
            contentHandler.startDocument();
            parseEvent(xmlStreamReader, xmlStreamReader.getEventType());
            while(depth > 0) {
                int eventType = xmlStreamReader.next();
                parseEvent(xmlStreamReader, eventType);
            }
            if(xmlStreamReader.hasNext()) {
                xmlStreamReader.next();
            }
            contentHandler.endDocument();
        } catch(SAXException e ) {
            throw e;
        } catch(Exception e) {
            throw new SAXException(e);
        }
    }

    private void parseEvent(XMLStreamReader xmlStreamReader, int eventType) throws SAXException {
        switch (eventType) {
            case XMLStreamReader.START_ELEMENT: {
                depth++;
                int namespaceCount = xmlStreamReader.getNamespaceCount();
                if(namespaceCount > 0) {
                    for(int x=0; x<namespaceCount; x++) {
                        contentHandler.startPrefixMapping(xmlStreamReader.getNamespacePrefix(x), xmlStreamReader.getNamespaceURI(x));
                    }
                }
                String localName = xmlStreamReader.getLocalName();
                String namespaceURI = xmlStreamReader.getNamespaceURI();
                if(Constants.EMPTY_STRING.equals(namespaceURI)) {
                    namespaceURI = null;
                }
                if(qNameAware) {
                    String prefix = xmlStreamReader.getPrefix();
                    if(null == prefix || prefix.length() == 0) {
                        contentHandler.startElement(namespaceURI, localName, localName, indexedAttributeList.reset());
                    } else {
                        contentHandler.startElement(namespaceURI, localName, prefix + Constants.COLON + localName, indexedAttributeList.reset());
                    }
                } else {
                    contentHandler.startElement(namespaceURI, localName, null, indexedAttributeList.reset());
                }
                break;
            }
            case XMLStreamReader.END_ELEMENT: {
                depth--;
                String localName = xmlStreamReader.getLocalName();
                String namespaceURI = xmlStreamReader.getNamespaceURI();
                if(Constants.EMPTY_STRING.equals(namespaceURI)) {
                    namespaceURI = null;
                }
                if(qNameAware) {
                    String prefix = xmlStreamReader.getPrefix();
                    if(null == prefix || prefix.length() == 0) {
                        contentHandler.endElement(namespaceURI, localName, localName);
                    } else {
                        contentHandler.endElement(namespaceURI, localName, prefix + Constants.COLON + localName);
                    }
                } else {
                    contentHandler.endElement(namespaceURI, localName, null);
                }
                int namespaceCount = xmlStreamReader.getNamespaceCount();
                if(namespaceCount > 0) {
                    for(int x=0; x<namespaceCount; x++) {
                        contentHandler.endPrefixMapping(xmlStreamReader.getNamespacePrefix(x));
                    }
                }
               break;
            }
            case XMLStreamReader.PROCESSING_INSTRUCTION: {
                contentHandler.processingInstruction(xmlStreamReader.getPITarget(), xmlStreamReader.getPIData());
                break;
            }
            case XMLStreamReader.CHARACTERS: {
                parseCharactersEvent(xmlStreamReader);
                break;
            }
            case XMLStreamReader.COMMENT: {
                if(null != lexicalHandler) {
                    lexicalHandler.comment(xmlStreamReader.getTextCharacters(), xmlStreamReader.getTextStart(), xmlStreamReader.getTextLength());
                }
                break;
            }
            case XMLStreamReader.SPACE: {
                contentHandler.characters(xmlStreamReader.getTextCharacters(), xmlStreamReader.getTextStart(), xmlStreamReader.getTextLength());
                break;
            }
            case XMLStreamReader.START_DOCUMENT: {
                depth++;
                break;
            }
            case XMLStreamReader.END_DOCUMENT: {
                depth--;
                return;
            }
            case XMLStreamReader.ENTITY_REFERENCE: {
                break;
            }
            case XMLStreamReader.ATTRIBUTE: {
                break;
            }
            case XMLStreamReader.DTD: {
                break;
            }
            case XMLStreamReader.CDATA: {
                char[] characters = xmlStreamReader.getText().toCharArray();
                if(null == lexicalHandler) {
                    parseCharactersEvent(xmlStreamReader);
                } else {
                    lexicalHandler.startCDATA();
                    parseCharactersEvent(xmlStreamReader);
                    lexicalHandler.endCDATA();
                }
                break;
            }
        }
    }

    /**
     * Subclasses of this class can override this method to provide alternate
     * mechanisms for processing the characters event.  One possibility is
     * obtaining a CharSequence and calling the corresponding characters method
     * on the extended content handler.
     */
    protected void parseCharactersEvent(XMLStreamReader xmlStreamReader) throws SAXException {
        contentHandler.characters(xmlStreamReader.getTextCharacters(), xmlStreamReader.getTextStart(), xmlStreamReader.getTextLength());
    }

    private static class XMLStreamReaderAttributes  extends IndexedAttributeList {

        private XMLStreamReader xmlStreamReader;

        public void setXmlStreamReader(XMLStreamReader xmlStreamReader) {
            this.xmlStreamReader = xmlStreamReader;
        }

        @Override
        protected Attribute[] attributes() {
            if(null == attributes) {
                int namespaceCount = xmlStreamReader.getNamespaceCount();
                int attributeCount = xmlStreamReader.getAttributeCount();
                if(namespaceCount + attributeCount == 0) {
                    attributes = NO_ATTRIBUTES;
                } else {
                    attributes = new Attribute[attributeCount + namespaceCount];
                    for(int x=0; x<attributeCount; x++) {
                        String uri = xmlStreamReader.getAttributeNamespace(x);
                        String localName = xmlStreamReader.getAttributeLocalName(x);
                        String prefix = xmlStreamReader.getAttributePrefix(x);
                        String qName;
                        if(null == prefix || prefix.length() == 0) {
                            qName = localName;
                        } else {
                            qName = prefix + Constants.COLON + localName;
                        }
                        String value = xmlStreamReader.getAttributeValue(x);
                        attributes[x] = new Attribute(uri, localName, qName, value);
                    }
                    for(int x=0; x<namespaceCount; x++) {
                        String uri = javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
                        String localName = xmlStreamReader.getNamespacePrefix(x);
                        String qName;
                        if(null == localName || localName.length() == 0) {
                            localName = javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
                            qName = javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
                        } else {
                            qName = javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + localName;
                        }
                        String value = xmlStreamReader.getNamespaceURI(x);
                        attributes[x + attributeCount] = new Attribute(uri, localName, qName, value);
                    }               

                }
            }
            return attributes;
        }

        @Override
        public String getValue(String uri, String localName) {
            if (Constants.EMPTY_STRING.equals(uri)) {
                uri = null;
            }
            return xmlStreamReader.getAttributeValue(uri, localName);
        }

    }

    /**
     * <p>An implementation of Locator, created from an existing XMLStreamReader.</p>
     *
     * @see org.xml.sax.Locator
     * @see javax.xml.stream.XMLStreamReader
     */
    private class StreamReaderLocator implements Locator2 {

        private XMLStreamReader reader;

        /**
         * Instantiates a new StreamReaderLocator.
         *
         * @param r the XMLStreamReader object from which to copy location information.
         */
        public StreamReaderLocator(XMLStreamReader r) {
            this.reader = r;
        }

        /**
         * Returns the public ID of this Locator.
         */
        public String getPublicId() {
            return this.reader.getLocation().getPublicId();
        }

        /**
         * Returns the system ID of this Locator.
         */
        public String getSystemId() {
            return this.reader.getLocation().getSystemId();
        }

        /**
         * Returns the line number of this Locator.
         */
        public int getLineNumber() {
            return this.reader.getLocation().getLineNumber();
        }

        /**
         * Returns the column number of this Locator.
         */
        public int getColumnNumber() {
            return this.reader.getLocation().getColumnNumber();
        }

        public String getXMLVersion() {
            return null;
        }

        public String getEncoding() {
            return null;
        }

    }
    
}