You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by "hua lei (JIRA)" <xe...@xml.apache.org> on 2006/06/25 19:50:32 UTC

[jira] Created: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Initial contribution for the SAXXMLStreamReader   
--------------------------------------------------

         Key: XERCESJ-1171
         URL: http://issues.apache.org/jira/browse/XERCESJ-1171
     Project: Xerces2-J
        Type: New Feature

  Components: StAX  
    Versions: 2.8.0    
 Environment: Windows XP Pro, SP2; Eclipse
    Reporter: hua lei


This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   

/*
 * Copyright 2006 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 
 */
package org.apache.xerces.stax;

import java.util.ArrayList;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;


import org.w3c.dom.Attr;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

/**
 * 
 * @author Hua Lei
 *
 */
public class SAXXMLStreamReader implements XMLStreamReader{
	
     //	The XMLInputFactory instance which creates the SAXXMLStreamReader
	 private XMLInputFactory xif;
	
	 // The Asynchronized SAX parser 
	 private AsyncSAXParser asp;
	 
	 // The SAX event handler which deals with parsed event
	 private SAXHandler handler;
	 
	 // The current event type
	 private int curType;
	 
	  // Record the index attribute and namespace for StartElement event
	 private ArrayList curAttrs;
	 private ArrayList curNamespaces;
	  
	 private Attributes attrs;
	
     /**
      * The construction method of SAXXMLStreamReader
      * 
      * @param is
      * @param xif
      */
	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
			throws XMLStreamException {

		  this.xif = xif;
		  this.curAttrs = new ArrayList();
		  this.curNamespaces = new ArrayList();
		  
		  try{
			asp = new AsyncSAXParser(xr, is, this);
			handler = new SAXHandler(asp);

			xr.setContentHandler(handler);
			xr.setDTDHandler(handler);
			xr.setEntityResolver(handler);
			xr.setErrorHandler(handler);
			asp.start();
			
			synchronized (asp) {
				while (asp.getRunningFlag() == true)
					asp.wait();

				asp.setRunningFlag(true);
				curType = asp.getCurType();
				asp.notify();
			}
		  }catch(Exception e){
			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
		  }
	 }
	 
