/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.xmlbeans.impl.validator;

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.impl.common.QNameHelper;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.Location;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.StreamReaderDelegate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * This class is a wrapper over a generic XMLStreamReader that provides validation.
 * There are 3 cases:
 * <br/> 1) the XMLStreamReader represents a document, it contains only one element document
 *          - in this case the user schema type should be null or it should be a document SchemaType
 * <br/> 2) the XMLStreamReader represents an xml-fragment (content only) - must have at least one user type or xsi:type
 * <br/>     a) it has an xsi:type - if user schema type is available it has to be a base type of xsi:type
 * <br/>     b) it doesn't have xsi:type - user must provide a schema type
 *         otherwise will error and will not do validation
 * <br/> 3) the XMLStreamReader represents a global attribute - i.e. user schema type is null and only one attribute
 * <br/>
 *
 * @author Cezar Andrei (cezar.andrei at bea.com)
 * Date: Feb 13, 2004
 */
public class ValidatingXMLStreamReader
    extends StreamReaderDelegate
    implements XMLStreamReader
{
    private static final String URI_XSI = "http://www.w3.org/2001/XMLSchema-instance";
    private static final QName XSI_TYPE = new QName(URI_XSI, "type");
    private static final QName XSI_NIL  = new QName(URI_XSI, "nil");
    private static final QName XSI_SL   = new QName(URI_XSI, "schemaLocation");
    private static final QName XSI_NSL  = new QName(URI_XSI, "noNamespaceSchemaLocation");

    private SchemaType _contentType;
    private SchemaTypeLoader _stl;
    private XmlOptions _options;
    private Collection _errorListener;
    protected Validator _validator;
    private final ElementEventImpl _elemEvent;
    private final AttributeEventImpl _attEvent;
    private final SimpleEventImpl _simpleEvent;
    private PackTextXmlStreamReader _packTextXmlStreamReader;

    private int _state;
    private final int STATE_FIRSTEVENT = 0;
    private final int STATE_VALIDATING = 1;
    private final int STATE_ATTBUFFERING = 2;
    private final int STATE_ERROR = 3;

    private List _attNamesList;
    private List _attValuesList;
    private SchemaType _xsiType;

    private int _depth;

    /**
     * Default constructor. Use init(...) to set the params.
     * See {@link #init}
     */
    public ValidatingXMLStreamReader()
    {
        super();
        _elemEvent = new ElementEventImpl();
        _attEvent = new AttributeEventImpl();
        _simpleEvent = new SimpleEventImpl();
        _packTextXmlStreamReader = new PackTextXmlStreamReader();
    }

    /**
     * Used in case of reusing the same ValidatinXMLStreamReader object
     * @param xsr The stream to be validated
     * @param startWithCurrentEvent Validation will start if true with the current event or if false with the next event in the stream
     * @param contentType The schemaType of the content. This can be null for document and global Att validation
     * @param stl SchemaTypeLoader context of validation
     * @param options Validator options
     * @param errorListener Errors and warnings listener
     */
    public void init(XMLStreamReader xsr, boolean startWithCurrentEvent, SchemaType contentType,
                     SchemaTypeLoader stl, XmlOptions options, Collection errorListener)
    {
        _packTextXmlStreamReader.init(xsr);

//        setParent(xsr);
        setParent(_packTextXmlStreamReader);
        _contentType = contentType;
        _stl = stl;
        _options = options;
        _errorListener = errorListener;
//        _elemEvent.setXMLStreamReader(xsr);
//        _attEvent.setXMLStreamReader(xsr);
//        _simpleEvent.setXMLStreamReader(xsr);
        _elemEvent.setXMLStreamReader(_packTextXmlStreamReader);
        _attEvent.setXMLStreamReader(_packTextXmlStreamReader);
        _simpleEvent.setXMLStreamReader(_packTextXmlStreamReader);
        _validator = null;
        _state = STATE_FIRSTEVENT;
        if (_attNamesList!=null)
        {
            _attNamesList.clear();
            _attValuesList.clear();
        }
        _xsiType = null;
        _depth = 0;

        if (startWithCurrentEvent)
        {
            int evType = getEventType();
            validate_event(evType);
        }
    }

    private static class PackTextXmlStreamReader
        extends StreamReaderDelegate
        implements XMLStreamReader
    {
        private boolean _hasBufferedText;
        private StringBuilder _buffer = new StringBuilder();
        private int _textEventType;

        void init(XMLStreamReader xmlstream)
        {
            setParent(xmlstream);
            _hasBufferedText = false;
            _buffer.delete(0, _buffer.length());
        }

        public int next()
            throws XMLStreamException
        {
            if (_hasBufferedText)
            {
                clearBuffer();
                return super.getEventType();
            }

            int evType = super.next();

            if (evType == XMLEvent.CHARACTERS || evType == XMLEvent.CDATA || evType == XMLEvent.SPACE)
            {
                _textEventType = evType;
                bufferText();
            }

            return evType;
        }

        private void clearBuffer()
        {
            _buffer.delete(0, _buffer.length());
            _hasBufferedText = false;
        }

        private void bufferText()
            throws XMLStreamException
        {
            if (super.hasText())
                _buffer.append( super.getText());

            _hasBufferedText = true;

            while (hasNext())
            {
                int evType = super.next();

                switch (evType)
                {
                case XMLEvent.CHARACTERS:
                case XMLEvent.CDATA:
                case XMLEvent.SPACE:
                    if (super.hasText())
                        _buffer.append(super.getText());

                case XMLEvent.COMMENT:
                    //ignore
                    continue;
                default:
                    return;
                }
            }
        }

        public String getText()
        {
            assert _hasBufferedText;
            return _buffer.toString();
        }

        public int getTextLength()
        {
            assert _hasBufferedText;
            return _buffer.length();
        }

        public int getTextStart()
        {
            assert _hasBufferedText;
            return 0;
        }

        public char[] getTextCharacters()
        {
            assert _hasBufferedText;
            return _buffer.toString().toCharArray();
        }

        public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
        {
            assert _hasBufferedText;
            _buffer.getChars(sourceStart, sourceStart + length, target, targetStart);
            return length;
        }

        public boolean isWhiteSpace()
        {
            assert _hasBufferedText;
            return XmlWhitespace.isAllSpace(_buffer);
        }

        public boolean hasText()
        {
            if (_hasBufferedText)
                return true;
            else
                return super.hasText();
        }

        public int getEventType()
        {
            if (_hasBufferedText)
                return _textEventType;
            else
                return super.getEventType();
        }
    }

    private static class ElementEventImpl
        implements ValidatorListener.Event
    {
        private static final int BUF_LENGTH = 1024;
        private char[] _buf = new char[BUF_LENGTH];
        private int _length;
        private boolean _supportForGetTextCharacters = true;

        private XMLStreamReader _xmlStream;

        private void setXMLStreamReader(XMLStreamReader xsr)
        {
            _xmlStream = xsr;
        }

        // can return null, used only to locate errors
        public XmlCursor getLocationAsCursor()
        {
            return null;
        }

        public javax.xml.stream.Location getLocation()
        {
            return _xmlStream.getLocation();
        }

        // fill up chars with the xsi:type attribute value if there is one othervise return false
        public String getXsiType() // BEGIN xsi:type
        {
            return _xmlStream.getAttributeValue(URI_XSI, "type");
        }

        // fill up chars with xsi:nill attribute value if any
        public String getXsiNil() // BEGIN xsi:nil
        {
            return _xmlStream.getAttributeValue(URI_XSI, "nil");
        }

        // not used curently
        public String getXsiLoc() // BEGIN xsi:schemaLocation
        {
            return _xmlStream.getAttributeValue(URI_XSI, "schemaLocation");
        }

        // not used curently
        public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation
        {
            return _xmlStream.getAttributeValue(URI_XSI, "noNamespaceSchemaLocation");
        }

        // On START and ATTR
        public QName getName()
        {
            // avoid construction of a new QName object after the bug in getName() is fixed.
            if (_xmlStream.hasName())
                return new QName(_xmlStream.getNamespaceURI(), _xmlStream.getLocalName());
            else
                return null;
        }

        // On TEXT and ATTR
        public String getText()
        {
            _length = 0;
            addTextToBuffer();
            return new String( _buf, 0, _length );
//            return _xmlStream.getText();
        }

        public String getText(int wsr)
        {
            return XmlWhitespace.collapse( _xmlStream.getText(), wsr );
        }

        public boolean textIsWhitespace()
        {
            return _xmlStream.isWhiteSpace();
        }

        public String getNamespaceForPrefix(String prefix)
        {
            return _xmlStream.getNamespaceURI(prefix);
        }

        private void addTextToBuffer()
        {
            int textLength = _xmlStream.getTextLength();
            ensureBufferLength(textLength);

            if (_supportForGetTextCharacters)
                try
                {
                    _length = _xmlStream.getTextCharacters(0, _buf, _length, textLength);
                }
                catch(Exception e)
                {
                    _supportForGetTextCharacters = false;
                }

            if(!_supportForGetTextCharacters)
            {
                System.arraycopy(_xmlStream.getTextCharacters(), _xmlStream.getTextStart(), _buf, _length, textLength);
                _length = _length + textLength;
            }
        }

        private void ensureBufferLength(int lengthToAdd)
        {
            if (_length + lengthToAdd>_buf.length)
            {
                char[] newBuf = new char[_length + lengthToAdd];
                if (_length>0)
                    System.arraycopy(_buf, 0, newBuf, 0, _length);
                _buf = newBuf;
            }
        }
    }

    private static final class AttributeEventImpl
        implements ValidatorListener.Event
    {
        private int _attIndex;
        private XMLStreamReader _xmlStream;

        private void setXMLStreamReader(XMLStreamReader xsr)
        {
            _xmlStream = xsr;
        }

        // can return null, used only to locate errors
        public XmlCursor getLocationAsCursor()
        {
            return null;
        }

        public javax.xml.stream.Location getLocation()
        {
            return _xmlStream.getLocation();
        }

        // fill up chars with the xsi:type attribute value if there is one othervise return false
        public String getXsiType() // BEGIN xsi:type
        {
            throw new IllegalStateException();
        }

        // fill up chars with xsi:nill attribute value if any
        public String getXsiNil() // BEGIN xsi:nil
        {
            throw new IllegalStateException();
        }

        // not used curently
        public String getXsiLoc() // BEGIN xsi:schemaLocation
        {
            throw new IllegalStateException();
        }

        // not used curently
        public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation
        {
            throw new IllegalStateException();
        }

        // On START and ATTR
        public QName getName()
        {
            assert _xmlStream.isStartElement() : "Not on Start Element.";
            String uri = _xmlStream.getAttributeNamespace(_attIndex);
            QName qn = new QName(uri==null ? "" : uri, _xmlStream.getAttributeLocalName(_attIndex));
            //System.out.println("    Att QName: " + qn);
            return qn;
        }

        // On TEXT and ATTR
        public String getText()
        {
            assert _xmlStream.isStartElement() : "Not on Start Element.";
            return _xmlStream.getAttributeValue(_attIndex);
        }

        public String getText(int wsr)
        {
            assert _xmlStream.isStartElement() : "Not on Start Element.";
            return XmlWhitespace.collapse( _xmlStream.getAttributeValue(_attIndex), wsr );
        }

        public boolean textIsWhitespace()
        {
            throw new IllegalStateException();
        }

        public String getNamespaceForPrefix(String prefix)
        {
            assert _xmlStream.isStartElement() : "Not on Start Element.";
            return _xmlStream.getNamespaceURI(prefix);
        }

        private void setAttributeIndex(int attIndex)
        {
            _attIndex = attIndex;
        }
    }

    /**
     * This is used as implementation of Event for validating global attributes
     * and for pushing the buffered attributes
     */
    private static final class SimpleEventImpl
        implements ValidatorListener.Event
    {
        private String _text;
        private QName  _qname;
        private XMLStreamReader _xmlStream;

        private void setXMLStreamReader(XMLStreamReader xsr)
        {
            _xmlStream = xsr;
        }

        // should return null, getLocation will be used, used only to locate errors
        public XmlCursor getLocationAsCursor()
        { return null; }

        public javax.xml.stream.Location getLocation()
        {
            return _xmlStream.getLocation();
        }

        // fill up chars with the xsi:type attribute value if there is one othervise return false
        public String getXsiType() // BEGIN xsi:type
        { return null; }

        // fill up chars with xsi:nill attribute value if any
        public String getXsiNil() // BEGIN xsi:nil
        { return null; }

        // not used curently
        public String getXsiLoc() // BEGIN xsi:schemaLocation
        { return null; }

        // not used curently
        public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation
        { return null; }

        // On START and ATTR
        public QName getName()
        { return _qname; }

        // On TEXT and ATTR
        public String getText()
        {
            return _text;
        }

        public String getText(int wsr)
        {
            return XmlWhitespace.collapse( _text, wsr );
        }

        public boolean textIsWhitespace()
        { return false; }

        public String getNamespaceForPrefix(String prefix)
        {
            return _xmlStream.getNamespaceURI(prefix);
        }
    }

    /* public methods in XMLStreamReader */

    public Object getProperty(String s) throws IllegalArgumentException
    {
        return super.getProperty(s);
    }

    public int next() throws XMLStreamException
    {
        int evType = super.next();
        //debugEvent(evType);

        validate_event(evType);

        return evType;
    }

    private void validate_event(int evType)
    {
        if (_state==STATE_ERROR)
            return;

        if (_depth<0)
            throw new IllegalArgumentException("ValidatingXMLStreamReader cannot go further than the subtree is was initialized on.");

        switch(evType)
        {
        case XMLEvent.START_ELEMENT:
            _depth++;
            if (_state == STATE_ATTBUFFERING)
                pushBufferedAttributes();

            if (_validator==null)
            {
                // avoid construction of a new QName object after the bug in getName() is fixed.
                QName qname = new QName(getNamespaceURI(), getLocalName());

                if (_contentType==null)
                    _contentType = typeForGlobalElement(qname);

                if (_state==STATE_ERROR)
                    break;

                initValidator(_contentType);
                _validator.nextEvent(Validator.BEGIN, _elemEvent);
            }

            _validator.nextEvent(Validator.BEGIN, _elemEvent);

            int attCount = getAttributeCount();
            validate_attributes(attCount);

            break;

        case XMLEvent.ATTRIBUTE:
            if (getAttributeCount()==0)
                break;

            if (_state == STATE_FIRSTEVENT || _state == STATE_ATTBUFFERING)
            {
                // buffer all Attributes
                for (int i=0; i<getAttributeCount(); i++)
                {
                    // avoid construction of a new QName object after the bug in getName() is fixed.
                    QName qname = new QName(getAttributeNamespace(i), getAttributeLocalName(i));

                    if (qname.equals(XSI_TYPE))
                    {
                        String xsiTypeValue = getAttributeValue(i);
                        String uri = super.getNamespaceURI(QNameHelper.getPrefixPart(xsiTypeValue));
                        QName xsiTypeQname = new QName(uri, QNameHelper.getLocalPart(xsiTypeValue));
                        _xsiType = _stl.findType(xsiTypeQname);
                    }

                    if (_attNamesList==null)
                    {
                        _attNamesList = new ArrayList();
                        _attValuesList = new ArrayList();
                    }
                    // skip xsi:type xsi:nil xsi:schemaLocation xsi:noNamespaceSchemaLocation
                    if (isSpecialAttribute(qname))
                        continue;

                    _attNamesList.add(qname);
                    _attValuesList.add(getAttributeValue(i));
                }
                _state = STATE_ATTBUFFERING;
            }
            else
                throw new IllegalStateException("ATT event must be only at the beggining of the stream.");

            break;

        case XMLEvent.END_ELEMENT:
        case XMLEvent.END_DOCUMENT:
            _depth--;
            if (_state == STATE_ATTBUFFERING)
                pushBufferedAttributes();

            _validator.nextEvent(Validator.END, _elemEvent);
            break;

        case XMLEvent.CDATA:
        case XMLEvent.CHARACTERS:
            if (_state == STATE_ATTBUFFERING)
                pushBufferedAttributes();

            if (_validator==null)
            {
                if (_contentType==null)
                {
                    if (isWhiteSpace()) // hack/workaround for avoiding errors for parsers that do not generate XMLEvent.SPACE
                        break;

                    addError("No content type provided for validation of a content model.");
                    _state = STATE_ERROR;
                    break;
                }
                initValidator(_contentType);
                _validator.nextEvent(Validator.BEGIN, _simpleEvent);
            }

            _validator.nextEvent(Validator.TEXT, _elemEvent);
            break;

        case XMLEvent.START_DOCUMENT:
            _depth++;
            break;

        case XMLEvent.COMMENT:
        case XMLEvent.DTD:
        case XMLEvent.ENTITY_DECLARATION:
        case XMLEvent.ENTITY_REFERENCE:
        case XMLEvent.NAMESPACE:
        case XMLEvent.NOTATION_DECLARATION:
        case XMLEvent.PROCESSING_INSTRUCTION:
        case XMLEvent.SPACE:
            //ignore
            break;

        default:
            throw new IllegalStateException("Unknown event type.");
        }
    }

    private void pushBufferedAttributes()
    {
        SchemaType validationType = null;

        if (_xsiType!=null)
        {
            if (_contentType==null)
            {
                validationType = _xsiType;
            }
            else
            {
                // we have both _xsiType and _contentType
                if (_contentType.isAssignableFrom(_xsiType))
                {
                    validationType = _xsiType;
                }
                else
                {
                    addError("Specified type '" + _contentType +
                        "' not compatible with found xsi:type '" + _xsiType + "'.");
                    _state = STATE_ERROR;
                    return;
                }
            }
        }
        else
        {
            if (_contentType != null)
            {
                validationType = _contentType;
            }
            else if (_attNamesList!=null)
            {
                // no xsi:type, no _contentType
                // this is the global attribute case
                validationType = _stl.findAttributeType((QName)_attNamesList.get(0));
                if (validationType==null)
                {
                    addError("A schema global attribute with name '" + _attNamesList.get(0) +
                        "' could not be found in the current schema type loader.");
                    _state = STATE_ERROR;
                    return;
                }
                // if _attNamesList.size() > 1 than the validator will add an error
            }
            else
            {
                addError("No content type provided for validation of a content model.");
                _state = STATE_ERROR;
                return;
            }
        }

        // here validationType is the right type, start pushing all acumulated attributes
        initValidator(validationType);
        _validator.nextEvent(Validator.BEGIN, _simpleEvent);

        // validate attributes from _attNamesList
        validate_attributes(_attNamesList.size());
        _attNamesList = null;
        _attValuesList = null;

        _state = STATE_VALIDATING;
    }

    private boolean isSpecialAttribute(QName qn)
    {
        if (qn.getNamespaceURI().equals(URI_XSI))
            return qn.getLocalPart().equals(XSI_TYPE.getLocalPart()) ||
                qn.getLocalPart().equals(XSI_NIL.getLocalPart()) ||
                qn.getLocalPart().equals(XSI_SL.getLocalPart()) ||
                qn.getLocalPart().equals(XSI_NSL.getLocalPart());

        return false;
    }

    /**
     * Initializes the validator for the given schemaType
     * @param schemaType
     */
    private void initValidator(SchemaType schemaType)
    {
        assert schemaType!=null;

        _validator = new Validator(schemaType, null, _stl, _options, _errorListener);
    }

    private SchemaType typeForGlobalElement(QName qname)
    {
        assert qname!=null;

        SchemaType docType = _stl.findDocumentType(qname);

        if (docType==null)
        {
            addError("Schema document type not found for element '" + qname + "'.");
            _state = STATE_ERROR;
        }
        return docType;
    }

    private void addError(String msg)
    {
        String source = null;
        Location location = getLocation();

        if (location != null)
        {
            source = location.getPublicId();
            if (source==null)
                source = location.getSystemId();

            _errorListener.add(XmlError.forLocation(msg, source, location));
        }
        else
            _errorListener.add(XmlError.forMessage(msg));
    }

    protected void validate_attributes(int attCount)
    {
        for(int i=0; i<attCount; i++)
        {
            validate_attribute(i);
        }

        if (_options!=null && _options.isAttributeValidationCompatMode())
        {}
        else
            _validator.nextEvent(Validator.ENDATTRS, _simpleEvent);
    }

    protected void validate_attribute(int attIndex)
    {
        ValidatorListener.Event event;
        if (_attNamesList==null)
        {
            _attEvent.setAttributeIndex(attIndex);
            QName qn = _attEvent.getName();
            if (isSpecialAttribute(qn))
                return;

            event = _attEvent;
        }
        else
        {
            _simpleEvent._qname = (QName)_attNamesList.get(attIndex);
            _simpleEvent._text = (String)_attValuesList.get(attIndex);
            event = _simpleEvent;
        }

        _validator.nextEvent(Validator.ATTR, event);
    }

    /**
     * @return Returns the validation state up to this point.
     * NOTE: At least one START ELEMENT should have been consumed for a valid value to be returned.
     */
    public boolean isValid()
    {
        if ( _state==STATE_ERROR || _validator==null)
            return false;

        return _validator.isValid();
    }

//    /* for unit testing */
//    public static void main(String[] args) throws FileNotFoundException, XMLStreamException
//    {
//        ValidatingXMLStreamReader valXsr = new ValidatingXMLStreamReader();
//        for( int i = 0; i<args.length; i++)
//        {
//            validate(valXsr, args[i]);
//        }
//    }
//
//    private static void validate(ValidatingXMLStreamReader valXsr, String file)
//        throws XMLStreamException, FileNotFoundException
//    {
//        Collection errors = new ArrayList();
//        XMLStreamReader xsr = XMLInputFactory.newInstance().
//            createXMLStreamReader(new FileInputStream(new File(file)));
//        valXsr.init(xsr, null,
//            XmlBeans.typeLoaderForClassLoader(ValidatingXMLStreamReader.class.getClassLoader()),
//            null,
//            errors);
//
//        while( valXsr.hasNext() )
//        {
//            valXsr.next();
//        }
//
//        System.out.println("File '" + file + "' is: " + (valXsr.isValid() ? "Valid" : "INVALID") + "\t\t\t\t ----------");
//        for (Iterator i = errors.iterator(); i.hasNext(); )
//        {
//            XmlError err = (XmlError)i.next();
//            System.out.println("ERROR " + err.getSeverity() + " " + err.getLine() + ":" + err.getColumn() + " " +
//                err.getMessage() + " ");
//        }
//    }
//
//    private void debugEvent(int evType)
//    {
//        switch(evType)
//        {
//        case XMLEvent.START_ELEMENT:
//            System.out.println("SE     " + _elemEvent.getName());
//            break;
//        case XMLEvent.START_DOCUMENT:
//            System.out.println("SDoc");
//            break;
//        case XMLEvent.END_ELEMENT:
//            System.out.println("EE     " + _elemEvent.getName());
//            break;
//        case XMLEvent.END_DOCUMENT:
//            System.out.println("EDoc");
//            break;
//        case XMLEvent.SPACE:
//            System.out.println("SPACE");
//            break;
//        case XMLEvent.CDATA:
//            System.out.println("CDATA");
//            break;
//        case XMLEvent.CHARACTERS:
//            String c = _elemEvent.getText();
//            System.out.println("TEXT     " + c);
//            break;
//
//        case XMLEvent.ATTRIBUTE:      // global attributes
//            System.out.println("ATT     count: " + _elemEvent._xmlStream.getAttributeCount());
//            for(int i=0; i<_elemEvent._xmlStream.getAttributeCount(); i++)
//            {
//                System.out.println("\t\t" + _elemEvent._xmlStream.getAttributeNamespace(i) + ":" +
//                    _elemEvent._xmlStream.getAttributeLocalName(i) + "  =  " +
//                    _elemEvent._xmlStream.getAttributeValue(i));
//            }
//            break;
//        case XMLEvent.COMMENT:
//            System.out.println("COMMENT");
//            break;
//        case XMLEvent.DTD:
//            System.out.println("DTD");
//            break;
//        case XMLEvent.ENTITY_DECLARATION:
//            System.out.println("ENTITY_DECL");
//            break;
//        case XMLEvent.ENTITY_REFERENCE:
//            System.out.println("ENTITY_REF");
//            break;
//        case XMLEvent.NAMESPACE:
//            System.out.println("NS");
//            break;
//        case XMLEvent.NOTATION_DECLARATION:
//            System.out.println("NOTATION_DECL");
//            break;
//        case XMLEvent.PROCESSING_INSTRUCTION:
//            System.out.println("PI");
//            break;
//        }
//    }
}
