/*
 * Copyright (c) 2005, 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.xml.internal.stream;

import com.sun.xml.internal.stream.events.XMLEventAllocatorImpl;
import java.util.NoSuchElementException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.XMLEventAllocator;

/**
 * @author  @author  Neeraj Bajaj Sun Microsystems
 *
 */

public class XMLEventReaderImpl implements javax.xml.stream.XMLEventReader{

    protected XMLStreamReader fXMLReader ;
    protected XMLEventAllocator fXMLEventAllocator;

    //only constructor will do because we delegate everything to underlying XMLStreamReader
    public XMLEventReaderImpl(XMLStreamReader reader) throws  XMLStreamException {
        fXMLReader = reader ;
        fXMLEventAllocator = (XMLEventAllocator)reader.getProperty(XMLInputFactory.ALLOCATOR);
        if(fXMLEventAllocator == null){
            fXMLEventAllocator = new XMLEventAllocatorImpl();
        }
        fPeekedEvent = fXMLEventAllocator.allocate(fXMLReader);
    }


    public boolean hasNext() {
        //if we have the peeked event return 'true'
        if(fPeekedEvent != null)return true;
        //this is strange XMLStreamReader throws XMLStreamException
        //XMLEventReader doesn't throw XMLStreamException
        boolean next = false ;
        try{
            next = fXMLReader.hasNext();
        }catch(XMLStreamException ex){
            return false;
        }
        return next ;
    }


    public XMLEvent nextEvent() throws XMLStreamException {
        //if application peeked return the peeked event
        if(fPeekedEvent != null){
            fLastEvent = fPeekedEvent ;
            fPeekedEvent = null;
            return fLastEvent ;
        }
        else if(fXMLReader.hasNext()){
            //advance the reader to next state.
            fXMLReader.next();
            return fLastEvent = fXMLEventAllocator.allocate(fXMLReader);
        }
        else{
            fLastEvent = null;
            throw new NoSuchElementException();
        }
    }

    public void remove(){
        //remove of the event is not supported.
        throw new java.lang.UnsupportedOperationException();
    }


    public void close() throws XMLStreamException {
        fXMLReader.close();
    }

    /** Reads the content of a text-only element. Precondition:
     * the current event is START_ELEMENT. Postcondition:
     * The current event is the corresponding END_ELEMENT.
     * @throws XMLStreamException if the current event is not a START_ELEMENT
     * or if a non text element is encountered
     */
    public String getElementText() throws XMLStreamException {
        //we have to keep reference to the 'last event' of the stream to be able
        //to make this check - is there another way ? - nb.
        if(fLastEvent.getEventType() != XMLEvent.START_ELEMENT){
            throw new XMLStreamException(
            "parser must be on START_ELEMENT to read next text", fLastEvent.getLocation());
        }

        // STag content ETag
        //[43]   content   ::=   CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*

        //<foo>....some long text say in KB and underlying parser reports multiple character
        // but getElementText() events....</foo>

        String data = null;
        //having a peeked event makes things really worse -- we have to test the first event
        if(fPeekedEvent != null){
            XMLEvent event = fPeekedEvent ;
            fPeekedEvent = null;
            int type = event.getEventType();

            if(  type == XMLEvent.CHARACTERS || type == XMLEvent.SPACE ||
            type == XMLEvent.CDATA){
                data = event.asCharacters().getData();
            }
            else if(type == XMLEvent.ENTITY_REFERENCE){
                data = ((EntityReference)event).getDeclaration().getReplacementText();
            }
            else if(type == XMLEvent.COMMENT || type == XMLEvent.PROCESSING_INSTRUCTION){
                //ignore
            } else if(type == XMLEvent.START_ELEMENT) {
                throw new XMLStreamException(
                "elementGetText() function expects text only elment but START_ELEMENT was encountered.", event.getLocation());
            }else if(type == XMLEvent.END_ELEMENT){
                return "";
            }

            //create the string buffer and add initial data
            StringBuffer buffer = new StringBuffer();
            if(data != null && data.length() > 0 ) {
                buffer.append(data);
            }
            //get the next event -- we should stop at END_ELEMENT but it can be any thing
            //things are worse when implementing this function in XMLEventReader because
            //there isn't any function called getText() which can get values for
            //space, cdata, characters and entity reference
            //nextEvent() would also set the last event.
            event = nextEvent();
            while(event.getEventType() != XMLEvent.END_ELEMENT){
                if(  type == XMLEvent.CHARACTERS || type == XMLEvent.SPACE ||
                type == XMLEvent.CDATA){
                    data = event.asCharacters().getData();
                }
                else if(type == XMLEvent.ENTITY_REFERENCE){
                    data = ((EntityReference)event).getDeclaration().getReplacementText();
                }
                else if(type == XMLEvent.COMMENT || type == XMLEvent.PROCESSING_INSTRUCTION){
                    //ignore
                } else if(type == XMLEvent.END_DOCUMENT) {
                    throw new XMLStreamException("unexpected end of document when reading element text content");
                } else if(type == XMLEvent.START_ELEMENT) {
                    throw new XMLStreamException(
                    "elementGetText() function expects text only elment but START_ELEMENT was encountered.", event.getLocation());
                } else {
                    throw new XMLStreamException(
                    "Unexpected event type "+ type, event.getLocation());
                }
                //add the data to the buffer
                if(data != null && data.length() > 0 ) {
                    buffer.append(data);
                }
                event = nextEvent();
            }
            return buffer.toString();
        }//if (fPeekedEvent != null)

        //if there was no peeked, delegate everything to fXMLReader
        //update the last event before returning the text
        data = fXMLReader.getElementText();
        fLastEvent = fXMLEventAllocator.allocate(fXMLReader);
        return data;
    }