	  /**
	   * Get the value of a feature/property from the underlying implementation
	   *
	   * @param name The name of the property, may not be null
	   * @return The value of the property
	   * @throws IllegalArgumentException if name is null
	   */
	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
		  if(name == null)
			  throw new IllegalArgumentException("The feature name should not be null");
		  return xif.getProperty(name);
	  }
	  
	  /**
	   * Returns true if there are more parsing events and false
	   * if there are no more events.  This method will return
	   * false if the current state of the XMLStreamReader is
	   * END_DOCUMENT
	   * 
	   * @return true if there are more events, false otherwise
	   * @throws XMLStreamException if there is a fatal error detecting the next state
	   */
	  public boolean hasNext() throws XMLStreamException{
		  
		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
			  return false;
		  return true;
	  }
	  
	  /**
	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
	   *
	   * @see javax.xml.stream.events.XMLEvent
	   * @return the integer code corresponding to the current parse event
	   * @throws NoSuchElementException if this is called when hasNext() returns false
	   * @throws XMLStreamException  if there is an error processing the underlying XML source
	   */
	  public  int next() throws XMLStreamException{	 
		  if(hasNext() == false){
			  throw new XMLStreamException("No such element!");
		  }
		  try{		
			  synchronized(asp){
			     while(asp.getRunningFlag() == true) asp.wait();
			    
			     asp.setRunningFlag(true);
			     curType = asp.getCurType();
			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
			    	 initialElementAttrs(asp.getElementName());
			     asp.notify();
			     return curType;
			  }
		  }catch(Exception e){
			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
		  }
	  }
	  
	  /**
    	* This method is to record attribute(not namespace) and namespace of
		* current element
		* 
	    */
	  private void initialElementAttrs(String eleName){
		  if(curType == XMLStreamConstants.START_ELEMENT){
			  curAttrs.clear();
			  curNamespaces.clear();
			  attrs = asp.getAttributes(eleName);
			  if(attrs != null){
				  for(int i = 0; i < attrs.getLength(); i++){
					
					  String name = attrs.getQName(i);
					  if(name.startsWith("xmlns")){
						  String value = attrs.getValue(i);
						  String prefix = "";
						  if(!name.equals("xmlns"))
							  prefix += name.substring(6);

						  curNamespaces.add(new Integer(i));
					  }
					  else
						  curAttrs.add(new Integer(i));
				  }
			  }

		  }
	  }
	  
	  /**
	   * Test if the current event is of the given type and if the namespace and name match the current
	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
	   * if the localName is null it is not checked for equality.
	   * @param type the event type
	   * @param namespaceURI the uri of the event, may be null
	   * @param localName the localName of the event, may be null
	   * @throws XMLStreamException if the required values are not matched.
	   */
	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
		    // Need to be realized
	  }
	  

	  /**
	   * Reads the content of a text-only element, an exception is thrown if this is
	   * not a text-only element.
	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
	   
	   * <br /> Precondition: the current event is START_ELEMENT.
	   * <br /> 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{
		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
			throw new XMLStreamException(
					"parser must be on START_ELEMENT to read next text",
					getLocation());
		}
		int eventType = next();
		StringBuffer buf = new StringBuffer();
		while (eventType != XMLStreamConstants.END_ELEMENT) {
			if (eventType == XMLStreamConstants.CHARACTERS
					|| eventType == XMLStreamConstants.CDATA
					|| eventType == XMLStreamConstants.SPACE
					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
				buf.append(getText());
			} 
			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
					|| eventType == XMLStreamConstants.COMMENT) {
				// skipping
			} 
			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
				throw new XMLStreamException(
						"unexpected end of document when reading element text content", getLocation());
			} 
			else if (eventType == XMLStreamConstants.START_ELEMENT) {
				throw new XMLStreamException(
						"element text content may not contain START_ELEMENT",
						getLocation());
			} 
			else {
				throw new XMLStreamException("Unexpected event type "
						+ eventType, getLocation());
			}
			eventType = next();
		}
		return buf.toString();
	  }

	  /**
	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
	   * or PROCESSING_INSTRUCTION,
	   * until a START_ELEMENT or END_ELEMENT is reached.
	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
	   * are encountered, an exception is thrown. 
	   * return eventType;
	   * </pre>
	   *
	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
	   * START_ELEMENT or END_ELEMENT
	   * @throws NoSuchElementException if this is called when hasNext() returns false
	   */
	  public int nextTag() throws XMLStreamException{
		int eventType = next();
		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
				// skip whitespace
				|| eventType == XMLStreamConstants.SPACE
				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
				|| eventType == XMLStreamConstants.COMMENT) {
			eventType = next();
		}
		if (eventType != XMLStreamConstants.START_ELEMENT
				&& eventType != XMLStreamConstants.END_ELEMENT) {
			throw new XMLStreamException("expected start or end tag",
					getLocation());
		}
		return eventType;
	  }
	  
	  /**
	   * Frees any resources associated with this Reader.  This method does not close the
	   * underlying input source.
	   * 
	   * @throws XMLStreamException if there are errors freeing associated resources
	   */
	  public void close() throws XMLStreamException{
          // As for SAXSource, this method needs to close the underlying bytestream
	  }

	  /**
	   * Return the uri for the given prefix.
	   * The uri returned depends on the current state of the processor.
	   *
	   *
	   * @param prefix The prefix to lookup, may not be null
	   * @return the uri bound to the given prefix or null if it is not bound
	   * @throws IllegalArgumentException if the prefix is null
	   */
	  public String getNamespaceURI(String prefix){
		  // Need to be realized. For SAXSource, a Namespace context structure should 
		  // be constructed becuase it has no tree structure like DOMSource
		  return null;
	  }

	  /**
	   * Returns true if the cursor points to a start tag (otherwise false)
	   * @return true if the cursor points to a start tag, false otherwise
	   */
	  public boolean isStartElement(){  
		  return curType == XMLStreamConstants.START_ELEMENT;
	  }

	  /**
	   * Returns true if the cursor points to an end tag (otherwise false)
	   * @return true if the cursor points to an end tag, false otherwise
	   */
	  public boolean isEndElement(){
		  return curType == XMLStreamConstants.END_ELEMENT;
	  }

	  /**
	   * Returns true if the cursor points to a character data event
	   * @return true if the cursor points to character data, false otherwise
	   */
	  public boolean isCharacters(){
		  return curType == XMLStreamConstants.CHARACTERS;
	  }

	  /**
	   * Returns true if the cursor points to a character data event
	   * that consists of all whitespace
	   * 
	   * @return true if the cursor points to all whitespace, false otherwise
	   */
	  public boolean isWhiteSpace(){
		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
			 char[] data = asp.getCharacters();
			 if(data != null){
				  for(int i = 0; i < data.length; i++){
					  char c = data[i];
					  // The white space is tab, enter, and blank
					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
					  return false;
				  }
				  return true;
			  }
		  }
		  return false;
	  }


	  /**
	   * Returns the normalized attribute value of the
	   * attribute with the namespace and localName
	   * If the namespaceURI is null the namespace
	   * is not checked for equality
	   * 
	   * @param namespaceURI the namespace of the attribute
	   * @param localName the local name of the attribute, cannot be null
	   * @return returns the value of the attribute , returns null if not found
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributeValue(String namespaceURI,
	                                  String localName){
		  if(curType == XMLStreamConstants.START_ELEMENT){
			  String value = attrs.getValue(namespaceURI, localName);
			  return value;
		  }
		  
		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
	  }

	  /**
	   * Returns the count of attributes on this START_ELEMENT,
	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
	   * For SAXSource, there is no explict Attribute event
	   * 
	   * @return returns the number of attributes
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public int getAttributeCount(){
	    if (curType == XMLStreamConstants.START_ELEMENT) {
			return curAttrs.size();
		}

		throw new IllegalStateException(
				"Current event is not START_ELEMENT or ATTRIBUTE");
	  }

	  /**
		 * Returns the qname of the attribute at the provided index This method
		 * excludes namespace definitions
		 * 
		 * @param index
		 *            the position of the attribute
		 * @return the QName of the attribute
		 * @throws IllegalStateException
		 *             if this is not a START_ELEMENT or ATTRIBUTE
		 */
	  public QName getAttributeName(int index){

		  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
          
            String name =  attrs.getQName(index);
 		    String uri = attrs.getURI(index);
 		    return new QName(uri, name);
		  }

		  throw new IllegalStateException(
	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
		  
	  }
	  
	  /**
	   * Returns the namespace of the attribute at the provided
	   * index
	   * @param index the position of the attribute
	   * @return the namespace URI (can be null)
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributeNamespace(int index){
		  if (curType == XMLStreamConstants.START_ELEMENT) {
	            int leng = getAttributeCount();
	            if(index + 1 > leng || index < 0)
	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
	          
	            String namespaceURI = attrs.getURI(index);     	
	           	return namespaceURI;
			  }
			
			  throw new IllegalStateException(
					"Current event is not START_ELEMENT or ATTRIBUTE");		
	  }

	  /**
	   * Returns the localName of the attribute at the provided
	   * index
	   * @param index the position of the attribute
	   * @return the localName of the attribute
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributeLocalName(int index){
		  return null;
	  }

	  /**
	   * Returns the prefix of this attribute at the
	   * provided index
	   * @param index the position of the attribute
	   * @return the prefix of the attribute
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributePrefix(int index){
          return null;
	  }

	  /**
	   * Returns the XML type of the attribute at the provided
	   * index
	   * @param index the position of the attribute
	   * @return the XML type of the attribute
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributeType(int index){
           return null;
	  }

	  /**
	   * Returns the value of the attribute at the
	   * index
	   * @param index the position of the attribute
	   * @return the attribute value
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public String getAttributeValue(int index){
          return null;
	  }
	  

	  /**
	   * Returns a boolean which indicates if this
	   * attribute was created by default
	   * @param index the position of the attribute
	   * @return true if this is a default attribute
	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
	   */
	  public boolean isAttributeSpecified(int index){
		  return false;
	  }

	  /**
	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
	   * On an END_ELEMENT the count is of the namespaces that are about to go
	   * out of scope.  This is the equivalent of the information reported
	   * by SAX callback for an end element event.
	   * @return returns the number of namespace declarations on this specific element
	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
	   */
	  public int getNamespaceCount(){

		  return 0;
	  }

	  /**
	   * Returns the prefix for the namespace declared at the
	   * index.  Returns null if this is the default namespace
	   * declaration
	   *
	   * @param index the position of the namespace declaration
	   * @return returns the namespace prefix
	   * @throws IllegalStateException if this is not a START_ELEMENT,
	   *    END_ELEMENT or NAMESPACE
	   */
	  public String getNamespacePrefix(int index){
		  return null;
	  }
	  
	  /**
	   * Returns the uri for the namespace declared at the
	   * index.
	   *
	   * @param index the position of the namespace declaration
	   * @return returns the namespace uri
	   * @throws IllegalStateException if this is not a START_ELEMENT,
	   *   END_ELEMENT or NAMESPACE
	   */
	  public String getNamespaceURI(int index){
		  return null;	
	  }

	  /**
	   * Returns a read only namespace context for the current
	   * position.  The context is transient and only valid until
	   * a call to next() changes the state of the reader.
	   *
	   * @return return a namespace context
	   */
	  public NamespaceContext getNamespaceContext(){
		  return null;
	  }

	  /**
	   * Returns an integer code that indicates the type
	   * of the event the cursor is pointing to.
	   */
	  public int getEventType(){
		  return asp.getCurType();
	  }

	  /**
	   * Returns the current value of the parse event as a string,
	   * this returns the string value of a CHARACTERS event,
	   * returns the value of a COMMENT, the replacement value
	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
	   * the string value for a SPACE event,
	   * or the String value of the internal subset of the DTD.
	   * If an ENTITY_REFERENCE has been resolved, any character data
	   * will be reported as CHARACTERS events.
	   * 
	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
	   * will map to StAX character events. 
	   * 
	   * @return the current text or null
	   * @throws java.lang.IllegalStateException if this state is not
	   * a valid text state.
	   */
	  public String getText(){
		 return null;
	  }

	  /**
	   * Returns an array which contains the characters from this event.
	   * This array should be treated as read-only and transient. I.e. the array will
	   * contain the text characters until the XMLStreamReader moves on to the next event.
	   * Attempts to hold onto the character array beyond that time or modify the
	   * contents of the array are breaches of the contract for this interface.
	   * 
	   * @return the current text or an empty array
	   * @throws java.lang.IllegalStateException if this state is not
	   * a valid text state.
	   */
	  public char[] getTextCharacters(){
		  String text = getText();
		  return text.toCharArray();
	  }

	  /**
	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
	   *
	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
	   *
	   * @param sourceStart the index of the first character in the source array to copy
	   * @param target the destination array
	   * @param targetStart the start offset in the target array
	   * @param length the number of characters to copy
	   * @return the number of characters actually copied
	   * @throws XMLStreamException if the underlying XML source is not well-formed
	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
	   * @throws UnsupportedOperationException if this method is not supported 
	   * @throws NullPointerException is if target is null
	   */
	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
	     throws XMLStreamException{
	      
	        if(target == null)
	        	throw new NullPointerException();

	        int targetLen = target.length;
	        
	        if (targetStart < 0 || targetStart > targetLen)
	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
	        
	        
	        if(length < 0)
	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
	        	
	        int len = getTextLength();
	        if (sourceStart < 0 || sourceStart > len) {
	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
	        }

	       
	        int avail = len - sourceStart;

	        if (avail < length) {
	            length = avail;
	        }

	       
	        char[] intBuf = getTextCharacters();
	        int intStart = getTextStart();
	        System.arraycopy(intBuf, intStart + sourceStart,
	                             target, targetStart, length);
	        return length;
	   }

	  /**
	   * Returns the offset into the text character array where the first
	   * character (of this text event) is stored.
	   * @throws java.lang.IllegalStateException if this state is not
	   * a valid text state.
	   */
	  public int getTextStart(){
		   return 0;
	   }

	  /**
	   * Returns the length of the sequence of characters for this
	   * Text event within the text character array.
	   * @throws java.lang.IllegalStateException if this state is not
	   * a valid text state.
	   */
	  public int getTextLength(){
		  String text = getText();
		  return text.length();
	   }

	  /**
	   * Return input encoding if known or null if unknown.
	   * @return the encoding of this instance or null
	   */
	  public String getEncoding(){
		   return null;
	   }

	  /**
	   * Return true if the current event has text, false otherwise
	   * The following events have text:
	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
	   */
	  public boolean hasText(){
		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
			  return true;
		  else
			  return false;
	   }

	  /**
	   * Return the current location of the processor.
	   * If the Location is unknown the processor should return
	   * an implementation of Location that returns -1 for the
	   * location and null for the publicId and systemId.
	   * The location information is only valid until next() is
	   * called.
	   */
	  public Location getLocation(){
		  return null;
	  }

	  /**
	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
	   *
	   * 
	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
	   * @throws IllegalStateException if this is not a START_ELEMENT or
	   * END_ELEMENT
	   */
	  public QName getName(){

		  return null;
	  }

	  /**
	   * Returns the (local) name of the current event.
	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
	   * For ENTITY_REFERENCE it returns entity name.
	   * The current event must be START_ELEMENT or END_ELEMENT, 
	   * or ENTITY_REFERENCE
	   * @return the localName
	   * @throws IllegalStateException if this not a START_ELEMENT,
	   * END_ELEMENT or ENTITY_REFERENCE
	   */
	  public String getLocalName(){
		 
			  return null;
	  }

	  /**
	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
	   * returns false otherwise
	   */
	  public boolean hasName(){
		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
		     return true;
		  else 
			 return false;
	  }

	  /**
	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
	   * returns the URI of the current element (URI mapping to the prefix
	   * element/attribute has, if any; or if no prefix, null for attribute,
	   * and the default namespace URI for the element).
	   *
	   * @return the URI bound to this elements prefix, the default namespace, or null
	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
	   *    or ATTRIBUTE
	   */
	  public String getNamespaceURI(){
		
			  return null;
	  }

	  /**
	   * Returns the prefix of the current event or null if the event does not
	   * have a prefix
	   * @return the prefix or null
	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
	   */
	  public String getPrefix(){

		  return null;
	  }
	  
	  /**
	   * Get the xml version declared on the xml declaration
	   * Returns null if none was declared
	   * @return the XML version or null
	   */
	  public String getVersion(){
		  return null;
	  }

	  /**
	   * Get the standalone declaration from the xml declaration, if one found
	   * ({@link #standaloneSet} returns true if one was specified).
	   *
	   * @return true if this is standalone, or false otherwise
	   */
	  public boolean isStandalone(){
		  return false;
	  }

	  /**
	   * Checks if standalone was set in the document
	   * Since we only have DOMSource, the standaloneSet information is hard to 
	   * get. Because the default standalone is false, if the standalone is true
	   * then it was set.
	   * 
	   * @return true if standalone was set in the document, or false otherwise
	   */
	  public boolean standaloneSet(){
	
		  return true;
	  }

	  /**
	   * Returns the character encoding declared on the xml declaration
	   * Returns null if none was declared
	   * @return the encoding declared in the document or null
	   */
	  public String getCharacterEncodingScheme(){
		  return null;
	  }

	  /**
	   * Get the target of a processing instruction
	   * @return the target
	   * @throws IllegalStateException if the current event is not a
	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
	   */
	  public String getPITarget() {
          return null;
	  }

	  /**
	   * Get the data section of a processing instruction
	   * @return the data (if processing instruction has any), or null
	   *    if the processing instruction only has target.
	   * @throws IllegalStateException if the current event is not a
	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
	   */
	  public String getPIData(){
	     return null;
	  }
	 
}

