[ 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 > * ([EMAIL PROTECTED] #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 > * [EMAIL PROTECTED] 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 > * [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