    /** Get the value of a feature/property from the underlying implementation
     * @param name The name of the property
     * @return The value of the property
     * @throws IllegalArgumentException if the property is not supported
     */
    public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
        return fXMLReader.getProperty(name) ;
    }

    /** Skips any insignificant space events until a START_ELEMENT or
     * END_ELEMENT is reached. If anything other than space characters are
     * encountered, an exception is thrown. This method should
     * be used when processing element-only content because
     * the parser is not able to recognize ignorable whitespace if
     * the DTD is missing or not interpreted.
     * @throws XMLStreamException if anything other than space characters are encountered
     */
    public XMLEvent nextTag() throws XMLStreamException {
        //its really a pain if there is peeked event before calling nextTag()
        if(fPeekedEvent != null){
            //check the peeked event first.
            XMLEvent event = fPeekedEvent;
            fPeekedEvent = null ;
            int eventType = event.getEventType();
            //if peeked event is whitespace move to the next event
            //if peeked event is PI or COMMENT move to the next event
            if( (event.isCharacters() && event.asCharacters().isWhiteSpace())
            || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
            || eventType == XMLStreamConstants.COMMENT
            || eventType == XMLStreamConstants.START_DOCUMENT){
                event = nextEvent();
                eventType = event.getEventType();
            }

            //we have to have the while loop because there can be many PI or comment event in sucession
            while((event.isCharacters() && event.asCharacters().isWhiteSpace())
            || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
            || eventType == XMLStreamConstants.COMMENT){

                event = nextEvent();
                eventType = event.getEventType();
            }

            if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
                throw new XMLStreamException("expected start or end tag", event.getLocation());
            }
            return event;
        }

        //if there is no peeked event -- delegate the work of getting next event to fXMLReader
        fXMLReader.nextTag();
        return (fLastEvent = fXMLEventAllocator.allocate(fXMLReader));
    }

    public Object next() {
        Object object = null;
        try{
            object = nextEvent();
        }catch(XMLStreamException streamException){
            fLastEvent = null ;
            //don't swallow the cause
            NoSuchElementException e = new NoSuchElementException(streamException.getMessage());
            e.initCause(streamException.getCause());
            throw e;

        }
        return object;
    }

    public XMLEvent peek() throws XMLStreamException{
        //if someone call peek() two times we should just return the peeked event
        //this is reset if we call next() or nextEvent()
        if(fPeekedEvent != null) return fPeekedEvent;

        if(hasNext()){
            //revisit: we can implement peek() by calling underlying reader to advance
            // the stream and returning the event without the knowledge of the user
            // that the stream was advanced but the point is we are advancing the stream
            //here. -- nb.

            // Is there any application that relies on this behavior ?
            //Can it be an application knows that there is particularly very large 'comment' section
            //or character data which it doesn't want to read or to be returned as event
            //But as of now we are creating every event but it can be optimized not to create
            // the event.
            fXMLReader.next();
            fPeekedEvent = fXMLEventAllocator.allocate(fXMLReader);
            return fPeekedEvent;
        }else{
            return null;
        }
    }//peek()

    private XMLEvent fPeekedEvent;
    private XMLEvent fLastEvent;

}//XMLEventReaderImpl