/*
 * Copyright 2006 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 
 */

package org.apache.xerces.stax;

import java.util.HashMap;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.Attributes;

/**
 * 
 * @author Hua Lei
 *
 */
public class AsyncSAXParser extends Thread{
	private XMLReader xr;
	private InputSource is;
	
	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
	private SAXXMLStreamReader reader;
	
	// The flag which represents the status of AsyncSAXParser. If true,
	// the SAXParser is executing parsing work
	private boolean runningFlag;
	
	// The current event type
	private int curType;
	
	// The buffer which records the Characters and Space
	private char[] charactersBuf;
	
	// The current attributes of start element. The key is element name, and the 
	// value is its attributes
	private HashMap attrsMap;
	
	// The current element name
	private String eleName;
	
    public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
        this.xr = xr;
		this.is = is;
		this.reader = reader;
        this.runningFlag = true;     
        attrsMap = new HashMap();
    }
    /**
     * The thread begins to parse XML source. 
     */
    public void run(){
    	try{
    	   xr.parse(is);
    	}catch(Exception e){
    	  System.out.print("Error occurs during the SAX parsing process at ");
    	  e.printStackTrace();
    	}
    }  
    
    /**
     * Set the current event type
     * This method is used by SAXHandler
     * 
     * @param cur
     */
    public synchronized void setCurType(int cur){
    	this.curType = cur;
    }
    
    /**
     * Get the current event type
     * This method is used by SAXXMLStreamReader
     * 
     * @return
     */
    public synchronized int getCurType(){
    	return curType;
    }
    
    /**
     * Set the status of SAXParser
     * 
     * @param flag
     */
    public synchronized void setRunningFlag(boolean flag){
    	runningFlag = flag;
		    
    }
    
    /**
     * Get the status of SAXParser
     * 
     * @return
     */
    public synchronized boolean getRunningFlag(){
        return runningFlag;
    }
    
    /**
     * Set the characters buffer for characters event
     * 
     * @param ch
     * @param start
     * @param length
     */
    public void setCharacters(char[] ch, int start, int length){
    	charactersBuf = null;
    	charactersBuf = new char[length];
    	for(int i = 0; i < length; i++, start++)
    		charactersBuf[i] = ch[start]; 
    }
    
    /**
     * Get the current characters buffer
     * 
     * @return
     */
    public char[] getCharacters(){
    	return charactersBuf;
    }
   
    /**
     * Set the attributes for Start element
     * 
     * @param attrs
     */
    public void setAttributes(Attributes attrs, String eleName){
    	attrsMap.put(eleName, attrs);
    }
    
    /**
     * Get the current attributes
     * 
     * @return
     */
    public Attributes getAttributes(String eleName){
    	return (Attributes)attrsMap.get(eleName);
    }
    
    /**
     * Set the element name for startElement and endElement event
     * 
     * @param attrs
     */
    public void setElementName(String eleName){
    	this.eleName = eleName;
    }
    
    /**
     * Get the element name for startElement and endElement event
     * 
     * @return
     */
    public String getElementName(){
    	return eleName;
    }
}


/*
 * Copyright 2006 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 
 */

package org.apache.xerces.stax;


import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;

/**
 * 
 * @author Hua Lei
 *
 */
public class SAXHandler extends DefaultHandler{
      
      private AsyncSAXParser asp;
      
      public SAXHandler(AsyncSAXParser asp){
    	  this.asp = asp;
      }
      
      public void characters(char[] ch, int start, int length){
    	  try{
    	    synchronized (asp) {
				while (asp.getRunningFlag() == false)
					asp.wait();
				asp.setCurType(XMLStreamConstants.CHARACTERS);
				asp.setRunningFlag(false);
				asp.setCharacters(ch, start, length);
				asp.notify();
			}
    	  }catch(Exception e){
		  }
      }
       
      public void endDocument(){
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
  				asp.setRunningFlag(false);
  				asp.notify();
  			}
      	  }catch(Exception e){
  		  }
      }
       
      public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
    	  try{
        	    synchronized (asp) {
    				while (asp.getRunningFlag() == false)
    					asp.wait();
    				asp.setCurType(XMLStreamConstants.END_ELEMENT);
    				asp.setRunningFlag(false);
    				asp.setElementName(qName);
    				asp.notify();
    			}
          }catch(Exception e){}
      }
       
      public synchronized void ignorableWhitespace(char[] ch, int start, int length){
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.SPACE);
  				asp.setRunningFlag(false);
  				asp.setCharacters(ch, start, length);
  				asp.notify();
  			}
        }catch(Exception e){}
      }
       
      public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
  				asp.setRunningFlag(false);
  				asp.notify();
  			}
        }catch(Exception e){}
      }
       
      public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
    	  
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
  				asp.setRunningFlag(false);
  				asp.notify();
  			}
        }catch(Exception e){}
      }
       
      public synchronized void startDocument(){
    	 
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
  				asp.setRunningFlag(false);
  				asp.notify();
  			}
        }catch(Exception e){}
      }
       
      public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.START_ELEMENT);
  				asp.setRunningFlag(false);
  				asp.setAttributes(attributes, qName);
  				asp.setElementName(qName);
  				asp.notify();
  			}
        }catch(Exception e){}
      }

       
      public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
    	  System.out.println("ENTITY_DECLARATION");
    	  try{
      	    synchronized (asp) {
  				while (asp.getRunningFlag() == false)
  					asp.wait();
  				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
  				asp.setRunningFlag(false);
  				asp.notify();
  			}
        }catch(Exception e){}
      }
      
      // Need to be realized
      /*
      public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
    	  System.out.println("startPrefixMapping");
    	  asp.setRunningFlag(false);
      }
      
      public synchronized void endPrefixMapping(java.lang.String prefix){
    	  System.out.println("endPrefixMapping");
    	  asp.setRunningFlag(false);
      }
      
      public synchronized void skippedEntity(java.lang.String name){
    	  System.out.println("skippedEntity");
    	  asp.setRunningFlag(false);
      }
       */
       
}



-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Updated: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "hua lei (JIRA)" <xe...@xml.apache.org>.
     [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=all ]

hua lei updated XERCESJ-1171:
-----------------------------

    Attachment: StAX_SAX_7.17.zip

This file is zip format. 

> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>                 Key: XERCESJ-1171
>                 URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: StAX
>    Affects Versions: 2.8.0
>         Environment: Windows XP Pro, SP2; Eclipse
>            Reporter: hua lei
>         Assigned To: Michael Glavassevich
>         Attachments: StAX_SAX_7.17.rar, StAX_SAX_7.17.zip, xerces_stax.zip
>
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Assigned: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "Michael Glavassevich (JIRA)" <xe...@xml.apache.org>.
     [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=all ]

Michael Glavassevich reassigned XERCESJ-1171:
---------------------------------------------

    Assignee: Michael Glavassevich

> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>                 Key: XERCESJ-1171
>                 URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: StAX
>    Affects Versions: 2.8.0
>         Environment: Windows XP Pro, SP2; Eclipse
>            Reporter: hua lei
>         Assigned To: Michael Glavassevich
>         Attachments: xerces_stax.zip
>
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Updated: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "hua lei (JIRA)" <xe...@xml.apache.org>.
     [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=all ]

hua lei updated XERCESJ-1171:
-----------------------------

    Attachment: StAX_SAX_7.17.rar

The  class SAXXMLStreamReaderImpl is  updated as followed:

0)  Method "public SAXXMLStreamReaderImpl(XMLReader xr, InputSource is, XMLInputFactory xif) " is updated because the SAX Parser location information is added.  
1)  Method "public String getAttributeValue(String namespaceURI, String localName) " is updated
2)  Namespace related methods "public int getNamespaceCount(); public String getNamespacePrefix(int index); public String getNamespaceURI(int index)" are realized
3)  Method "public String getText()" are realized.  
4)  Method "public String getEncoding()" are realized.
5)  Element related methods "public QName getName() ;public String getLocalName();  public String getNamespaceURI(); public String getPrefix()" are realized.
6)  Method "public Location getLocation()" is realized. The SAXLocation is added to record the location information 

The class NamespaceContextImpl is updated as followed: 
1)  An ArrayList  "eleNamespaces" is added for SAXSource
2)  Methods "protected ArrayList getNamespaces(); protected String getNamespacePrefix(int index);protected String getNamespaceURI(int index)" are added.
3)  Method "public void onStartElement()" is updated
4) The inline class "DOMNamespace" is renamed as "Namespace", because it's not only used for DOMSource. 

The class SAXLocation is added.

The class StAXSAXHandler is updated as followed:
1)   An attribute "private Locator loc" is added
2)  The initialization method and method "  public synchronized void startDocument()"  are updated.



> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>                 Key: XERCESJ-1171
>                 URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: StAX
>    Affects Versions: 2.8.0
>         Environment: Windows XP Pro, SP2; Eclipse
>            Reporter: hua lei
>         Assigned To: Michael Glavassevich
>         Attachments: StAX_SAX_7.17.rar, xerces_stax.zip
>
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Updated: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "hua lei (JIRA)" <xe...@xml.apache.org>.
     [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=all ]

hua lei updated XERCESJ-1171:
-----------------------------

    Attachment: xerces_stax.zip

This is a much improved version for StAX component of xerces. Compared to initial version, many bugs are found and fixed. For example, Attributes.getQName(index) will get the node name of SAX attribute node, however,  the SAX is a stream-based parsing mechanism. So you can't use an Attributes object to get node name at certain index repeatly. Now the following work are undergoing:

1) The namespace and text related methods of SAX converter API 
2) After 1), the main function of SAX and DOM converters will be finished, the codes will be carefully reviewed and some small features will be added.  
3) More test cases will be carried out


> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>          Key: XERCESJ-1171
>          URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>      Project: Xerces2-J
>         Type: New Feature

>   Components: StAX
>     Versions: 2.8.0
>  Environment: Windows XP Pro, SP2; Eclipse
>     Reporter: hua lei
>  Attachments: xerces_stax.zip
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Resolved: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "Michael Glavassevich (JIRA)" <xe...@xml.apache.org>.
     [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=all ]

Michael Glavassevich resolved XERCESJ-1171.
-------------------------------------------

    Resolution: Fixed

Thanks Hua. Just got the SAX XMLStreamReader into SVN over the weekend. It was a bit confusing because you also included the DOM code in the zip (a different version than what you posted on XERCESJ-1170). I tried merging that with the code I previously committed but might have missed something. Please take a look it.  I also renamed some of the classes to make them more descriptive (SAXXMLStreamReader -> SAXXMLStreamReaderImpl, SAXHandler -> StAXSAXHandler and DOMLocation -> EmptyLocation).

> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>                 Key: XERCESJ-1171
>                 URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: StAX
>    Affects Versions: 2.8.0
>         Environment: Windows XP Pro, SP2; Eclipse
>            Reporter: hua lei
>         Assigned To: Michael Glavassevich
>         Attachments: xerces_stax.zip
>
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org


[jira] Commented: (XERCESJ-1171) Initial contribution for the SAXXMLStreamReader

Posted by "Michael Glavassevich (JIRA)" <xe...@xml.apache.org>.
    [ http://issues.apache.org/jira/browse/XERCESJ-1171?page=comments#action_12424425 ] 
            
Michael Glavassevich commented on XERCESJ-1171:
-----------------------------------------------

Thanks Hua. I've committed your updates to SVN. I made a minor fix to SAXXMLStreamReader so that it returns the local name from getLocalName() instead of throwing an exception when the state is END_ELEMENT and updated SAXLocation so that it returns the system ID and public ID from the SAX locator instead of null.

> Initial contribution for the SAXXMLStreamReader
> -----------------------------------------------
>
>                 Key: XERCESJ-1171
>                 URL: http://issues.apache.org/jira/browse/XERCESJ-1171
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: StAX
>    Affects Versions: 2.8.0
>         Environment: Windows XP Pro, SP2; Eclipse
>            Reporter: hua lei
>         Assigned To: Michael Glavassevich
>         Attachments: StAX_SAX_7.17.rar, StAX_SAX_7.17.zip, xerces_stax.zip
>
>
> This is an initial version for SAXXMLStreamReader. The function of SAXXMLStreamReader is to visit the SAXSource through XMLStreamReader interface. To improve the performance, the SAXXMLStreamReader thread is coordinated with SAXSource thread. The SAXXMLStreamReader will control the parsing process by next() method.  In the following code, the threads synchronization has been realized, and some interfaces in SAXXMLStreamReader is to be realized.   
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.ArrayList;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.namespace.QName;
> import javax.xml.stream.Location;
> import javax.xml.stream.XMLInputFactory;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import javax.xml.stream.XMLStreamReader;
> import org.w3c.dom.Attr;
> import org.xml.sax.Attributes;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXXMLStreamReader implements XMLStreamReader{
> 	
>      //	The XMLInputFactory instance which creates the SAXXMLStreamReader
> 	 private XMLInputFactory xif;
> 	
> 	 // The Asynchronized SAX parser 
> 	 private AsyncSAXParser asp;
> 	 
> 	 // The SAX event handler which deals with parsed event
> 	 private SAXHandler handler;
> 	 
> 	 // The current event type
> 	 private int curType;
> 	 
> 	  // Record the index attribute and namespace for StartElement event
> 	 private ArrayList curAttrs;
> 	 private ArrayList curNamespaces;
> 	  
> 	 private Attributes attrs;
> 	
>      /**
>       * The construction method of SAXXMLStreamReader
>       * 
>       * @param is
>       * @param xif
>       */
> 	 public SAXXMLStreamReader(XMLReader xr, InputSource is, XMLInputFactory xif)
> 			throws XMLStreamException {
> 		  this.xif = xif;
> 		  this.curAttrs = new ArrayList();
> 		  this.curNamespaces = new ArrayList();
> 		  
> 		  try{
> 			asp = new AsyncSAXParser(xr, is, this);
> 			handler = new SAXHandler(asp);
> 			xr.setContentHandler(handler);
> 			xr.setDTDHandler(handler);
> 			xr.setEntityResolver(handler);
> 			xr.setErrorHandler(handler);
> 			asp.start();
> 			
> 			synchronized (asp) {
> 				while (asp.getRunningFlag() == true)
> 					asp.wait();
> 				asp.setRunningFlag(true);
> 				curType = asp.getCurType();
> 				asp.notify();
> 			}
> 		  }catch(Exception e){
> 			 throw new XMLStreamException("Error occurs during the SAX parsing process", e);  
> 		  }
> 	 }
> 	 
> 	  /**
> 	   * Get the value of a feature/property from the underlying implementation
> 	   *
> 	   * @param name The name of the property, may not be null
> 	   * @return The value of the property
> 	   * @throws IllegalArgumentException if name is null
> 	   */
> 	  public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException{
> 		  if(name == null)
> 			  throw new IllegalArgumentException("The feature name should not be null");
> 		  return xif.getProperty(name);
> 	  }
> 	  
> 	  /**
> 	   * Returns true if there are more parsing events and false
> 	   * if there are no more events.  This method will return
> 	   * false if the current state of the XMLStreamReader is
> 	   * END_DOCUMENT
> 	   * 
> 	   * @return true if there are more events, false otherwise
> 	   * @throws XMLStreamException if there is a fatal error detecting the next state
> 	   */
> 	  public boolean hasNext() throws XMLStreamException{
> 		  
> 		  if(asp.getCurType() == XMLStreamConstants.END_DOCUMENT)
> 			  return false;
> 		  return true;
> 	  }
> 	  
> 	  /**
> 	   * This method will throw an IllegalStateException if it is called after hasNext() returns false.
> 	   *
> 	   * @see javax.xml.stream.events.XMLEvent
> 	   * @return the integer code corresponding to the current parse event
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   * @throws XMLStreamException  if there is an error processing the underlying XML source
> 	   */
> 	  public  int next() throws XMLStreamException{	 
> 		  if(hasNext() == false){
> 			  throw new XMLStreamException("No such element!");
> 		  }
> 		  try{		
> 			  synchronized(asp){
> 			     while(asp.getRunningFlag() == true) asp.wait();
> 			    
> 			     asp.setRunningFlag(true);
> 			     curType = asp.getCurType();
> 			     if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 			    	 initialElementAttrs(asp.getElementName());
> 			     asp.notify();
> 			     return curType;
> 			  }
> 		  }catch(Exception e){
> 			  throw new XMLStreamException("Error occurs when processing SAXSource", e);
> 		  }
> 	  }
> 	  
> 	  /**
>     	* This method is to record attribute(not namespace) and namespace of
> 		* current element
> 		* 
> 	    */
> 	  private void initialElementAttrs(String eleName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  curAttrs.clear();
> 			  curNamespaces.clear();
> 			  attrs = asp.getAttributes(eleName);
> 			  if(attrs != null){
> 				  for(int i = 0; i < attrs.getLength(); i++){
> 					
> 					  String name = attrs.getQName(i);
> 					  if(name.startsWith("xmlns")){
> 						  String value = attrs.getValue(i);
> 						  String prefix = "";
> 						  if(!name.equals("xmlns"))
> 							  prefix += name.substring(6);
> 						  curNamespaces.add(new Integer(i));
> 					  }
> 					  else
> 						  curAttrs.add(new Integer(i));
> 				  }
> 			  }
> 		  }
> 	  }
> 	  
> 	  /**
> 	   * Test if the current event is of the given type and if the namespace and name match the current
> 	   * namespace and name of the current event.  If the namespaceURI is null it is not checked for equality,
> 	   * if the localName is null it is not checked for equality.
> 	   * @param type the event type
> 	   * @param namespaceURI the uri of the event, may be null
> 	   * @param localName the localName of the event, may be null
> 	   * @throws XMLStreamException if the required values are not matched.
> 	   */
> 	  public void require(int type, String namespaceURI, String localName) throws XMLStreamException{
> 		    // Need to be realized
> 	  }
> 	  
> 	  /**
> 	   * Reads the content of a text-only element, an exception is thrown if this is
> 	   * not a text-only element.
> 	   * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content.
> 	   
> 	   * <br /> Precondition: the current event is START_ELEMENT.
> 	   * <br /> 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{
> 		if (getEventType() != XMLStreamConstants.START_ELEMENT) {
> 			throw new XMLStreamException(
> 					"parser must be on START_ELEMENT to read next text",
> 					getLocation());
> 		}
> 		int eventType = next();
> 		StringBuffer buf = new StringBuffer();
> 		while (eventType != XMLStreamConstants.END_ELEMENT) {
> 			if (eventType == XMLStreamConstants.CHARACTERS
> 					|| eventType == XMLStreamConstants.CDATA
> 					|| eventType == XMLStreamConstants.SPACE
> 					|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
> 				buf.append(getText());
> 			} 
> 			else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 					|| eventType == XMLStreamConstants.COMMENT) {
> 				// skipping
> 			} 
> 			else if (eventType == XMLStreamConstants.END_DOCUMENT) {
> 				throw new XMLStreamException(
> 						"unexpected end of document when reading element text content", getLocation());
> 			} 
> 			else if (eventType == XMLStreamConstants.START_ELEMENT) {
> 				throw new XMLStreamException(
> 						"element text content may not contain START_ELEMENT",
> 						getLocation());
> 			} 
> 			else {
> 				throw new XMLStreamException("Unexpected event type "
> 						+ eventType, getLocation());
> 			}
> 			eventType = next();
> 		}
> 		return buf.toString();
> 	  }
> 	  /**
> 	   * Skips any white space (isWhiteSpace() returns true), COMMENT,
> 	   * or PROCESSING_INSTRUCTION,
> 	   * until a START_ELEMENT or END_ELEMENT is reached.
> 	   * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
> 	   * are encountered, an exception is thrown. 
> 	   * return eventType;
> 	   * </pre>
> 	   *
> 	   * @return the event type of the element read (START_ELEMENT or END_ELEMENT)
> 	   * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION,
> 	   * START_ELEMENT or END_ELEMENT
> 	   * @throws NoSuchElementException if this is called when hasNext() returns false
> 	   */
> 	  public int nextTag() throws XMLStreamException{
> 		int eventType = next();
> 		while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip																		// //																			// whitespace
> 				|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
> 				// skip whitespace
> 				|| eventType == XMLStreamConstants.SPACE
> 				|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
> 				|| eventType == XMLStreamConstants.COMMENT) {
> 			eventType = next();
> 		}
> 		if (eventType != XMLStreamConstants.START_ELEMENT
> 				&& eventType != XMLStreamConstants.END_ELEMENT) {
> 			throw new XMLStreamException("expected start or end tag",
> 					getLocation());
> 		}
> 		return eventType;
> 	  }
> 	  
> 	  /**
> 	   * Frees any resources associated with this Reader.  This method does not close the
> 	   * underlying input source.
> 	   * 
> 	   * @throws XMLStreamException if there are errors freeing associated resources
> 	   */
> 	  public void close() throws XMLStreamException{
>           // As for SAXSource, this method needs to close the underlying bytestream
> 	  }
> 	  /**
> 	   * Return the uri for the given prefix.
> 	   * The uri returned depends on the current state of the processor.
> 	   *
> 	   *
> 	   * @param prefix The prefix to lookup, may not be null
> 	   * @return the uri bound to the given prefix or null if it is not bound
> 	   * @throws IllegalArgumentException if the prefix is null
> 	   */
> 	  public String getNamespaceURI(String prefix){
> 		  // Need to be realized. For SAXSource, a Namespace context structure should 
> 		  // be constructed becuase it has no tree structure like DOMSource
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a start tag (otherwise false)
> 	   * @return true if the cursor points to a start tag, false otherwise
> 	   */
> 	  public boolean isStartElement(){  
> 		  return curType == XMLStreamConstants.START_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to an end tag (otherwise false)
> 	   * @return true if the cursor points to an end tag, false otherwise
> 	   */
> 	  public boolean isEndElement(){
> 		  return curType == XMLStreamConstants.END_ELEMENT;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * @return true if the cursor points to character data, false otherwise
> 	   */
> 	  public boolean isCharacters(){
> 		  return curType == XMLStreamConstants.CHARACTERS;
> 	  }
> 	  /**
> 	   * Returns true if the cursor points to a character data event
> 	   * that consists of all whitespace
> 	   * 
> 	   * @return true if the cursor points to all whitespace, false otherwise
> 	   */
> 	  public boolean isWhiteSpace(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.SPACE){
> 			 char[] data = asp.getCharacters();
> 			 if(data != null){
> 				  for(int i = 0; i < data.length; i++){
> 					  char c = data[i];
> 					  // The white space is tab, enter, and blank
> 					  // by http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
> 					  if(c == '\t' || c == '\n' || c == ' ' || c == '\r') continue;
> 					  return false;
> 				  }
> 				  return true;
> 			  }
> 		  }
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the normalized attribute value of the
> 	   * attribute with the namespace and localName
> 	   * If the namespaceURI is null the namespace
> 	   * is not checked for equality
> 	   * 
> 	   * @param namespaceURI the namespace of the attribute
> 	   * @param localName the local name of the attribute, cannot be null
> 	   * @return returns the value of the attribute , returns null if not found
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(String namespaceURI,
> 	                                  String localName){
> 		  if(curType == XMLStreamConstants.START_ELEMENT){
> 			  String value = attrs.getValue(namespaceURI, localName);
> 			  return value;
> 		  }
> 		  
> 		  throw new IllegalStateException("Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 	   * Returns the count of attributes on this START_ELEMENT,
> 	   * this method is only valid on a START_ELEMENT or ATTRIBUTE. 
> 	   * For SAXSource, there is no explict Attribute event
> 	   * 
> 	   * @return returns the number of attributes
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public int getAttributeCount(){
> 	    if (curType == XMLStreamConstants.START_ELEMENT) {
> 			return curAttrs.size();
> 		}
> 		throw new IllegalStateException(
> 				"Current event is not START_ELEMENT or ATTRIBUTE");
> 	  }
> 	  /**
> 		 * Returns the qname of the attribute at the provided index This method
> 		 * excludes namespace definitions
> 		 * 
> 		 * @param index
> 		 *            the position of the attribute
> 		 * @return the QName of the attribute
> 		 * @throws IllegalStateException
> 		 *             if this is not a START_ELEMENT or ATTRIBUTE
> 		 */
> 	  public QName getAttributeName(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
>             int leng = getAttributeCount();
>             if(index + 1 > leng || index < 0)
>             	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
>           
>             String name =  attrs.getQName(index);
>  		    String uri = attrs.getURI(index);
>  		    return new QName(uri, name);
> 		  }
> 		  throw new IllegalStateException(
> 	 		"Current event is not START_ELEMENT or ATTRIBUTE");		
> 		  
> 	  }
> 	  
> 	  /**
> 	   * Returns the namespace of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the namespace URI (can be null)
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeNamespace(int index){
> 		  if (curType == XMLStreamConstants.START_ELEMENT) {
> 	            int leng = getAttributeCount();
> 	            if(index + 1 > leng || index < 0)
> 	            	throw new IndexOutOfBoundsException("The index "+ index+ " should be between 0..."+ (leng-1));
> 	          
> 	            String namespaceURI = attrs.getURI(index);     	
> 	           	return namespaceURI;
> 			  }
> 			
> 			  throw new IllegalStateException(
> 					"Current event is not START_ELEMENT or ATTRIBUTE");		
> 	  }
> 	  /**
> 	   * Returns the localName of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the localName of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeLocalName(int index){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of this attribute at the
> 	   * provided index
> 	   * @param index the position of the attribute
> 	   * @return the prefix of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributePrefix(int index){
>           return null;
> 	  }
> 	  /**
> 	   * Returns the XML type of the attribute at the provided
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the XML type of the attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeType(int index){
>            return null;
> 	  }
> 	  /**
> 	   * Returns the value of the attribute at the
> 	   * index
> 	   * @param index the position of the attribute
> 	   * @return the attribute value
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public String getAttributeValue(int index){
>           return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns a boolean which indicates if this
> 	   * attribute was created by default
> 	   * @param index the position of the attribute
> 	   * @return true if this is a default attribute
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
> 	   */
> 	  public boolean isAttributeSpecified(int index){
> 		  return false;
> 	  }
> 	  /**
> 	   * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT.
> 	   * This method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.
> 	   * On an END_ELEMENT the count is of the namespaces that are about to go
> 	   * out of scope.  This is the equivalent of the information reported
> 	   * by SAX callback for an end element event.
> 	   * @return returns the number of namespace declarations on this specific element
> 	   * @throws IllegalStateException if this is not a START_ELEMEN or, END_ELEMENT
> 	   */
> 	  public int getNamespaceCount(){
> 		  return 0;
> 	  }
> 	  /**
> 	   * Returns the prefix for the namespace declared at the
> 	   * index.  Returns null if this is the default namespace
> 	   * declaration
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace prefix
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *    END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespacePrefix(int index){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Returns the uri for the namespace declared at the
> 	   * index.
> 	   *
> 	   * @param index the position of the namespace declaration
> 	   * @return returns the namespace uri
> 	   * @throws IllegalStateException if this is not a START_ELEMENT,
> 	   *   END_ELEMENT or NAMESPACE
> 	   */
> 	  public String getNamespaceURI(int index){
> 		  return null;	
> 	  }
> 	  /**
> 	   * Returns a read only namespace context for the current
> 	   * position.  The context is transient and only valid until
> 	   * a call to next() changes the state of the reader.
> 	   *
> 	   * @return return a namespace context
> 	   */
> 	  public NamespaceContext getNamespaceContext(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns an integer code that indicates the type
> 	   * of the event the cursor is pointing to.
> 	   */
> 	  public int getEventType(){
> 		  return asp.getCurType();
> 	  }
> 	  /**
> 	   * Returns the current value of the parse event as a string,
> 	   * this returns the string value of a CHARACTERS event,
> 	   * returns the value of a COMMENT, the replacement value
> 	   * for an ENTITY_REFERENCE, the string value of a CDATA section,
> 	   * the string value for a SPACE event,
> 	   * or the String value of the internal subset of the DTD.
> 	   * If an ENTITY_REFERENCE has been resolved, any character data
> 	   * will be reported as CHARACTERS events.
> 	   * 
> 	   * The DOM nodes Text, Comment, and CDATASection extends CharacterData, which
> 	   * will map to StAX character events. 
> 	   * 
> 	   * @return the current text or null
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public String getText(){
> 		 return null;
> 	  }
> 	  /**
> 	   * Returns an array which contains the characters from this event.
> 	   * This array should be treated as read-only and transient. I.e. the array will
> 	   * contain the text characters until the XMLStreamReader moves on to the next event.
> 	   * Attempts to hold onto the character array beyond that time or modify the
> 	   * contents of the array are breaches of the contract for this interface.
> 	   * 
> 	   * @return the current text or an empty array
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public char[] getTextCharacters(){
> 		  String text = getText();
> 		  return text.toCharArray();
> 	  }
> 	  /**
> 	   * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.  
> 	   * Text starting a "sourceStart" is copied into "target" starting at "targetStart".  
> 	   * Up to "length" characters are copied.  The number of characters actually copied is returned.
> 	   *
> 	   * XMLStreamException may be thrown if there are any XML errors in the underlying source. 
> 	   * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",  
> 	   * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".  
> 	   *
> 	   * @param sourceStart the index of the first character in the source array to copy
> 	   * @param target the destination array
> 	   * @param targetStart the start offset in the target array
> 	   * @param length the number of characters to copy
> 	   * @return the number of characters actually copied
> 	   * @throws XMLStreamException if the underlying XML source is not well-formed
> 	   * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
> 	   * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target
> 	   * @throws UnsupportedOperationException if this method is not supported 
> 	   * @throws NullPointerException is if target is null
> 	   */
> 	   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) 
> 	     throws XMLStreamException{
> 	      
> 	        if(target == null)
> 	        	throw new NullPointerException();
> 	        int targetLen = target.length;
> 	        
> 	        if (targetStart < 0 || targetStart > targetLen)
> 	            throw new ArrayIndexOutOfBoundsException("The start position of target is out of index");
> 	        
> 	        
> 	        if(length < 0)
> 	            throw new ArrayIndexOutOfBoundsException("The length is out of index");
> 	        	
> 	        int len = getTextLength();
> 	        if (sourceStart < 0 || sourceStart > len) {
> 	            throw new ArrayIndexOutOfBoundsException("The start position of source is out of index");
> 	        }
> 	       
> 	        int avail = len - sourceStart;
> 	        if (avail < length) {
> 	            length = avail;
> 	        }
> 	       
> 	        char[] intBuf = getTextCharacters();
> 	        int intStart = getTextStart();
> 	        System.arraycopy(intBuf, intStart + sourceStart,
> 	                             target, targetStart, length);
> 	        return length;
> 	   }
> 	  /**
> 	   * Returns the offset into the text character array where the first
> 	   * character (of this text event) is stored.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextStart(){
> 		   return 0;
> 	   }
> 	  /**
> 	   * Returns the length of the sequence of characters for this
> 	   * Text event within the text character array.
> 	   * @throws java.lang.IllegalStateException if this state is not
> 	   * a valid text state.
> 	   */
> 	  public int getTextLength(){
> 		  String text = getText();
> 		  return text.length();
> 	   }
> 	  /**
> 	   * Return input encoding if known or null if unknown.
> 	   * @return the encoding of this instance or null
> 	   */
> 	  public String getEncoding(){
> 		   return null;
> 	   }
> 	  /**
> 	   * Return true if the current event has text, false otherwise
> 	   * The following events have text:
> 	   * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
> 	   */
> 	  public boolean hasText(){
> 		  if(curType == XMLStreamConstants.CHARACTERS || curType == XMLStreamConstants.ENTITY_REFERENCE ||
> 				  curType == XMLStreamConstants.COMMENT || curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
> 			  return true;
> 		  else
> 			  return false;
> 	   }
> 	  /**
> 	   * Return the current location of the processor.
> 	   * If the Location is unknown the processor should return
> 	   * an implementation of Location that returns -1 for the
> 	   * location and null for the publicId and systemId.
> 	   * The location information is only valid until next() is
> 	   * called.
> 	   */
> 	  public Location getLocation(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns a QName for the current START_ELEMENT or END_ELEMENT event
> 	   *
> 	   * 
> 	   * @return the QName for the current START_ELEMENT or END_ELEMENT event
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or
> 	   * END_ELEMENT
> 	   */
> 	  public QName getName(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Returns the (local) name of the current event.
> 	   * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
> 	   * For ENTITY_REFERENCE it returns entity name.
> 	   * The current event must be START_ELEMENT or END_ELEMENT, 
> 	   * or ENTITY_REFERENCE
> 	   * @return the localName
> 	   * @throws IllegalStateException if this not a START_ELEMENT,
> 	   * END_ELEMENT or ENTITY_REFERENCE
> 	   */
> 	  public String getLocalName(){
> 		 
> 			  return null;
> 	  }
> 	  /**
> 	   * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
> 	   * returns false otherwise
> 	   */
> 	  public boolean hasName(){
> 		  if(curType == XMLStreamConstants.START_ELEMENT || curType == XMLStreamConstants.END_ELEMENT)
> 		     return true;
> 		  else 
> 			 return false;
> 	  }
> 	  /**
> 	   * If the current event is a START_ELEMENT or END_ELEMENT  this method
> 	   * returns the URI of the current element (URI mapping to the prefix
> 	   * element/attribute has, if any; or if no prefix, null for attribute,
> 	   * and the default namespace URI for the element).
> 	   *
> 	   * @return the URI bound to this elements prefix, the default namespace, or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
> 	   *    or ATTRIBUTE
> 	   */
> 	  public String getNamespaceURI(){
> 		
> 			  return null;
> 	  }
> 	  /**
> 	   * Returns the prefix of the current event or null if the event does not
> 	   * have a prefix
> 	   * @return the prefix or null
> 	   * @throws IllegalStateException if this is not a START_ELEMENT or END_ELEMENT
> 	   */
> 	  public String getPrefix(){
> 		  return null;
> 	  }
> 	  
> 	  /**
> 	   * Get the xml version declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the XML version or null
> 	   */
> 	  public String getVersion(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the standalone declaration from the xml declaration, if one found
> 	   * ({@link #standaloneSet} returns true if one was specified).
> 	   *
> 	   * @return true if this is standalone, or false otherwise
> 	   */
> 	  public boolean isStandalone(){
> 		  return false;
> 	  }
> 	  /**
> 	   * Checks if standalone was set in the document
> 	   * Since we only have DOMSource, the standaloneSet information is hard to 
> 	   * get. Because the default standalone is false, if the standalone is true
> 	   * then it was set.
> 	   * 
> 	   * @return true if standalone was set in the document, or false otherwise
> 	   */
> 	  public boolean standaloneSet(){
> 	
> 		  return true;
> 	  }
> 	  /**
> 	   * Returns the character encoding declared on the xml declaration
> 	   * Returns null if none was declared
> 	   * @return the encoding declared in the document or null
> 	   */
> 	  public String getCharacterEncodingScheme(){
> 		  return null;
> 	  }
> 	  /**
> 	   * Get the target of a processing instruction
> 	   * @return the target
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPITarget() {
>           return null;
> 	  }
> 	  /**
> 	   * Get the data section of a processing instruction
> 	   * @return the data (if processing instruction has any), or null
> 	   *    if the processing instruction only has target.
> 	   * @throws IllegalStateException if the current event is not a
> 	   *   {@link XMLStreamConstants#PROCESSING_INSTRUCTION}
> 	   */
> 	  public String getPIData(){
> 	     return null;
> 	  }
> 	 
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import java.util.HashMap;
> import org.xml.sax.InputSource;
> import org.xml.sax.XMLReader;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class AsyncSAXParser extends Thread{
> 	private XMLReader xr;
> 	private InputSource is;
> 	
> 	// The SAXXMLStreamReader which coordinates with AsyncSAXParser
> 	private SAXXMLStreamReader reader;
> 	
> 	// The flag which represents the status of AsyncSAXParser. If true,
> 	// the SAXParser is executing parsing work
> 	private boolean runningFlag;
> 	
> 	// The current event type
> 	private int curType;
> 	
> 	// The buffer which records the Characters and Space
> 	private char[] charactersBuf;
> 	
> 	// The current attributes of start element. The key is element name, and the 
> 	// value is its attributes
> 	private HashMap attrsMap;
> 	
> 	// The current element name
> 	private String eleName;
> 	
>     public AsyncSAXParser(XMLReader xr, InputSource is, SAXXMLStreamReader reader){
>         this.xr = xr;
> 		this.is = is;
> 		this.reader = reader;
>         this.runningFlag = true;     
>         attrsMap = new HashMap();
>     }
>     /**
>      * The thread begins to parse XML source. 
>      */
>     public void run(){
>     	try{
>     	   xr.parse(is);
>     	}catch(Exception e){
>     	  System.out.print("Error occurs during the SAX parsing process at ");
>     	  e.printStackTrace();
>     	}
>     }  
>     
>     /**
>      * Set the current event type
>      * This method is used by SAXHandler
>      * 
>      * @param cur
>      */
>     public synchronized void setCurType(int cur){
>     	this.curType = cur;
>     }
>     
>     /**
>      * Get the current event type
>      * This method is used by SAXXMLStreamReader
>      * 
>      * @return
>      */
>     public synchronized int getCurType(){
>     	return curType;
>     }
>     
>     /**
>      * Set the status of SAXParser
>      * 
>      * @param flag
>      */
>     public synchronized void setRunningFlag(boolean flag){
>     	runningFlag = flag;
> 		    
>     }
>     
>     /**
>      * Get the status of SAXParser
>      * 
>      * @return
>      */
>     public synchronized boolean getRunningFlag(){
>         return runningFlag;
>     }
>     
>     /**
>      * Set the characters buffer for characters event
>      * 
>      * @param ch
>      * @param start
>      * @param length
>      */
>     public void setCharacters(char[] ch, int start, int length){
>     	charactersBuf = null;
>     	charactersBuf = new char[length];
>     	for(int i = 0; i < length; i++, start++)
>     		charactersBuf[i] = ch[start]; 
>     }
>     
>     /**
>      * Get the current characters buffer
>      * 
>      * @return
>      */
>     public char[] getCharacters(){
>     	return charactersBuf;
>     }
>    
>     /**
>      * Set the attributes for Start element
>      * 
>      * @param attrs
>      */
>     public void setAttributes(Attributes attrs, String eleName){
>     	attrsMap.put(eleName, attrs);
>     }
>     
>     /**
>      * Get the current attributes
>      * 
>      * @return
>      */
>     public Attributes getAttributes(String eleName){
>     	return (Attributes)attrsMap.get(eleName);
>     }
>     
>     /**
>      * Set the element name for startElement and endElement event
>      * 
>      * @param attrs
>      */
>     public void setElementName(String eleName){
>     	this.eleName = eleName;
>     }
>     
>     /**
>      * Get the element name for startElement and endElement event
>      * 
>      * @return
>      */
>     public String getElementName(){
>     	return eleName;
>     }
> }
> /*
>  * Copyright 2006 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 
>  */
> package org.apache.xerces.stax;
> import javax.xml.stream.XMLStreamConstants;
> import javax.xml.stream.XMLStreamException;
> import org.xml.sax.helpers.DefaultHandler;
> import org.xml.sax.Attributes;
> /**
>  * 
>  * @author Hua Lei
>  *
>  */
> public class SAXHandler extends DefaultHandler{
>       
>       private AsyncSAXParser asp;
>       
>       public SAXHandler(AsyncSAXParser asp){
>     	  this.asp = asp;
>       }
>       
>       public void characters(char[] ch, int start, int length){
>     	  try{
>     	    synchronized (asp) {
> 				while (asp.getRunningFlag() == false)
> 					asp.wait();
> 				asp.setCurType(XMLStreamConstants.CHARACTERS);
> 				asp.setRunningFlag(false);
> 				asp.setCharacters(ch, start, length);
> 				asp.notify();
> 			}
>     	  }catch(Exception e){
> 		  }
>       }
>        
>       public void endDocument(){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.END_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>       	  }catch(Exception e){
>   		  }
>       }
>        
>       public synchronized void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName){
>     	  try{
>         	    synchronized (asp) {
>     				while (asp.getRunningFlag() == false)
>     					asp.wait();
>     				asp.setCurType(XMLStreamConstants.END_ELEMENT);
>     				asp.setRunningFlag(false);
>     				asp.setElementName(qName);
>     				asp.notify();
>     			}
>           }catch(Exception e){}
>       }
>        
>       public synchronized void ignorableWhitespace(char[] ch, int start, int length){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.SPACE);
>   				asp.setRunningFlag(false);
>   				asp.setCharacters(ch, start, length);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void notationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.NOTATION_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void processingInstruction(java.lang.String target, java.lang.String data){
>     	  
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.PROCESSING_INSTRUCTION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startDocument(){
>     	 
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_DOCUMENT);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes){
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.START_ELEMENT);
>   				asp.setRunningFlag(false);
>   				asp.setAttributes(attributes, qName);
>   				asp.setElementName(qName);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>        
>       public synchronized void unparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName){
>     	  System.out.println("ENTITY_DECLARATION");
>     	  try{
>       	    synchronized (asp) {
>   				while (asp.getRunningFlag() == false)
>   					asp.wait();
>   				asp.setCurType(XMLStreamConstants.ENTITY_DECLARATION);
>   				asp.setRunningFlag(false);
>   				asp.notify();
>   			}
>         }catch(Exception e){}
>       }
>       
>       // Need to be realized
>       /*
>       public synchronized void startPrefixMapping(java.lang.String prefix, java.lang.String uri){
>     	  System.out.println("startPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void endPrefixMapping(java.lang.String prefix){
>     	  System.out.println("endPrefixMapping");
>     	  asp.setRunningFlag(false);
>       }
>       
>       public synchronized void skippedEntity(java.lang.String name){
>     	  System.out.println("skippedEntity");
>     	  asp.setRunningFlag(false);
>       }
>        */
>        
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org