< prev index next >

src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.org.apache.xerces.internal.impl;
  27 








  28 import com.sun.xml.internal.stream.Entity;
  29 import com.sun.xml.internal.stream.StaxErrorReporter;
  30 import com.sun.xml.internal.stream.XMLEntityStorage;


  31 import com.sun.xml.internal.stream.events.EntityDeclarationImpl;
  32 import com.sun.xml.internal.stream.events.NotationDeclarationImpl;
  33 import javax.xml.namespace.NamespaceContext;
  34 import com.sun.org.apache.xerces.internal.xni.XNIException;
  35 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  36 import javax.xml.XMLConstants;
  37 import javax.xml.namespace.QName;
  38 import javax.xml.stream.Location;
  39 import javax.xml.stream.events.XMLEvent;
  40 import com.sun.org.apache.xerces.internal.util.NamespaceContextWrapper;
  41 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  42 import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl;
  43 import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
  44 import java.io.BufferedInputStream;
  45 import java.io.BufferedReader;
  46 import java.io.IOException;
  47 import java.io.InputStream;
  48 import java.io.Reader;
  49 import java.util.ArrayList;
  50 import java.util.Enumeration;
  51 import java.util.Iterator;
  52 import java.util.List;





  53 import javax.xml.stream.XMLInputFactory;
  54 import javax.xml.stream.XMLStreamConstants;
  55 import javax.xml.stream.XMLStreamException;
  56 import com.sun.org.apache.xerces.internal.util.XMLChar;
  57 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
  58 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
  59 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
  60 
  61 /** This class implements javax.xml.stream.XMLStreamReader. It makes use of XML*Scanner classes to
  62  * derive most of its functionality. If desired, Application can reuse this instance by calling
  63  * reset() and setInputSource().

  64  *
  65  * @author Neeraj Bajaj Sun Microsystems,Inc.
  66  * @author K.Venugopal Sun Microsystems,Inc.
  67  * @author Sunitha Reddy Sun Microsystems,Inc.
  68  */
  69 public class XMLStreamReaderImpl implements javax.xml.stream.XMLStreamReader {
  70 
  71     /** Property identifier: entity manager. */
  72     protected static final String ENTITY_MANAGER =
  73     Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
  74 
  75     /** Property identifier: Error Reporter. */
  76     protected static final String ERROR_REPORTER =
  77     Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  78 
  79     /** Property identifier: Symbol table. */
  80     protected static final String SYMBOL_TABLE =
  81     Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;






  82 
  83     protected static final String READER_IN_DEFINED_STATE =
  84     Constants.READER_IN_DEFINED_STATE;
  85 
  86     private SymbolTable fSymbolTable = new SymbolTable();
  87 
  88     /** Document scanner. */


  89     protected XMLDocumentScannerImpl fScanner = new XMLNSDocumentScannerImpl();
  90 
  91     //make Global NamespaceContextWrapper object,  fScanner.getNamespaceContext() is dynamic object and ita value changes
  92     //as per the state of the parser.
  93     protected NamespaceContextWrapper fNamespaceContextWrapper = new NamespaceContextWrapper((NamespaceSupport)fScanner.getNamespaceContext()) ;

  94     protected XMLEntityManager fEntityManager = new XMLEntityManager();
  95     protected StaxErrorReporter fErrorReporter = new StaxErrorReporter();
  96 
  97 
  98     /** Entity scanner, this alwasy works on last entity that was opened. */

  99     protected XMLEntityScanner fEntityScanner = null;
 100 
 101     /** Input Source */


 102     protected XMLInputSource fInputSource = null;
 103     /** Store properties*/
 104     protected PropertyManager fPropertyManager = null ;


 105 
 106     /** current event type */
 107     private int fEventType ;
 108     /** debug flag*/
 109     static final boolean DEBUG = false ;
 110     /** more to scan */






 111     private boolean fReuse = true;
 112     private boolean fReaderInDefinedState = true ;
 113     private boolean fBindNamespaces = true;
 114     private String fDTDDecl = null;
 115     private String versionStr = null;
 116 
 117     /**
 118      * @param inputStream
 119      * @param props
 120      * @throws XMLStreamException
 121      */
 122     public XMLStreamReaderImpl(InputStream inputStream, PropertyManager props) throws  XMLStreamException {
 123         init(props);
 124         //publicId, systemid, baseSystemId, inputStream, enocding
 125         XMLInputSource inputSource = new XMLInputSource(null,null,null,inputStream,null);
 126         //pass the input source to document scanner impl.
 127         setInputSource(inputSource);
 128     }
 129 
 130     public XMLDocumentScannerImpl getScanner(){
 131         System.out.println("returning scanner");
 132         return fScanner;
 133     }

 134     /**
 135      * @param systemid
 136      * @param props
 137      * @throws XMLStreamException
 138      */
 139     public XMLStreamReaderImpl(String systemid, PropertyManager props) throws  XMLStreamException {
 140         init(props);
 141         //publicId, systemid, baseSystemId, inputStream, enocding
 142         XMLInputSource inputSource = new XMLInputSource(null, systemid, null, false);
 143         //pass the input source to document scanner impl.
 144         setInputSource(inputSource);
 145     }
 146 
 147 
 148     /**
 149      * @param inputStream
 150      * @param encoding
 151      * @param props
 152      * @throws XMLStreamException
 153      */
 154     public XMLStreamReaderImpl(InputStream inputStream, String encoding, PropertyManager props ) throws  XMLStreamException {

 155         init(props);
 156         //publicId, systemid, baseSystemId, inputStream, enocding
 157         XMLInputSource inputSource = new XMLInputSource(null,null,null, new BufferedInputStream(inputStream),encoding );

 158         //pass the input source to document scanner impl.
 159         setInputSource(inputSource);
 160     }
 161 
 162     /**
 163      * @param reader
 164      * @param props
 165      * @throws XMLStreamException
 166      */
 167     public XMLStreamReaderImpl(Reader reader, PropertyManager props) throws  XMLStreamException {

 168         init(props);
 169         //publicId, systemid, baseSystemId, inputStream, enocding
 170         //xxx: Using buffered reader
 171         XMLInputSource inputSource = new XMLInputSource(null,null,null,new BufferedReader(reader),null);

 172         //pass the input source to document scanner impl.
 173         setInputSource(inputSource);
 174     }
 175 
 176     /**
 177      * @param inputSource
 178      * @param props
 179      * @throws XMLStreamException
 180      */
 181     public XMLStreamReaderImpl(XMLInputSource inputSource, PropertyManager props) throws  XMLStreamException {

 182         init(props);
 183         //pass the input source to document scanner impl.
 184         setInputSource(inputSource);
 185     }
 186 
 187     /**
 188      * @param inputSource
 189      * @throws XMLStreamException
 190      */
 191     public void setInputSource(XMLInputSource inputSource ) throws XMLStreamException {
 192         //once setInputSource() is called this instance is busy parsing the inputsource supplied
 193         //this instances is free for reuse if parser has reached END_DOCUMENT state or application has
 194         //called close()
 195         fReuse = false;
 196 
 197         try{
 198 
 199             fScanner.setInputSource(inputSource) ;
 200             //XMLStreamReader should be in defined state
 201             if(fReaderInDefinedState){
 202                 fEventType = fScanner.next();
 203                 if (versionStr == null)
 204                     versionStr = getVersion();

 205 
 206                 if (fEventType == XMLStreamConstants.START_DOCUMENT && versionStr != null && versionStr.equals("1.1")){

 207                     switchToXML11Scanner();
 208                 }
 209 
 210             }
 211         }catch(java.io.IOException ex){
 212             throw new XMLStreamException(ex);
 213         } catch(XNIException ex){ //Issue 56 XNIException not caught
 214             throw new XMLStreamException(ex.getMessage(), getLocation(), ex.getException());
 215         }
 216     }//setInputSource
 217 
 218     void init(PropertyManager propertyManager) throws XMLStreamException {
 219         fPropertyManager = propertyManager;
 220         //set Stax internal properties -- Note that these instances are being created in XMLReaderImpl.
 221         //1.SymbolTable
 222         //2.XMLMessageFormatter
 223         //3.XMLEntityManager
 224         //4. call reset()
 225         //1.
 226         propertyManager.setProperty(SYMBOL_TABLE,  fSymbolTable ) ;
 227         //2.
 228         propertyManager.setProperty(ERROR_REPORTER,  fErrorReporter ) ;
 229         //3.
 230         propertyManager.setProperty(ENTITY_MANAGER, fEntityManager);
 231         //4.
 232         reset();
 233     }
 234 
 235     /** This function tells if this instances is available for reuse.
 236      * One must call reset() and setInputSource() to be able to reuse
 237      * this instance.
 238      */
 239     public boolean canReuse(){
 240         if(DEBUG){
 241             System.out.println("fReuse = " + fReuse);
 242             System.out.println("fEventType = " + getEventTypeString(fEventType) );
 243         }
 244         //when parsing begins, fReuse is set to false
 245         //fReuse is set to 'true' when application calls close()
 246         return fReuse;
 247     }
 248 
 249     /**
 250      * Resets this instance so that this instance is ready for reuse.
 251      */
 252     public void reset(){
 253         fReuse = true;
 254         fEventType = 0 ;
 255         //reset entity manager
 256         fEntityManager.reset(fPropertyManager);
 257         //reset the scanner
 258         fScanner.reset(fPropertyManager);
 259         //REVISIT:this is too ugly -- we are getting XMLEntityManager and XMLEntityReader from
 260         //property manager, it should be only XMLEntityManager
 261         fDTDDecl = null;
 262         fEntityScanner = (XMLEntityScanner)fEntityManager.getEntityScanner()  ;
 263         //default value for this property is true. However, this should be false when using XMLEventReader... Ugh..
 264         //because XMLEventReader should not have defined state.
 265         fReaderInDefinedState = ((Boolean)fPropertyManager.getProperty(READER_IN_DEFINED_STATE)).booleanValue();
 266         fBindNamespaces = ((Boolean)fPropertyManager.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue();
 267         versionStr = null;
 268     }
 269 
 270 
 271     /** Frees any resources associated with this Reader. This method does not close the underlying input source.
 272      * @throws XMLStreamException if there are errors freeing associated resources



 273      */
 274     public void close() throws XMLStreamException {
 275         //xxx: Check what this function is intended to do.
 276         //reset();
 277         fReuse = true ;
 278     }
 279 
 280 
 281     /** Returns the character encoding declared on the xml declaration Returns null if none was declared


 282      * @return the encoding declared in the document or null
 283      */
 284     public String getCharacterEncodingScheme() {
 285         return fScanner.getCharacterEncodingScheme();
 286 
 287     }
 288 
 289 
 290     /**
 291      * @return
 292      */
 293     public int getColumnNumber() {
 294         return fEntityScanner.getColumnNumber();
 295     }//getColumnNumber
 296 
 297     /** Return input encoding if known or null if unknown.


 298      * @return the encoding of this instance or null
 299      */
 300     public String getEncoding() {
 301         return fEntityScanner.getEncoding();
 302     }//getEncoding
 303 
 304     /** 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.







 305      * @return the current text or null
 306      */
 307     public int getEventType() {
 308         return fEventType ;
 309     }//getEventType
 310 
 311     /**
 312      * @return
 313      */
 314     public int getLineNumber() {
 315         return fEntityScanner.getLineNumber() ;
 316     }//getLineNumber
 317 
 318     public String getLocalName() {
 319         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT){
 320             //xxx check whats the value of fCurrentElement
 321             return fScanner.getElementQName().localpart ;
 322         }
 323         else if(fEventType == XMLEvent.ENTITY_REFERENCE){
 324             return fScanner.getEntityName();
 325         }
 326         throw new IllegalStateException("Method getLocalName() cannot be called for " +
 327             getEventTypeString(fEventType) + " event.");
 328     }//getLocalName()
 329 
 330     /**
 331      * @return
 332      */
 333     public String getNamespaceURI() {
 334         //doesn't take care of Attribute as separte event
 335         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT){
 336             return fScanner.getElementQName().uri ;
 337         }
 338         return null ;
 339     }//getNamespaceURI
 340 
 341     /** Get the data section of a processing instruction


 342      * @return the data or null
 343      */
 344 
 345     public String getPIData() {
 346         if( fEventType == XMLEvent.PROCESSING_INSTRUCTION){
 347             return fScanner.getPIData().toString();



 348         }
 349         else throw new java.lang.IllegalStateException("Current state of the parser is " + getEventTypeString(fEventType) +
 350         " But Expected state is " + XMLEvent.PROCESSING_INSTRUCTION  ) ;
 351     }//getPIData
 352 
 353 
 354     /** Get the target of a processing instruction

 355      * @return the target or null
 356      */
 357     public String getPITarget() {
 358         if( fEventType == XMLEvent.PROCESSING_INSTRUCTION){
 359             return fScanner.getPITarget();



 360         }
 361         else throw new java.lang.IllegalStateException("Current state of the parser is " + getEventTypeString(fEventType) +
 362         " But Expected state is " + XMLEvent.PROCESSING_INSTRUCTION  ) ;
 363 
 364     }//getPITarget
 365 
 366 
 367     /**
 368     * @return the prefix of the current event, or null if the event does
 369     * not have a prefix. For START_ELEMENT and END_ELEMENT, return
 370     * XMLConstants.DEFAULT_NS_PREFIX when no prefix is available.
 371     */
 372     public String getPrefix() {
 373         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT){
 374             String prefix = fScanner.getElementQName().prefix;
 375             return prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix;
 376         }
 377         return null ;
 378     }//getPrefix()
 379 
 380 
 381 
 382     /**
 383      * @return
 384      */
 385     public char[] getTextCharacters() {
 386         if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
 387                  || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE){
 388              return fScanner.getCharacterData().ch;
 389          } else{
 390              throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 391              + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 392                      + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 393                      + " , " + getEventTypeString(XMLEvent.SPACE) +" valid for getTextCharacters() " ) ;
 394          }
 395     }
 396 
 397     /**
 398      * @return
 399      */
 400     public int getTextLength() {
 401         if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
 402                  || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE){
 403              return fScanner.getCharacterData().length;
 404          } else{
 405              throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 406              + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 407                      + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 408                      + " , " + getEventTypeString(XMLEvent.SPACE) +" valid for getTextLength() " ) ;
 409          }
 410 
 411    }
 412 
 413     /**
 414      * @return
 415      */
 416     public int getTextStart() {
 417         if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE){

 418              return  fScanner.getCharacterData().offset;
 419          } else{
 420              throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 421              + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 422                      + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 423                      + " , " + getEventTypeString(XMLEvent.SPACE) +" valid for getTextStart() " ) ;
 424          }
 425     }
 426 
 427     /**
 428      * @return
 429      */
 430     public String getValue() {
 431         if(fEventType == XMLEvent.PROCESSING_INSTRUCTION){
 432             return fScanner.getPIData().toString();
 433         } else if(fEventType == XMLEvent.COMMENT){
 434             return fScanner.getComment();
 435         } else if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT){
 436             return fScanner.getElementQName().localpart ;
 437         } else if(fEventType == XMLEvent.CHARACTERS){
 438             return fScanner.getCharacterData().toString();
 439         }
 440         return null;
 441     }//getValue()
 442 
 443     /** Get the XML language version of the current document being parsed */


 444     public String getVersion() {
 445         //apply SAP's patch: the default version in the scanner was set to 1.0 because of DOM and SAX
 446         //so this patch is a workaround of the difference between StAX and DOM
 447         // SAPJVM: Return null if the XML version has not been declared (as specified in the JavaDoc).
 448 
 449         String version = fEntityScanner.getXMLVersion();
 450 
 451         return "1.0".equals(version) && !fEntityScanner.xmlVersionSetExplicitly ? null : version;
 452     }
 453 
 454     /**
 455      * @return
 456      */
 457     public boolean hasAttributes() {
 458         return fScanner.getAttributeIterator().getLength() > 0 ? true : false ;
 459     }
 460 
 461     /** this Funtion returns true if the current event has name */


 462     public boolean hasName() {
 463         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 464             return true;
 465         }  else {
 466             return false;
 467         }
 468     }//hasName()
 469 
 470     /**
 471      * @throws XMLStreamException
 472      * @return
 473      */
 474     public boolean hasNext() throws XMLStreamException {
 475         //the scanner returns -1 when it detects a broken stream
 476         if (fEventType == -1) return false;


 477         //we can check in scanners if the scanner state is not set to
 478         //terminating, we still have more events.
 479         return fEventType != XMLEvent.END_DOCUMENT;
 480     }
 481 
 482     /**
 483      * @return
 484      */
 485     public boolean hasValue() {
 486         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT
 487         || fEventType == XMLEvent.ENTITY_REFERENCE || fEventType == XMLEvent.PROCESSING_INSTRUCTION
 488         || fEventType == XMLEvent.COMMENT || fEventType == XMLEvent.CHARACTERS) {
 489             return true;
 490         } else {
 491             return false;
 492         }
 493 
 494     }
 495 
 496     /**
 497      * @return
 498      */
 499     public boolean isEndElement() {
 500         return fEventType == XMLEvent.END_ELEMENT;
 501     }
 502 
 503     /**
 504      * @return
 505      */
 506     public boolean isStandalone() {
 507         return fScanner.isStandAlone();
 508     }
 509 
 510     /**
 511      * @return
 512      */
 513     public boolean isStartElement() {
 514         return fEventType == XMLEvent.START_ELEMENT;
 515     }
 516 
 517     /**
 518      *  Returns true if the cursor points to a character data event that consists of all whitespace
 519      *  Application calling this method needs to cache the value and avoid calling this method again
 520      *  for the same event.

 521      * @return
 522      */
 523     public boolean isWhiteSpace() {
 524         if(isCharacters() || (fEventType == XMLStreamConstants.CDATA)){
 525             char [] ch = this.getTextCharacters();
 526             final int start = this.getTextStart();
 527             final int end = start + this.getTextLength();
 528             for (int i = start; i < end; i++){
 529                 if(!XMLChar.isSpace(ch[i])){
 530                     return false;
 531                 }
 532             }
 533             return true;
 534         }
 535         return false;
 536     }
 537 
 538 
 539 
 540     /**
 541      * @throws XMLStreamException
 542      * @return
 543      */
 544     public int next() throws XMLStreamException {
 545         if( !hasNext() ) {
 546             if (fEventType != -1) {
 547                 throw new java.util.NoSuchElementException( "END_DOCUMENT reached: no more elements on the stream." );

 548             } else {
 549                 throw new XMLStreamException( "Error processing input source. The input stream is not complete." );

 550             }
 551         }
 552         try {
 553             fEventType = fScanner.next();
 554 
 555             if (versionStr == null) {
 556                 versionStr = getVersion();
 557             }
 558 
 559             if (fEventType == XMLStreamConstants.START_DOCUMENT
 560                     && versionStr != null
 561                     && versionStr.equals("1.1")) {
 562                 switchToXML11Scanner();
 563             }
 564 
 565             return fEventType;
 566         } catch (IOException ex) {
 567             // if this error occured trying to resolve the external DTD subset
 568             // and IS_VALIDATING == false, then this is not an XML error
 569             if (fScanner.fScannerState == fScanner.SCANNER_STATE_DTD_EXTERNAL) {
 570                 Boolean isValidating = (Boolean) fPropertyManager.getProperty(
 571                         XMLInputFactory.IS_VALIDATING);
 572                 if (isValidating != null
 573                         && !isValidating.booleanValue()) {
 574                     // ignore the error, set scanner to known state
 575                     fEventType = XMLEvent.DTD;
 576                     fScanner.setScannerState(fScanner.SCANNER_STATE_PROLOG);
 577                     fScanner.setDriver(fScanner.fPrologDriver);
 578                     if (fDTDDecl == null
 579                             || fDTDDecl.length() == 0) {
 580                         fDTDDecl = "<!-- "
 581                                 + "Exception scanning External DTD Subset.  "
 582                                 + "True contents of DTD cannot be determined.  "
 583                                 + "Processing will continue as XMLInputFactory.IS_VALIDATING == false."
 584                                 + " -->";
 585                     }
 586                     return XMLEvent.DTD;
 587                 }
 588             }
 589 
 590             // else real error
 591             throw new XMLStreamException(ex.getMessage(), getLocation(), ex);
 592         } catch (XNIException ex) {
 593             throw new XMLStreamException(
 594                     ex.getMessage(),
 595                     getLocation(),
 596                     ex.getException());
 597         }
 598     } //next()
 599 
 600     private void switchToXML11Scanner() throws IOException{
 601 
 602         int oldEntityDepth = fScanner.fEntityDepth;
 603         com.sun.org.apache.xerces.internal.xni.NamespaceContext oldNamespaceContext = fScanner.fNamespaceContext;

 604 
 605         fScanner = new XML11NSDocumentScannerImpl();
 606 
 607         //get the new scanner state to old scanner's previous state
 608         fScanner.reset(fPropertyManager);
 609         fScanner.setPropertyManager(fPropertyManager);
 610         fEntityScanner = fEntityManager.getEntityScanner();
 611         fEntityScanner.registerListener(fScanner);
 612         fEntityManager.fCurrentEntity.mayReadChunks = true;
 613         fScanner.setScannerState(XMLEvent.START_DOCUMENT);
 614 
 615         fScanner.fEntityDepth = oldEntityDepth;
 616         fScanner.fNamespaceContext = oldNamespaceContext;
 617         fEventType = fScanner.next();
 618     }
 619 
 620 
 621 
 622     final static String getEventTypeString(int eventType) {
 623         switch (eventType){
 624             case XMLEvent.START_ELEMENT:
 625                 return "START_ELEMENT";
 626             case XMLEvent.END_ELEMENT:
 627                 return "END_ELEMENT";
 628             case XMLEvent.PROCESSING_INSTRUCTION:
 629                 return "PROCESSING_INSTRUCTION";
 630             case XMLEvent.CHARACTERS:
 631                 return "CHARACTERS";
 632             case XMLEvent.COMMENT:
 633                 return "COMMENT";
 634             case XMLEvent.START_DOCUMENT:
 635                 return "START_DOCUMENT";
 636             case XMLEvent.END_DOCUMENT:
 637                 return "END_DOCUMENT";
 638             case XMLEvent.ENTITY_REFERENCE:
 639                 return "ENTITY_REFERENCE";
 640             case XMLEvent.ATTRIBUTE:
 641                 return "ATTRIBUTE";
 642             case XMLEvent.DTD:
 643                 return "DTD";
 644             case XMLEvent.CDATA:
 645                 return "CDATA";
 646             case XMLEvent.SPACE:
 647                 return "SPACE";
 648         }
 649         return "UNKNOWN_EVENT_TYPE, " + String.valueOf(eventType);
 650     }
 651 
 652     /** Returns the count of attributes on this START_ELEMENT,
 653      * this method is only valid on a START_ELEMENT or ATTRIBUTE.  This
 654      * count excludes namespace definitions.  Attribute indices are
 655      * zero-based.

 656      * @return returns the number of attributes
 657      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 658      */
 659     public int getAttributeCount() {
 660         //xxx: recognize SAX properties namespace, namespace-prefix to get XML Namespace declarations
 661         //does length includes namespace declarations ?
 662 
 663         //State should be either START_ELEMENT or ATTRIBUTE
 664         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 665             return fScanner.getAttributeIterator().getLength() ;
 666         } else{
 667             throw new java.lang.IllegalStateException( "Current state is not among the states "
 668                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 669                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 670                      + "valid for getAttributeCount()") ;
 671         }
 672     }//getAttributeCount
 673 
 674     /** Returns the localName of the attribute at the provided
 675      * index

 676      * @param index the position of the attribute
 677      * @return the localName of the attribute
 678      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 679      */
 680     public QName getAttributeName(int index) {
 681         //State should be either START_ELEMENT or ATTRIBUTE
 682         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 683             return convertXNIQNametoJavaxQName(fScanner.getAttributeIterator().getQualifiedName(index)) ;
 684         } else{
 685             throw new java.lang.IllegalStateException("Current state is not among the states "
 686                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 687                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 688                      + "valid for getAttributeName()") ;
 689         }
 690     }//getAttributeName
 691 
 692     /**
 693      * @param index
 694      * @return
 695      */
 696     public String getAttributeLocalName(int index) {
 697         //State should be either START_ELEMENT or ATTRIBUTE
 698         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 699             return fScanner.getAttributeIterator().getLocalName(index) ;
 700         } else{
 701             throw new java.lang.IllegalStateException() ;
 702         }
 703     }//getAttributeName
 704 
 705     /** Returns the namespace of the attribute at the provided
 706      * index

 707      * @param index the position of the attribute
 708      * @return the namespace URI (can be null)
 709      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 710      */
 711     public String getAttributeNamespace(int index) {
 712         //State should be either START_ELEMENT or ATTRIBUTE
 713         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 714             return fScanner.getAttributeIterator().getURI(index);
 715         } else{
 716             throw new java.lang.IllegalStateException("Current state is not among the states "
 717                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 718                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 719                      + "valid for getAttributeNamespace()") ;
 720         }
 721 
 722     }//getAttributeNamespace
 723 
 724     /** Returns the prefix of this attribute at the
 725      * provided index

 726      * @param index the position of the attribute
 727      * @return the prefix of the attribute
 728      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 729      */
 730     public String getAttributePrefix(int index) {
 731         //State should be either START_ELEMENT or ATTRIBUTE
 732         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 733             return fScanner.getAttributeIterator().getPrefix(index);
 734         } else{
 735             throw new java.lang.IllegalStateException("Current state is not among the states "
 736                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 737                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 738                      + "valid for getAttributePrefix()") ;
 739         }
 740     }//getAttributePrefix
 741 
 742     /** Returns the qname of the attribute at the provided index

 743      *
 744      * @param index the position of the attribute
 745      * @return the QName of the attribute
 746      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 747      */
 748     public javax.xml.namespace.QName getAttributeQName(int index) {
 749         //State should be either START_ELEMENT or ATTRIBUTE
 750         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 751             // create new object at runtime..
 752             String localName = fScanner.getAttributeIterator().getLocalName(index) ;
 753             String uri = fScanner.getAttributeIterator().getURI(index) ;
 754             return new javax.xml.namespace.QName(uri, localName) ;
 755         } else{
 756             throw new java.lang.IllegalStateException("Current state is not among the states "
 757                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 758                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 759                      + "valid for getAttributeQName()") ;
 760         }
 761     }//getAttributeQName
 762 
 763     /** Returns the XML type of the attribute at the provided
 764      * index

 765      * @param index the position of the attribute
 766      * @return the XML type of the attribute
 767      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 768      */
 769     public String getAttributeType(int index) {
 770         //State should be either START_ELEMENT or ATTRIBUTE
 771         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 772             return fScanner.getAttributeIterator().getType(index) ;
 773         } else{
 774             throw new java.lang.IllegalStateException("Current state is not among the states "
 775                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 776                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 777                      + "valid for getAttributeType()") ;
 778         }
 779 
 780     }//getAttributeType
 781 
 782     /** Returns the value of the attribute at the
 783      * index

 784      * @param index the position of the attribute
 785      * @return the attribute value
 786      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 787      */
 788     public String getAttributeValue(int index) {
 789         //State should be either START_ELEMENT or ATTRIBUTE
 790         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 791             return fScanner.getAttributeIterator().getValue(index) ;
 792         } else{
 793             throw new java.lang.IllegalStateException("Current state is not among the states "
 794                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 795                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 796                      + "valid for getAttributeValue()") ;
 797         }
 798 
 799     }//getAttributeValue
 800 
 801     /**
 802      * @param namespaceURI
 803      * @param localName
 804      * @return
 805      */
 806     public String getAttributeValue(String namespaceURI, String localName) {
 807         //State should be either START_ELEMENT or ATTRIBUTE
 808         if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 809             XMLAttributesImpl attributes = fScanner.getAttributeIterator();
 810             if (namespaceURI == null) { //sjsxp issue 70
 811                 return attributes.getValue(attributes.getIndexByLocalName(localName)) ;
 812             } else {
 813                 return fScanner.getAttributeIterator().getValue(
 814                         namespaceURI.length() == 0 ? null : namespaceURI, localName) ;
 815             }
 816 
 817         } else{
 818             throw new java.lang.IllegalStateException("Current state is not among the states "
 819                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 820                      + getEventTypeString(XMLEvent.ATTRIBUTE)
 821                      + "valid for getAttributeValue()") ;
 822         }
 823 
 824     }
 825 
 826     /** Reads the content of a text-only element. Precondition:
 827      * the current event is START_ELEMENT. Postcondition:
 828      * The current event is the corresponding END_ELEMENT.
 829      * @throws XMLStreamException if the current event is not a START_ELEMENT or if
 830      * a non text element is encountered


 831      */
 832     public String getElementText() throws XMLStreamException {
 833 
 834         if(getEventType() != XMLStreamConstants.START_ELEMENT) {
 835             throw new XMLStreamException(
 836             "parser must be on START_ELEMENT to read next text", getLocation());
 837         }
 838         int eventType = next();
 839         StringBuffer content = new StringBuffer();
 840         while(eventType != XMLStreamConstants.END_ELEMENT ) {
 841             if(eventType == XMLStreamConstants.CHARACTERS
 842             || eventType == XMLStreamConstants.CDATA
 843             || eventType == XMLStreamConstants.SPACE
 844             || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
 845                 content.append(getText());
 846             } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
 847             || eventType == XMLStreamConstants.COMMENT) {
 848                 // skipping
 849             } else if(eventType == XMLStreamConstants.END_DOCUMENT) {
 850                 throw new XMLStreamException("unexpected end of document when reading element text content");
 851             } else if(eventType == XMLStreamConstants.START_ELEMENT) {
 852                 throw new XMLStreamException(
 853                 "elementGetText() function expects text only elment but START_ELEMENT was encountered.", getLocation());



 854             } else {
 855                 throw new XMLStreamException(
 856                 "Unexpected event type "+ eventType, getLocation());
 857             }
 858             eventType = next();
 859         }
 860         return content.toString();
 861     }
 862 
 863     /** Return the current location of the processor.
 864      * If the Location is unknown the processor should return
 865      * an implementation of Location that returns -1 for the
 866      * location and null for the publicId and systemId.
 867      * The location information is only valid until next() is
 868      * called.
 869      */
 870     public Location getLocation() {
 871         return new Location() {
 872             String _systemId = fEntityScanner.getExpandedSystemId();
 873             String _publicId = fEntityScanner.getPublicId();
 874             int _offset = fEntityScanner.getCharacterOffset();
 875             int _columnNumber = fEntityScanner.getColumnNumber();
 876             int _lineNumber = fEntityScanner.getLineNumber();
 877             public String getLocationURI(){

 878                 return _systemId;
 879             }
 880 
 881             public int getCharacterOffset(){
 882                 return _offset;
 883             }
 884 
 885             public int getColumnNumber() {
 886                 return _columnNumber;
 887             }
 888 
 889             public int getLineNumber(){
 890                 return _lineNumber;
 891             }
 892 
 893             public String getPublicId(){
 894                 return _publicId;
 895             }
 896 
 897             public String getSystemId(){
 898                 return _systemId;
 899             }
 900 
 901             public String toString(){
 902                 StringBuffer sbuffer = new StringBuffer() ;
 903                 sbuffer.append("Line number = " + getLineNumber());
 904                 sbuffer.append("\n") ;
 905                 sbuffer.append("Column number = " + getColumnNumber());
 906                 sbuffer.append("\n") ;
 907                 sbuffer.append("System Id = " + getSystemId());
 908                 sbuffer.append("\n") ;
 909                 sbuffer.append("Public Id = " + getPublicId());
 910                 sbuffer.append("\n") ;
 911                 sbuffer.append("Location Uri= " + getLocationURI());
 912                 sbuffer.append("\n") ;
 913                 sbuffer.append("CharacterOffset = " + getCharacterOffset());
 914                 sbuffer.append("\n") ;
 915                 return sbuffer.toString();
 916             }
 917         } ;
 918 
 919     }
 920 
 921     /** Returns a QName for the current START_ELEMENT or END_ELEMENT event


 922      * @return the QName for the current START_ELEMENT or END_ELEMENT event
 923      */
 924     public javax.xml.namespace.QName getName() {
 925         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT)
 926             return convertXNIQNametoJavaxQName(fScanner.getElementQName());
 927         else
 928             throw new java.lang.IllegalStateException("Illegal to call getName() "+
 929             "when event type is "+ getEventTypeString(fEventType) + "."
 930                      + " Valid states are " + getEventTypeString(XMLEvent.START_ELEMENT) + ", "
 931                      + getEventTypeString(XMLEvent.END_ELEMENT));
 932     }

 933 
 934     /** Returns a read only namespace context for the current
 935      * position.  The context is transient and only valid until
 936      * a call to next() changes the state of the reader.


 937      * @return return a namespace context
 938      */
 939     public NamespaceContext getNamespaceContext() {
 940         return fNamespaceContextWrapper ;
 941     }
 942 
 943     /** Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT,
 944      * this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE. On
 945      * an END_ELEMENT the count is of the namespaces that are about to go
 946      * out of scope.  This is the equivalent of the information reported
 947      * by SAX callback for an end element event.
 948      * @return returns the number of namespace declarations on this specific element
 949      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE




 950      */
 951     public int getNamespaceCount() {
 952         //namespaceContext is dynamic object.
 953         //REVISIT: check if it specifies all conditions mentioned in the javadoc
 954         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){
 955             return fScanner.getNamespaceContext().getDeclaredPrefixCount() ;
 956         } else{

 957             throw new IllegalStateException("Current event state is " + getEventTypeString(fEventType)
 958              + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
 959              + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
 960                      + getEventTypeString(XMLEvent.NAMESPACE)
 961              + " valid for getNamespaceCount()." );
 962         }
 963     }
 964 
 965     /** Returns the prefix for the namespace declared at the
 966      * index.  Returns null if this is the default namespace
 967      * declaration
 968      *
 969      * @param index the position of the namespace declaration
 970      * @return returns the namespace prefix
 971      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE

 972      */
 973     public String getNamespacePrefix(int index) {
 974         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){

 975             //namespaceContext is dynamic object.
 976             String prefix = fScanner.getNamespaceContext().getDeclaredPrefixAt(index) ;
 977             return prefix.equals("") ? null : prefix ;
 978         }
 979         else{
 980             throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
 981              + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
 982              + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
 983                      + getEventTypeString(XMLEvent.NAMESPACE)
 984              + " valid for getNamespacePrefix()." );
 985         }
 986     }
 987 
 988     /** Returns the uri for the namespace declared at the
 989      * index.
 990      *
 991      * @param index the position of the namespace declaration
 992      * @return returns the namespace uri
 993      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE

 994      */
 995     public String getNamespaceURI(int index) {
 996         if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){

 997             //namespaceContext is dynamic object.
 998             return fScanner.getNamespaceContext().getURI(fScanner.getNamespaceContext().getDeclaredPrefixAt(index));
 999         }
1000         else{
1001             throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
1002              + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
1003              + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
1004                      + getEventTypeString(XMLEvent.NAMESPACE)
1005              + " valid for getNamespaceURI()." );
1006         }
1007 
1008     }
1009 
1010     /** Get the value of a feature/property from the underlying implementation


1011      * @param name The name of the property, may not be null
1012      * @return The value of the property
1013      * @throws IllegalArgumentException if name is null
1014      */
1015     public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
1016         if(name == null) throw new java.lang.IllegalArgumentException() ;
1017         if (fPropertyManager != null ){
1018             if(name.equals(fPropertyManager.STAX_NOTATIONS)){


1019                 return getNotationDecls();
1020             }else if(name.equals(fPropertyManager.STAX_ENTITIES)){
1021                 return getEntityDecls();
1022             }else
1023                 return fPropertyManager.getProperty(name);
1024         }

1025         return null;
1026     }
1027 
1028     /** Returns the current value of the parse event as a string,
1029      * this returns the string value of a CHARACTERS event,
1030      * returns the value of a COMMENT, the replacement value
1031      * for an ENTITY_REFERENCE,
1032      * or the String value of the DTD

1033      * @return the current text or null
1034      * @throws java.lang.IllegalStateException if this state is not
1035      * a valid text state.
1036      */
1037     public String getText() {
1038         if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
1039                 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE){
1040             //this requires creation of new string
1041             //fEventType == XMLEvent.ENTITY_REFERENCE
1042             return fScanner.getCharacterData().toString() ;
1043         } else if(fEventType == XMLEvent.ENTITY_REFERENCE){
1044             String name = fScanner.getEntityName();
1045             if(name != null){
1046                 if(fScanner.foundBuiltInRefs)
1047                     return fScanner.getCharacterData().toString();

1048 
1049                 XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1050                 Entity en = entityStore.getEntity(name);
1051                 if(en == null)
1052                     return null;
1053                 if(en.isExternal())
1054                     return ((Entity.ExternalEntity)en).entityLocation.getExpandedSystemId();
1055                 else
1056                     return ((Entity.InternalEntity)en).text;
1057             }else


1058                 return null;
1059         }
1060         else if(fEventType == XMLEvent.DTD){
1061                 if(fDTDDecl != null){
1062                     return fDTDDecl;
1063                 }
1064                 XMLStringBuffer tmpBuffer = fScanner.getDTDDecl();
1065                 fDTDDecl = tmpBuffer.toString();
1066                 return fDTDDecl;
1067         } else{
1068                 throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
1069                      + " is not among the states" + getEventTypeString(XMLEvent.CHARACTERS) + ", "
1070                      + getEventTypeString(XMLEvent.COMMENT) + ", "
1071                      + getEventTypeString(XMLEvent.CDATA) + ", "
1072                      + getEventTypeString(XMLEvent.SPACE) + ", "
1073                      + getEventTypeString(XMLEvent.ENTITY_REFERENCE) + ", "
1074                      + getEventTypeString(XMLEvent.DTD) + " valid for getText() " ) ;
1075         }
1076     }//getText
1077 
1078 
1079     /** 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.
1080      * If the namespaceURI is null it is not checked for equality, if the localName is null it is not checked for equality.



1081      * @param type the event type
1082      * @param namespaceURI the uri of the event, may be null
1083      * @param localName the localName of the event, may be null
1084      * @throws XMLStreamException if the required values are not matched.
1085      */
1086     public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
1087         if( type != fEventType)
1088              throw new XMLStreamException("Event type " + getEventTypeString(type) + " specified did " +
1089                      "not match with current parser event " + getEventTypeString(fEventType));
1090           if( namespaceURI != null && !namespaceURI.equals(getNamespaceURI()) )
1091              throw new XMLStreamException("Namespace URI " + namespaceURI +" specified did not match " +
1092                      "with current namespace URI");
1093           if(localName != null && !localName.equals(getLocalName()))
1094              throw new XMLStreamException("LocalName " + localName +" specified did not match with " +
1095                      "current local name");



1096         return;
1097     }
1098 
1099     /** Gets the the text associated with a CHARACTERS, SPACE or CDATA event.
1100      * Text starting a "sourceStart" is copied into "destination" starting at "targetStart".
1101      * Up to "length" characters are copied.  The number of characters actually copied is returned.
1102      *
1103      * The "sourceStart" argument must be greater or equal to 0 and less than or equal to
1104      * the number of characters associated with the event.  Usually, one requests text starting at a "sourceStart" of 0.
1105      * If the number of characters actually copied is less than the "length", then there is no more text.
1106      * Otherwise, subsequent calls need to be made until all text has been retrieved. For example:




1107      *
1108      * <code>
1109      * int length = 1024;
1110      * char[] myBuffer = new char[ length ];
1111      *
1112      * for ( int sourceStart = 0 ; ; sourceStart += length )
1113      * {
1114      *    int nCopied = stream.getTextCharacters( sourceStart, myBuffer, 0, length );
1115      *
1116      *   if (nCopied < length)
1117      *       break;
1118      * }
1119      * </code>
1120      * XMLStreamException may be thrown if there are any XML errors in the underlying source.
1121      * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target",
1122      * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target".

1123      *
1124      * @param sourceStart the index of the first character in the source array to copy

1125      * @param target the destination array
1126      * @param targetStart the start offset in the target array
1127      * @param length the number of characters to copy
1128      * @return the number of characters actually copied
1129      * @throws XMLStreamException if the underlying XML source is not well-formed
1130      * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target
1131      * @throws IndexOutOfBoundwhile(isCharacters()) ;sException if length < 0 or targetStart + length > length of target



1132      * @throws UnsupportedOperationException if this method is not supported
1133      * @throws NullPointerException is if target is null
1134      */
1135     public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {

1136 
1137         if(target == null){
1138             throw new NullPointerException("target char array can't be null") ;
1139         }
1140 
1141         if(targetStart < 0 || length < 0 || sourceStart < 0 || targetStart >= target.length ||
1142             (targetStart + length ) > target.length) {
1143             throw new IndexOutOfBoundsException();
1144         }
1145 
1146         //getTextStart() + sourceStart should not be greater than the lenght of number of characters
1147         //present
1148         int copiedLength = 0;
1149         //int presentDataLen = getTextLength() - (getTextStart()+sourceStart);
1150         int available = getTextLength() - sourceStart;
1151         if(available < 0){
1152             throw new IndexOutOfBoundsException("sourceStart is greater than" +
1153                 "number of characters associated with this event");
1154         }
1155         if(available < length){
1156             copiedLength = available;
1157         } else{
1158             copiedLength = length;
1159         }
1160 
1161         System.arraycopy(getTextCharacters(), getTextStart() + sourceStart , target, targetStart, copiedLength);
1162         return copiedLength;
1163     }
1164 
1165     /** Return true if the current event has text, false otherwise
1166      * The following events have text:
1167      * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT
1168      */
1169     public boolean hasText() {
1170         if(DEBUG) pr("XMLReaderImpl#EVENT TYPE = " + fEventType ) ;
1171         if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT || fEventType == XMLEvent.CDATA) {



1172             return fScanner.getCharacterData().length > 0;
1173         } else if(fEventType == XMLEvent.ENTITY_REFERENCE) {
1174             String name = fScanner.getEntityName();
1175             if(name != null){
1176                 if(fScanner.foundBuiltInRefs)
1177                     return true;

1178 
1179                 XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1180                 Entity en = entityStore.getEntity(name);
1181                 if(en == null)
1182                     return false;
1183                 if(en.isExternal()){
1184                     return ((Entity.ExternalEntity)en).entityLocation.getExpandedSystemId() != null;
1185                 } else{
1186                     return ((Entity.InternalEntity)en).text != null ;
1187                 }
1188             }else
1189                 return false;



1190         } else {
1191             if(fEventType == XMLEvent.DTD)


1192                 return fScanner.fSeenDoctypeDecl;
1193         }
1194         return false;
1195     }
1196 
1197     /** Returns a boolean which indicates if this
1198      * attribute was created by default


1199      * @param index the position of the attribute
1200      * @return true if this is a default attribute
1201      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
1202      */
1203     public boolean isAttributeSpecified(int index) {
1204         //check that current state should be either START_ELEMENT or ATTRIBUTE
1205         if( (fEventType == XMLEvent.START_ELEMENT) || (fEventType == XMLEvent.ATTRIBUTE)){
1206             return fScanner.getAttributeIterator().isSpecified(index) ;
1207         } else{
1208             throw new IllegalStateException("Current state is not among the states "
1209                      + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
1210                      + getEventTypeString(XMLEvent.ATTRIBUTE)
1211                      + "valid for isAttributeSpecified()")  ;
1212         }
1213     }
1214 
1215     /** Returns true if the cursor points to a character data event


1216      * @return true if the cursor points to character data, false otherwise
1217      */
1218     public boolean isCharacters() {
1219         return fEventType == XMLEvent.CHARACTERS ;
1220     }
1221 
1222     /** Skips any insignificant events (COMMENT and PROCESSING_INSTRUCTION)
1223      * until a START_ELEMENT or
1224      * END_ELEMENT is reached. If other than space characters are
1225      * encountered, an exception is thrown. This method should
1226      * be used when processing element-only content because
1227      * the parser is not able to recognize ignorable whitespace if
1228      * then DTD is missing or not interpreted.
1229      * @return the event type of the element read
1230      * @throws XMLStreamException if the current event is not white space
1231      */
1232     public int nextTag() throws XMLStreamException {
1233 
1234         int eventType = next();
1235         while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
1236         || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
1237         // skip whitespace
1238         || eventType == XMLStreamConstants.SPACE
1239         || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
1240         || eventType == XMLStreamConstants.COMMENT
1241         ) {
1242             eventType = next();
1243         }
1244 
1245         if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
1246             throw new XMLStreamException(
1247                     "found: " + getEventTypeString(eventType)
1248                     + ", expected " + getEventTypeString(XMLStreamConstants.START_ELEMENT)
1249                     + " or " + getEventTypeString(XMLStreamConstants.END_ELEMENT),
1250                     getLocation());
1251         }
1252 
1253         return eventType;
1254     }
1255 
1256     /** Checks if standalone was set in the document


1257      * @return true if standalone was set in the document, or false otherwise
1258      */
1259     public boolean standaloneSet() {
1260         //xxx: it requires if the standalone was set in the document ? This is different that if the document
1261         // is standalone
1262         return fScanner.standaloneSet() ;
1263     }
1264 
1265     /**
1266      * @param qname
1267      * @return
1268      */
1269     public javax.xml.namespace.QName convertXNIQNametoJavaxQName(com.sun.org.apache.xerces.internal.xni.QName qname){
1270         if (qname == null) return null;



1271         //xxx: prefix definition ?
1272         if(qname.prefix == null){
1273             return new javax.xml.namespace.QName(qname.uri, qname.localpart) ;
1274         } else{
1275             return new javax.xml.namespace.QName(qname.uri, qname.localpart, qname.prefix) ;
1276         }
1277     }
1278 
1279     /** Return the uri for the given prefix.
1280      * The uri returned depends on the current state of the processor.

1281      *
1282      * <p><strong>NOTE:</strong>The 'xml' prefix is bound as defined in
1283      * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>


1284      * specification to "http://www.w3.org/XML/1998/namespace".
1285      *
1286      * <p><strong>NOTE:</strong> The 'xmlns' prefix must be resolved to following namespace


1287      * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>

1288      * @return the uri bound to the given prefix or null if it is not bound
1289      * @param prefix The prefix to lookup, may not be null
1290      * @throws IllegalStateException - if the prefix is null
1291      */
1292     public String getNamespaceURI(String prefix) {
1293         if(prefix == null) throw new java.lang.IllegalArgumentException("prefix cannot be null.") ;


1294 
1295         //first add the string to symbol table.. since internally identity comparisons are done.
1296         return fScanner.getNamespaceContext().getURI(fSymbolTable.addSymbol(prefix)) ;
1297     }
1298 
1299     //xxx: this function is not being used.
1300     protected void setPropertyManager(PropertyManager propertyManager){
1301         fPropertyManager = propertyManager ;
1302         //REVISIT: we were supplying hashmap ealier
1303         fScanner.setProperty("stax-properties",propertyManager);
1304         fScanner.setPropertyManager(propertyManager) ;
1305     }
1306 
1307     /**
1308      * @return returns the reference to property manager.
1309      */
1310     protected PropertyManager getPropertyManager(){
1311         return fPropertyManager ;
1312     }
1313 
1314     static void pr(String str) {
1315         System.out.println(str) ;
1316     }
1317 
1318     protected List getEntityDecls(){
1319         if(fEventType == XMLStreamConstants.DTD){
1320             XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1321             ArrayList list = null;
1322             if(entityStore.hasEntities()){

1323                 EntityDeclarationImpl decl = null;
1324                 list = new ArrayList(entityStore.getEntitySize());
1325                 Enumeration enu = entityStore.getEntityKeys();
1326                 while(enu.hasMoreElements()){
1327                     String key = (String)enu.nextElement();
1328                     Entity en = (Entity)entityStore.getEntity(key);
1329                     decl = new EntityDeclarationImpl();
1330                     decl.setEntityName(key);
1331                     if(en.isExternal()){
1332                         decl.setXMLResourceIdentifier(((Entity.ExternalEntity)en).entityLocation);
1333                         decl.setNotationName(((Entity.ExternalEntity)en).notation);


1334                     }
1335                     else
1336                         decl.setEntityReplacementText(((Entity.InternalEntity)en).text);
1337                     list.add(decl);
1338                 }
1339             }
1340             return list;
1341         }
1342         return null;
1343     }
1344 
1345     protected List getNotationDecls(){
1346         if(fEventType == XMLStreamConstants.DTD){
1347             if(fScanner.fDTDScanner == null) return null;
1348             DTDGrammar grammar = ((XMLDTDScannerImpl)(fScanner.fDTDScanner)).getGrammar();
1349             if(grammar == null) return null;
1350             List notations = grammar.getNotationDecls();
1351 
1352             Iterator it = notations.iterator();
1353             ArrayList list = new ArrayList();
1354             while(it.hasNext()){
1355                 XMLNotationDecl ni = (XMLNotationDecl)it.next();
1356                 if(ni!= null){
1357                     list.add(new NotationDeclarationImpl(ni));

1358                 }
1359             }
1360             return list;
1361         }
1362         return null;
1363     }
1364 
1365 
1366 
1367 }//XMLReaderImpl


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.org.apache.xerces.internal.impl;
  27 
  28 import com.sun.org.apache.xerces.internal.util.NamespaceContextWrapper;
  29 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
  30 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  31 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
  32 import com.sun.org.apache.xerces.internal.util.XMLChar;
  33 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
  34 import com.sun.org.apache.xerces.internal.xni.XNIException;
  35 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  36 import com.sun.xml.internal.stream.Entity;
  37 import com.sun.xml.internal.stream.StaxErrorReporter;
  38 import com.sun.xml.internal.stream.XMLEntityStorage;
  39 import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
  40 import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl;
  41 import com.sun.xml.internal.stream.events.EntityDeclarationImpl;
  42 import com.sun.xml.internal.stream.events.NotationDeclarationImpl;











  43 import java.io.BufferedInputStream;
  44 import java.io.BufferedReader;
  45 import java.io.IOException;
  46 import java.io.InputStream;
  47 import java.io.Reader;
  48 import java.util.ArrayList;


  49 import java.util.List;
  50 import java.util.Map;
  51 import javax.xml.XMLConstants;
  52 import javax.xml.namespace.NamespaceContext;
  53 import javax.xml.namespace.QName;
  54 import javax.xml.stream.Location;
  55 import javax.xml.stream.XMLInputFactory;
  56 import javax.xml.stream.XMLStreamConstants;
  57 import javax.xml.stream.XMLStreamException;
  58 import javax.xml.stream.events.EntityDeclaration;
  59 import javax.xml.stream.events.NotationDeclaration;
  60 import javax.xml.stream.events.XMLEvent;

  61 
  62 /**
  63  * This class implements javax.xml.stream.XMLStreamReader. It makes use of
  64  * XML*Scanner classes to derive most of its functionality. If desired,
  65  * Application can reuse this instance by calling reset() and setInputSource().
  66  *
  67  * @author Neeraj Bajaj Sun Microsystems,Inc.
  68  * @author K.Venugopal Sun Microsystems,Inc.
  69  * @author Sunitha Reddy Sun Microsystems,Inc.
  70  */
  71 public class XMLStreamReaderImpl implements javax.xml.stream.XMLStreamReader {
  72 
  73     /**
  74      * Property identifier: entity manager.
  75      */
  76     protected static final String ENTITY_MANAGER
  77             = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
  78 
  79     /**
  80      * Property identifier: Error Reporter.
  81      */
  82     protected static final String ERROR_REPORTER
  83             = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  84 
  85     /**
  86      * Property identifier: Symbol table.
  87      */
  88     protected static final String SYMBOL_TABLE
  89             = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  90 
  91     protected static final String READER_IN_DEFINED_STATE
  92             = Constants.READER_IN_DEFINED_STATE;
  93 
  94     private SymbolTable fSymbolTable = new SymbolTable();
  95 
  96     /**
  97      * Document scanner.
  98      */
  99     protected XMLDocumentScannerImpl fScanner = new XMLNSDocumentScannerImpl();
 100 
 101     //make Global NamespaceContextWrapper object,  fScanner.getNamespaceContext()
 102     //is dynamic object and ita value changes as per the state of the parser.
 103     protected NamespaceContextWrapper fNamespaceContextWrapper =
 104             new NamespaceContextWrapper((NamespaceSupport) fScanner.getNamespaceContext());
 105     protected XMLEntityManager fEntityManager = new XMLEntityManager();
 106     protected StaxErrorReporter fErrorReporter = new StaxErrorReporter();
 107 
 108     /**
 109      * Entity scanner, this alwasy works on last entity that was opened.
 110      */
 111     protected XMLEntityScanner fEntityScanner = null;
 112 
 113     /**
 114      * Input Source
 115      */
 116     protected XMLInputSource fInputSource = null;
 117     /**
 118      * Store properties
 119      */
 120     protected PropertyManager fPropertyManager = null;
 121 
 122     /**
 123      * current event type
 124      */
 125     private int fEventType;
 126     /**
 127      * debug flag
 128      */
 129     static final boolean DEBUG = false;
 130     /**
 131      * more to scan
 132      */
 133     private boolean fReuse = true;
 134     private boolean fReaderInDefinedState = true;

 135     private String fDTDDecl = null;
 136     private String versionStr = null;
 137 
 138     /**
 139      * @param inputStream
 140      * @param props
 141      * @throws XMLStreamException
 142      */
 143     public XMLStreamReaderImpl(InputStream inputStream, PropertyManager props) throws XMLStreamException {
 144         init(props);
 145         //publicId, systemid, baseSystemId, inputStream, enocding
 146         XMLInputSource inputSource = new XMLInputSource(null, null, null, inputStream, null);
 147         //pass the input source to document scanner impl.
 148         setInputSource(inputSource);
 149     }
 150 
 151     public XMLDocumentScannerImpl getScanner() {
 152         System.out.println("returning scanner");
 153         return fScanner;
 154     }
 155 
 156     /**
 157      * @param systemid
 158      * @param props
 159      * @throws XMLStreamException
 160      */
 161     public XMLStreamReaderImpl(String systemid, PropertyManager props) throws XMLStreamException {
 162         init(props);
 163         //publicId, systemid, baseSystemId, inputStream, enocding
 164         XMLInputSource inputSource = new XMLInputSource(null, systemid, null, false);
 165         //pass the input source to document scanner impl.
 166         setInputSource(inputSource);
 167     }
 168 

 169     /**
 170      * @param inputStream
 171      * @param encoding
 172      * @param props
 173      * @throws XMLStreamException
 174      */
 175     public XMLStreamReaderImpl(InputStream inputStream, String encoding, PropertyManager props)
 176             throws XMLStreamException {
 177         init(props);
 178         //publicId, systemid, baseSystemId, inputStream, enocding
 179         XMLInputSource inputSource = new XMLInputSource(null, null, null,
 180                 new BufferedInputStream(inputStream), encoding);
 181         //pass the input source to document scanner impl.
 182         setInputSource(inputSource);
 183     }
 184 
 185     /**
 186      * @param reader
 187      * @param props
 188      * @throws XMLStreamException
 189      */
 190     public XMLStreamReaderImpl(Reader reader, PropertyManager props)
 191             throws XMLStreamException {
 192         init(props);
 193         //publicId, systemid, baseSystemId, inputStream, enocding
 194         //xxx: Using buffered reader
 195         XMLInputSource inputSource = new XMLInputSource(null, null, null,
 196                 new BufferedReader(reader), null);
 197         //pass the input source to document scanner impl.
 198         setInputSource(inputSource);
 199     }
 200 
 201     /**
 202      * @param inputSource
 203      * @param props
 204      * @throws XMLStreamException
 205      */
 206     public XMLStreamReaderImpl(XMLInputSource inputSource, PropertyManager props)
 207             throws XMLStreamException {
 208         init(props);
 209         //pass the input source to document scanner impl.
 210         setInputSource(inputSource);
 211     }
 212 
 213     /**
 214      * @param inputSource
 215      * @throws XMLStreamException
 216      */
 217     public final void setInputSource(XMLInputSource inputSource) throws XMLStreamException {
 218         //once setInputSource() is called this instance is busy parsing the inputsource supplied
 219         //this instances is free for reuse if parser has reached END_DOCUMENT state or application has
 220         //called close()
 221         fReuse = false;
 222 
 223         try {
 224 
 225             fScanner.setInputSource(inputSource);
 226             //XMLStreamReader should be in defined state
 227             if (fReaderInDefinedState) {
 228                 fEventType = fScanner.next();
 229                 if (versionStr == null) {
 230                     versionStr = getVersion();
 231                 }
 232 
 233                 if (fEventType == XMLStreamConstants.START_DOCUMENT && versionStr != null
 234                         && versionStr.equals("1.1")) {
 235                     switchToXML11Scanner();
 236                 }
 237 
 238             }
 239         } catch (java.io.IOException ex) {
 240             throw new XMLStreamException(ex);
 241         } catch (XNIException ex) { //Issue 56 XNIException not caught
 242             throw new XMLStreamException(ex.getMessage(), getLocation(), ex.getException());
 243         }
 244     }//setInputSource
 245 
 246     final void init(PropertyManager propertyManager) throws XMLStreamException {
 247         fPropertyManager = propertyManager;
 248         //set Stax internal properties -- Note that these instances are being created in XMLReaderImpl.
 249         //1.SymbolTable
 250         //2.XMLMessageFormatter
 251         //3.XMLEntityManager
 252         //4. call reset()
 253         //1.
 254         propertyManager.setProperty(SYMBOL_TABLE, fSymbolTable);
 255         //2.
 256         propertyManager.setProperty(ERROR_REPORTER, fErrorReporter);
 257         //3.
 258         propertyManager.setProperty(ENTITY_MANAGER, fEntityManager);
 259         //4.
 260         reset();
 261     }
 262 
 263     /**
 264      * This function tells if this instances is available for reuse. One must
 265      * call reset() and setInputSource() to be able to reuse this instance.
 266      */
 267     public boolean canReuse() {
 268         if (DEBUG) {
 269             System.out.println("fReuse = " + fReuse);
 270             System.out.println("fEventType = " + getEventTypeString(fEventType));
 271         }
 272         //when parsing begins, fReuse is set to false
 273         //fReuse is set to 'true' when application calls close()
 274         return fReuse;
 275     }
 276 
 277     /**
 278      * Resets this instance so that this instance is ready for reuse.
 279      */
 280     public void reset() {
 281         fReuse = true;
 282         fEventType = 0;
 283         //reset entity manager
 284         fEntityManager.reset(fPropertyManager);
 285         //reset the scanner
 286         fScanner.reset(fPropertyManager);
 287         //REVISIT:this is too ugly -- we are getting XMLEntityManager and XMLEntityReader from
 288         //property manager, it should be only XMLEntityManager
 289         fDTDDecl = null;
 290         fEntityScanner = fEntityManager.getEntityScanner();
 291         //default value for this property is true. However, this should be false
 292         //when using XMLEventReader, because XMLEventReader should not have defined state.
 293         fReaderInDefinedState = ((Boolean) fPropertyManager.getProperty(READER_IN_DEFINED_STATE));

 294         versionStr = null;
 295     }
 296 
 297     /**
 298      * Frees any resources associated with this Reader. This method does not
 299      * close the underlying input source.
 300      *
 301      * @throws XMLStreamException if there are errors freeing associated
 302      * resources
 303      */
 304     public void close() throws XMLStreamException {
 305         //xxx: Check what this function is intended to do.
 306         //reset();
 307         fReuse = true;
 308     }
 309 
 310     /**
 311      * Returns the character encoding declared on the xml declaration Returns
 312      * null if none was declared
 313      *
 314      * @return the encoding declared in the document or null
 315      */
 316     public String getCharacterEncodingScheme() {
 317         return fScanner.getCharacterEncodingScheme();
 318 
 319     }
 320 

 321     /**
 322      * @return
 323      */
 324     public int getColumnNumber() {
 325         return fEntityScanner.getColumnNumber();
 326     }//getColumnNumber
 327 
 328     /**
 329      * Return input encoding if known or null if unknown.
 330      *
 331      * @return the encoding of this instance or null
 332      */
 333     public String getEncoding() {
 334         return fEntityScanner.getEncoding();
 335     }//getEncoding
 336 
 337     /**
 338      * Returns the current value of the parse event as a string, this returns
 339      * the string value of a CHARACTERS event, returns the value of a COMMENT,
 340      * the replacement value for an ENTITY_REFERENCE, the string value of a
 341      * CDATA section, the string value for a SPACE event, or the String value of
 342      * the internal subset of the DTD. If an ENTITY_REFERENCE has been resolved,
 343      * any character data will be reported as CHARACTERS events.
 344      *
 345      * @return the current text or null
 346      */
 347     public int getEventType() {
 348         return fEventType;
 349     }//getEventType
 350 
 351     /**
 352      * @return
 353      */
 354     public int getLineNumber() {
 355         return fEntityScanner.getLineNumber();
 356     }//getLineNumber
 357 
 358     public String getLocalName() {
 359         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 360             //xxx check whats the value of fCurrentElement
 361             return fScanner.getElementQName().localpart;
 362         } else if (fEventType == XMLEvent.ENTITY_REFERENCE) {

 363             return fScanner.getEntityName();
 364         }
 365         throw new IllegalStateException("Method getLocalName() cannot be called for "
 366                 + getEventTypeString(fEventType) + " event.");
 367     }//getLocalName()
 368 
 369     /**
 370      * @return
 371      */
 372     public String getNamespaceURI() {
 373         //doesn't take care of Attribute as separte event
 374         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 375             return fScanner.getElementQName().uri;
 376         }
 377         return null;
 378     }//getNamespaceURI
 379 
 380     /**
 381      * Get the data section of a processing instruction
 382      *
 383      * @return the data or null
 384      */

 385     public String getPIData() {
 386         if (fEventType == XMLEvent.PROCESSING_INSTRUCTION) {
 387             return fScanner.getPIData().toString();
 388         } else {
 389             throw new java.lang.IllegalStateException("Current state of the parser is " + getEventTypeString(fEventType)
 390                     + " But Expected state is " + XMLEvent.PROCESSING_INSTRUCTION);
 391         }


 392     }//getPIData
 393 
 394     /**
 395      * Get the target of a processing instruction
 396      *
 397      * @return the target or null
 398      */
 399     public String getPITarget() {
 400         if (fEventType == XMLEvent.PROCESSING_INSTRUCTION) {
 401             return fScanner.getPITarget();
 402         } else {
 403             throw new java.lang.IllegalStateException("Current state of the parser is " + getEventTypeString(fEventType)
 404                     + " But Expected state is " + XMLEvent.PROCESSING_INSTRUCTION);
 405         }


 406 
 407     }//getPITarget
 408 

 409     /**
 410      * @return the prefix of the current event, or null if the event does not
 411      * have a prefix. For START_ELEMENT and END_ELEMENT, return
 412      * XMLConstants.DEFAULT_NS_PREFIX when no prefix is available.
 413      */
 414     public String getPrefix() {
 415         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 416             String prefix = fScanner.getElementQName().prefix;
 417             return prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix;
 418         }
 419         return null;
 420     }//getPrefix()
 421 


 422     /**
 423      * @return
 424      */
 425     public char[] getTextCharacters() {
 426         if (fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
 427                 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE) {
 428             return fScanner.getCharacterData().ch;
 429         } else {
 430             throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 431                     + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 432                     + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 433                     + " , " + getEventTypeString(XMLEvent.SPACE) + " valid for getTextCharacters() ");
 434         }
 435     }
 436 
 437     /**
 438      * @return
 439      */
 440     public int getTextLength() {
 441         if (fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
 442                 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE) {
 443             return fScanner.getCharacterData().length;
 444         } else {
 445             throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 446                     + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 447                     + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 448                     + " , " + getEventTypeString(XMLEvent.SPACE) + " valid for getTextLength() ");
 449         }
 450 
 451     }
 452 
 453     /**
 454      * @return
 455      */
 456     public int getTextStart() {
 457         if (fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
 458                 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE) {
 459             return fScanner.getCharacterData().offset;
 460         } else {
 461             throw new IllegalStateException("Current state = " + getEventTypeString(fEventType)
 462                     + " is not among the states " + getEventTypeString(XMLEvent.CHARACTERS) + " , "
 463                     + getEventTypeString(XMLEvent.COMMENT) + " , " + getEventTypeString(XMLEvent.CDATA)
 464                     + " , " + getEventTypeString(XMLEvent.SPACE) + " valid for getTextStart() ");
 465         }
 466     }
 467 
 468     /**
 469      * @return
 470      */
 471     public String getValue() {
 472         if (fEventType == XMLEvent.PROCESSING_INSTRUCTION) {
 473             return fScanner.getPIData().toString();
 474         } else if (fEventType == XMLEvent.COMMENT) {
 475             return fScanner.getComment();
 476         } else if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 477             return fScanner.getElementQName().localpart;
 478         } else if (fEventType == XMLEvent.CHARACTERS) {
 479             return fScanner.getCharacterData().toString();
 480         }
 481         return null;
 482     }//getValue()
 483 
 484     /**
 485      * Get the XML language version of the current document being parsed
 486      */
 487     public String getVersion() {
 488         //apply SAP's patch: the default version in the scanner was set to 1.0 because of DOM and SAX
 489         //so this patch is a workaround of the difference between StAX and DOM
 490         // SAPJVM: Return null if the XML version has not been declared (as specified in the JavaDoc).
 491 
 492         String version = fEntityScanner.getXMLVersion();
 493 
 494         return "1.0".equals(version) && !fEntityScanner.xmlVersionSetExplicitly ? null : version;
 495     }
 496 
 497     /**
 498      * @return
 499      */
 500     public boolean hasAttributes() {
 501         return fScanner.getAttributeIterator().getLength() > 0 ? true : false;
 502     }
 503 
 504     /**
 505      * this Funtion returns true if the current event has name
 506      */
 507     public boolean hasName() {
 508         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 509             return true;
 510         } else {
 511             return false;
 512         }
 513     }//hasName()
 514 
 515     /**
 516      * @throws XMLStreamException
 517      * @return
 518      */
 519     public boolean hasNext() throws XMLStreamException {
 520         //the scanner returns -1 when it detects a broken stream
 521         if (fEventType == -1) {
 522             return false;
 523         }
 524         //we can check in scanners if the scanner state is not set to
 525         //terminating, we still have more events.
 526         return fEventType != XMLEvent.END_DOCUMENT;
 527     }
 528 
 529     /**
 530      * @return
 531      */
 532     public boolean hasValue() {
 533         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT
 534                 || fEventType == XMLEvent.ENTITY_REFERENCE || fEventType == XMLEvent.PROCESSING_INSTRUCTION
 535                 || fEventType == XMLEvent.COMMENT || fEventType == XMLEvent.CHARACTERS) {
 536             return true;
 537         } else {
 538             return false;
 539         }
 540 
 541     }
 542 
 543     /**
 544      * @return
 545      */
 546     public boolean isEndElement() {
 547         return fEventType == XMLEvent.END_ELEMENT;
 548     }
 549 
 550     /**
 551      * @return
 552      */
 553     public boolean isStandalone() {
 554         return fScanner.isStandAlone();
 555     }
 556 
 557     /**
 558      * @return
 559      */
 560     public boolean isStartElement() {
 561         return fEventType == XMLEvent.START_ELEMENT;
 562     }
 563 
 564     /**
 565      * Returns true if the cursor points to a character data event that consists
 566      * of all whitespace Application calling this method needs to cache the
 567      * value and avoid calling this method again for the same event.
 568      *
 569      * @return
 570      */
 571     public boolean isWhiteSpace() {
 572         if (isCharacters() || (fEventType == XMLStreamConstants.CDATA)) {
 573             char[] ch = this.getTextCharacters();
 574             final int start = this.getTextStart();
 575             final int end = start + this.getTextLength();
 576             for (int i = start; i < end; i++) {
 577                 if (!XMLChar.isSpace(ch[i])) {
 578                     return false;
 579                 }
 580             }
 581             return true;
 582         }
 583         return false;
 584     }
 585 


 586     /**
 587      * @throws XMLStreamException
 588      * @return
 589      */
 590     public int next() throws XMLStreamException {
 591         if (!hasNext()) {
 592             if (fEventType != -1) {
 593                 throw new java.util.NoSuchElementException(
 594                         "END_DOCUMENT reached: no more elements on the stream.");
 595             } else {
 596                 throw new XMLStreamException(
 597                         "Error processing input source. The input stream is not complete.");
 598             }
 599         }
 600         try {
 601             fEventType = fScanner.next();
 602 
 603             if (versionStr == null) {
 604                 versionStr = getVersion();
 605             }
 606 
 607             if (fEventType == XMLStreamConstants.START_DOCUMENT
 608                     && versionStr != null
 609                     && versionStr.equals("1.1")) {
 610                 switchToXML11Scanner();
 611             }
 612 
 613             return fEventType;
 614         } catch (IOException ex) {
 615             // if this error occured trying to resolve the external DTD subset
 616             // and IS_VALIDATING == false, then this is not an XML error
 617             if (fScanner.fScannerState == XMLDocumentScannerImpl.SCANNER_STATE_DTD_EXTERNAL) {
 618                 Boolean isValidating = (Boolean) fPropertyManager.getProperty(
 619                         XMLInputFactory.IS_VALIDATING);
 620                 if (isValidating != null
 621                         && !isValidating.booleanValue()) {
 622                     // ignore the error, set scanner to known state
 623                     fEventType = XMLEvent.DTD;
 624                     fScanner.setScannerState(XMLDocumentScannerImpl.SCANNER_STATE_PROLOG);
 625                     fScanner.setDriver(fScanner.fPrologDriver);
 626                     if (fDTDDecl == null
 627                             || fDTDDecl.length() == 0) {
 628                         fDTDDecl = "<!-- "
 629                                 + "Exception scanning External DTD Subset.  "
 630                                 + "True contents of DTD cannot be determined.  "
 631                                 + "Processing will continue as XMLInputFactory.IS_VALIDATING == false."
 632                                 + " -->";
 633                     }
 634                     return XMLEvent.DTD;
 635                 }
 636             }
 637 
 638             // else real error
 639             throw new XMLStreamException(ex.getMessage(), getLocation(), ex);
 640         } catch (XNIException ex) {
 641             throw new XMLStreamException(
 642                     ex.getMessage(),
 643                     getLocation(),
 644                     ex.getException());
 645         }
 646     } //next()
 647 
 648     private void switchToXML11Scanner() throws IOException {
 649 
 650         int oldEntityDepth = fScanner.fEntityDepth;
 651         com.sun.org.apache.xerces.internal.xni.NamespaceContext oldNamespaceContext
 652                 = fScanner.fNamespaceContext;
 653 
 654         fScanner = new XML11NSDocumentScannerImpl();
 655 
 656         //get the new scanner state to old scanner's previous state
 657         fScanner.reset(fPropertyManager);
 658         fScanner.setPropertyManager(fPropertyManager);
 659         fEntityScanner = fEntityManager.getEntityScanner();
 660         fEntityScanner.registerListener(fScanner);
 661         fEntityManager.fCurrentEntity.mayReadChunks = true;
 662         fScanner.setScannerState(XMLEvent.START_DOCUMENT);
 663 
 664         fScanner.fEntityDepth = oldEntityDepth;
 665         fScanner.fNamespaceContext = oldNamespaceContext;
 666         fEventType = fScanner.next();
 667     }
 668 


 669     final static String getEventTypeString(int eventType) {
 670         switch (eventType) {
 671             case XMLEvent.START_ELEMENT:
 672                 return "START_ELEMENT";
 673             case XMLEvent.END_ELEMENT:
 674                 return "END_ELEMENT";
 675             case XMLEvent.PROCESSING_INSTRUCTION:
 676                 return "PROCESSING_INSTRUCTION";
 677             case XMLEvent.CHARACTERS:
 678                 return "CHARACTERS";
 679             case XMLEvent.COMMENT:
 680                 return "COMMENT";
 681             case XMLEvent.START_DOCUMENT:
 682                 return "START_DOCUMENT";
 683             case XMLEvent.END_DOCUMENT:
 684                 return "END_DOCUMENT";
 685             case XMLEvent.ENTITY_REFERENCE:
 686                 return "ENTITY_REFERENCE";
 687             case XMLEvent.ATTRIBUTE:
 688                 return "ATTRIBUTE";
 689             case XMLEvent.DTD:
 690                 return "DTD";
 691             case XMLEvent.CDATA:
 692                 return "CDATA";
 693             case XMLEvent.SPACE:
 694                 return "SPACE";
 695         }
 696         return "UNKNOWN_EVENT_TYPE, " + String.valueOf(eventType);
 697     }
 698 
 699     /**
 700      * Returns the count of attributes on this START_ELEMENT, this method is
 701      * only valid on a START_ELEMENT or ATTRIBUTE. This count excludes namespace
 702      * definitions. Attribute indices are zero-based.
 703      *
 704      * @return returns the number of attributes
 705      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 706      */
 707     public int getAttributeCount() {
 708         //xxx: recognize SAX properties namespace, namespace-prefix to get XML Namespace declarations
 709         //does length includes namespace declarations ?
 710 
 711         //State should be either START_ELEMENT or ATTRIBUTE
 712         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 713             return fScanner.getAttributeIterator().getLength();
 714         } else {
 715             throw new java.lang.IllegalStateException("Current state is not among the states "
 716                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 717                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 718                     + "valid for getAttributeCount()");
 719         }
 720     }//getAttributeCount
 721 
 722     /**
 723      * Returns the localName of the attribute at the provided index
 724      *
 725      * @param index the position of the attribute
 726      * @return the localName of the attribute
 727      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 728      */
 729     public QName getAttributeName(int index) {
 730         //State should be either START_ELEMENT or ATTRIBUTE
 731         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 732             return convertXNIQNametoJavaxQName(fScanner.getAttributeIterator().getQualifiedName(index));
 733         } else {
 734             throw new java.lang.IllegalStateException("Current state is not among the states "
 735                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 736                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 737                     + "valid for getAttributeName()");
 738         }
 739     }//getAttributeName
 740 
 741     /**
 742      * @param index
 743      * @return
 744      */
 745     public String getAttributeLocalName(int index) {
 746         //State should be either START_ELEMENT or ATTRIBUTE
 747         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 748             return fScanner.getAttributeIterator().getLocalName(index);
 749         } else {
 750             throw new java.lang.IllegalStateException();
 751         }
 752     }//getAttributeName
 753 
 754     /**
 755      * Returns the namespace of the attribute at the provided index
 756      *
 757      * @param index the position of the attribute
 758      * @return the namespace URI (can be null)
 759      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 760      */
 761     public String getAttributeNamespace(int index) {
 762         //State should be either START_ELEMENT or ATTRIBUTE
 763         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 764             return fScanner.getAttributeIterator().getURI(index);
 765         } else {
 766             throw new java.lang.IllegalStateException("Current state is not among the states "
 767                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 768                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 769                     + "valid for getAttributeNamespace()");
 770         }
 771 
 772     }//getAttributeNamespace
 773 
 774     /**
 775      * Returns the prefix of this attribute at the provided index
 776      *
 777      * @param index the position of the attribute
 778      * @return the prefix of the attribute
 779      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 780      */
 781     public String getAttributePrefix(int index) {
 782         //State should be either START_ELEMENT or ATTRIBUTE
 783         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 784             return fScanner.getAttributeIterator().getPrefix(index);
 785         } else {
 786             throw new java.lang.IllegalStateException("Current state is not among the states "
 787                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 788                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 789                     + "valid for getAttributePrefix()");
 790         }
 791     }//getAttributePrefix
 792 
 793     /**
 794      * Returns the qname of the attribute at the provided index
 795      *
 796      * @param index the position of the attribute
 797      * @return the QName of the attribute
 798      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 799      */
 800     public javax.xml.namespace.QName getAttributeQName(int index) {
 801         //State should be either START_ELEMENT or ATTRIBUTE
 802         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 803             // create new object at runtime..
 804             String localName = fScanner.getAttributeIterator().getLocalName(index);
 805             String uri = fScanner.getAttributeIterator().getURI(index);
 806             return new javax.xml.namespace.QName(uri, localName);
 807         } else {
 808             throw new java.lang.IllegalStateException("Current state is not among the states "
 809                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 810                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 811                     + "valid for getAttributeQName()");
 812         }
 813     }//getAttributeQName
 814 
 815     /**
 816      * Returns the XML type of the attribute at the provided index
 817      *
 818      * @param index the position of the attribute
 819      * @return the XML type of the attribute
 820      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 821      */
 822     public String getAttributeType(int index) {
 823         //State should be either START_ELEMENT or ATTRIBUTE
 824         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 825             return fScanner.getAttributeIterator().getType(index);
 826         } else {
 827             throw new java.lang.IllegalStateException("Current state is not among the states "
 828                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 829                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 830                     + "valid for getAttributeType()");
 831         }
 832 
 833     }//getAttributeType
 834 
 835     /**
 836      * Returns the value of the attribute at the index
 837      *
 838      * @param index the position of the attribute
 839      * @return the attribute value
 840      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
 841      */
 842     public String getAttributeValue(int index) {
 843         //State should be either START_ELEMENT or ATTRIBUTE
 844         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 845             return fScanner.getAttributeIterator().getValue(index);
 846         } else {
 847             throw new java.lang.IllegalStateException("Current state is not among the states "
 848                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 849                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 850                     + "valid for getAttributeValue()");
 851         }
 852 
 853     }//getAttributeValue
 854 
 855     /**
 856      * @param namespaceURI
 857      * @param localName
 858      * @return
 859      */
 860     public String getAttributeValue(String namespaceURI, String localName) {
 861         //State should be either START_ELEMENT or ATTRIBUTE
 862         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) {
 863             XMLAttributesImpl attributes = fScanner.getAttributeIterator();
 864             if (namespaceURI == null) { //sjsxp issue 70
 865                 return attributes.getValue(attributes.getIndexByLocalName(localName));
 866             } else {
 867                 return fScanner.getAttributeIterator().getValue(
 868                         namespaceURI.length() == 0 ? null : namespaceURI, localName);
 869             }
 870 
 871         } else {
 872             throw new java.lang.IllegalStateException("Current state is not among the states "
 873                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
 874                     + getEventTypeString(XMLEvent.ATTRIBUTE)
 875                     + "valid for getAttributeValue()");
 876         }
 877 
 878     }
 879 
 880     /**
 881      * Reads the content of a text-only element. Precondition: the current event
 882      * is START_ELEMENT. Postcondition: The current event is the corresponding
 883      * END_ELEMENT.
 884      *
 885      * @throws XMLStreamException if the current event is not a START_ELEMENT or
 886      * if a non text element is encountered
 887      */
 888     public String getElementText() throws XMLStreamException {
 889 
 890         if (getEventType() != XMLStreamConstants.START_ELEMENT) {
 891             throw new XMLStreamException(
 892                     "parser must be on START_ELEMENT to read next text", getLocation());
 893         }
 894         int eventType = next();
 895         StringBuilder content = new StringBuilder();
 896         while (eventType != XMLStreamConstants.END_ELEMENT) {
 897             if (eventType == XMLStreamConstants.CHARACTERS
 898                     || eventType == XMLStreamConstants.CDATA
 899                     || eventType == XMLStreamConstants.SPACE
 900                     || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
 901                 content.append(getText());
 902             } else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
 903                     || eventType == XMLStreamConstants.COMMENT) {
 904                 // skipping
 905             } else if (eventType == XMLStreamConstants.END_DOCUMENT) {


 906                 throw new XMLStreamException(
 907                         "unexpected end of document when reading element text content");
 908             } else if (eventType == XMLStreamConstants.START_ELEMENT) {
 909                 throw new XMLStreamException("elementGetText() function expects text "
 910                         + "only elment but START_ELEMENT was encountered.", getLocation());
 911             } else {
 912                 throw new XMLStreamException(
 913                         "Unexpected event type " + eventType, getLocation());
 914             }
 915             eventType = next();
 916         }
 917         return content.toString();
 918     }
 919 
 920     /**
 921      * Return the current location of the processor. If the Location is unknown
 922      * the processor should return an implementation of Location that returns -1
 923      * for the location and null for the publicId and systemId. The location
 924      * information is only valid until next() is called.

 925      */
 926     public Location getLocation() {
 927         return new Location() {
 928             String _systemId = fEntityScanner.getExpandedSystemId();
 929             String _publicId = fEntityScanner.getPublicId();
 930             int _offset = fEntityScanner.getCharacterOffset();
 931             int _columnNumber = fEntityScanner.getColumnNumber();
 932             int _lineNumber = fEntityScanner.getLineNumber();
 933 
 934             public String getLocationURI() {
 935                 return _systemId;
 936             }
 937 
 938             public int getCharacterOffset() {
 939                 return _offset;
 940             }
 941 
 942             public int getColumnNumber() {
 943                 return _columnNumber;
 944             }
 945 
 946             public int getLineNumber() {
 947                 return _lineNumber;
 948             }
 949 
 950             public String getPublicId() {
 951                 return _publicId;
 952             }
 953 
 954             public String getSystemId() {
 955                 return _systemId;
 956             }
 957 
 958             public String toString() {
 959                 StringBuilder sbuffer = new StringBuilder();
 960                 sbuffer.append("Line number = " + getLineNumber());
 961                 sbuffer.append("\n");
 962                 sbuffer.append("Column number = " + getColumnNumber());
 963                 sbuffer.append("\n");
 964                 sbuffer.append("System Id = " + getSystemId());
 965                 sbuffer.append("\n");
 966                 sbuffer.append("Public Id = " + getPublicId());
 967                 sbuffer.append("\n");
 968                 sbuffer.append("Location Uri= " + getLocationURI());
 969                 sbuffer.append("\n");
 970                 sbuffer.append("CharacterOffset = " + getCharacterOffset());
 971                 sbuffer.append("\n");
 972                 return sbuffer.toString();
 973             }
 974         };
 975 
 976     }
 977 
 978     /**
 979      * Returns a QName for the current START_ELEMENT or END_ELEMENT event
 980      *
 981      * @return the QName for the current START_ELEMENT or END_ELEMENT event
 982      */
 983     public javax.xml.namespace.QName getName() {
 984         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) {
 985             return convertXNIQNametoJavaxQName(fScanner.getElementQName());
 986         } else {
 987             throw new java.lang.IllegalStateException("Illegal to call getName() "
 988                     + "when event type is " + getEventTypeString(fEventType) + "."
 989                     + " Valid states are " + getEventTypeString(XMLEvent.START_ELEMENT) + ", "
 990                     + getEventTypeString(XMLEvent.END_ELEMENT));
 991         }
 992     }
 993 
 994     /**
 995      * Returns a read only namespace context for the current position. The
 996      * context is transient and only valid until a call to next() changes the
 997      * state of the reader.
 998      *
 999      * @return return a namespace context
1000      */
1001     public NamespaceContext getNamespaceContext() {
1002         return fNamespaceContextWrapper;
1003     }
1004 
1005     /**
1006      * Returns the count of namespaces declared on this START_ELEMENT or
1007      * END_ELEMENT, this method is only valid on a START_ELEMENT, END_ELEMENT or
1008      * NAMESPACE. On an END_ELEMENT the count is of the namespaces that are
1009      * about to go out of scope. This is the equivalent of the information
1010      * reported by SAX callback for an end element event.
1011      *
1012      * @return returns the number of namespace declarations on this specific
1013      * element
1014      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
1015      * or NAMESPACE
1016      */
1017     public int getNamespaceCount() {
1018         //namespaceContext is dynamic object.
1019         //REVISIT: check if it specifies all conditions mentioned in the javadoc
1020         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT
1021                 || fEventType == XMLEvent.NAMESPACE) {
1022             return fScanner.getNamespaceContext().getDeclaredPrefixCount();
1023         } else {
1024             throw new IllegalStateException("Current event state is " + getEventTypeString(fEventType)
1025                     + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
1026                     + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
1027                     + getEventTypeString(XMLEvent.NAMESPACE)
1028                     + " valid for getNamespaceCount().");
1029         }
1030     }
1031 
1032     /**
1033      * Returns the prefix for the namespace declared at the index. Returns null
1034      * if this is the default namespace declaration
1035      *
1036      * @param index the position of the namespace declaration
1037      * @return returns the namespace prefix
1038      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
1039      * or NAMESPACE
1040      */
1041     public String getNamespacePrefix(int index) {
1042         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT
1043                 || fEventType == XMLEvent.NAMESPACE) {
1044             //namespaceContext is dynamic object.
1045             String prefix = fScanner.getNamespaceContext().getDeclaredPrefixAt(index);
1046             return prefix.equals("") ? null : prefix;
1047         } else {

1048             throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
1049                     + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
1050                     + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
1051                     + getEventTypeString(XMLEvent.NAMESPACE)
1052                     + " valid for getNamespacePrefix().");
1053         }
1054     }
1055 
1056     /**
1057      * Returns the uri for the namespace declared at the index.
1058      *
1059      * @param index the position of the namespace declaration
1060      * @return returns the namespace uri
1061      * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT
1062      * or NAMESPACE
1063      */
1064     public String getNamespaceURI(int index) {
1065         if (fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT
1066                 || fEventType == XMLEvent.NAMESPACE) {
1067             //namespaceContext is dynamic object.
1068             return fScanner.getNamespaceContext().getURI(fScanner.getNamespaceContext()
1069                     .getDeclaredPrefixAt(index));
1070         } else {
1071             throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
1072                     + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT)
1073                     + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", "
1074                     + getEventTypeString(XMLEvent.NAMESPACE)
1075                     + " valid for getNamespaceURI().");
1076         }
1077 
1078     }
1079 
1080     /**
1081      * Get the value of a feature/property from the underlying implementation
1082      *
1083      * @param name The name of the property, may not be null
1084      * @return The value of the property
1085      * @throws IllegalArgumentException if name is null
1086      */
1087     public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
1088         if (name == null) {
1089             throw new java.lang.IllegalArgumentException();
1090         }
1091         if (fPropertyManager != null) {
1092             if (name.equals(PropertyManager.STAX_NOTATIONS)) {
1093                 return getNotationDecls();
1094             } else if (name.equals(PropertyManager.STAX_ENTITIES)) {
1095                 return getEntityDecls();
1096             } else {
1097                 return fPropertyManager.getProperty(name);
1098             }
1099         }
1100         return null;
1101     }
1102 
1103     /**
1104      * Returns the current value of the parse event as a string, this returns
1105      * the string value of a CHARACTERS event, returns the value of a COMMENT,
1106      * the replacement value for an ENTITY_REFERENCE, or the String value of the
1107      * DTD
1108      *
1109      * @return the current text or null
1110      * @throws java.lang.IllegalStateException if this state is not a valid text
1111      * state.
1112      */
1113     public String getText() {
1114         if (fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
1115                 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE) {
1116             //this requires creation of new string
1117             //fEventType == XMLEvent.ENTITY_REFERENCE
1118             return fScanner.getCharacterData().toString();
1119         } else if (fEventType == XMLEvent.ENTITY_REFERENCE) {
1120             String name = fScanner.getEntityName();
1121             if (name != null) {
1122                 if (fScanner.foundBuiltInRefs) {
1123                     return fScanner.getCharacterData().toString();
1124                 }
1125 
1126                 XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1127                 Entity en = entityStore.getEntity(name);
1128                 if (en == null) {
1129                     return null;
1130                 }
1131                 if (en.isExternal()) {
1132                     return ((Entity.ExternalEntity) en).entityLocation.getExpandedSystemId();
1133                 } else {
1134                     return ((Entity.InternalEntity) en).text;
1135                 }
1136             } else {
1137                 return null;
1138             }
1139         } else if (fEventType == XMLEvent.DTD) {
1140             if (fDTDDecl != null) {
1141                 return fDTDDecl;
1142             }
1143             XMLStringBuffer tmpBuffer = fScanner.getDTDDecl();
1144             fDTDDecl = tmpBuffer.toString();
1145             return fDTDDecl;
1146         } else {
1147             throw new IllegalStateException("Current state " + getEventTypeString(fEventType)
1148                     + " is not among the states" + getEventTypeString(XMLEvent.CHARACTERS) + ", "
1149                     + getEventTypeString(XMLEvent.COMMENT) + ", "
1150                     + getEventTypeString(XMLEvent.CDATA) + ", "
1151                     + getEventTypeString(XMLEvent.SPACE) + ", "
1152                     + getEventTypeString(XMLEvent.ENTITY_REFERENCE) + ", "
1153                     + getEventTypeString(XMLEvent.DTD) + " valid for getText() ");
1154         }
1155     }//getText
1156 
1157     /**
1158      * Test if the current event is of the given type and if the namespace and
1159      * name match the current namespace and name of the current event. If the
1160      * namespaceURI is null it is not checked for equality, if the localName is
1161      * null it is not checked for equality.
1162      *
1163      * @param type the event type
1164      * @param namespaceURI the uri of the event, may be null
1165      * @param localName the localName of the event, may be null
1166      * @throws XMLStreamException if the required values are not matched.
1167      */
1168     public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
1169         if (type != fEventType) {
1170             throw new XMLStreamException("Event type " + getEventTypeString(type) + " specified did "
1171                     + "not match with current parser event " + getEventTypeString(fEventType));
1172         }
1173         if (namespaceURI != null && !namespaceURI.equals(getNamespaceURI())) {
1174             throw new XMLStreamException("Namespace URI " + namespaceURI + " specified did not match "
1175                     + "with current namespace URI");
1176         }
1177         if (localName != null && !localName.equals(getLocalName())) {
1178             throw new XMLStreamException("LocalName " + localName + " specified did not match with "
1179                     + "current local name");
1180         }
1181         return;
1182     }
1183 
1184     /**
1185      * Gets the the text associated with a CHARACTERS, SPACE or CDATA event.
1186      * Text starting a "sourceStart" is copied into "destination" starting at
1187      * "targetStart". Up to "length" characters are copied. The number of
1188      * characters actually copied is returned.
1189      *
1190      * The "sourceStart" argument must be greater or equal to 0 and less than or
1191      * equal to the number of characters associated with the event. Usually, one
1192      * requests text starting at a "sourceStart" of 0. If the number of
1193      * characters actually copied is less than the "length", then there is no
1194      * more text. Otherwise, subsequent calls need to be made until all text has
1195      * been retrieved. For example:
1196      *
1197      * <code>
1198      * int length = 1024;
1199      * char[] myBuffer = new char[ length ];
1200      *
1201      * for ( int sourceStart = 0 ; ; sourceStart += length )
1202      * {
1203      *    int nCopied = stream.getTextCharacters( sourceStart, myBuffer, 0, length );
1204      *
1205      *   if (nCopied < length)
1206      *       break;
1207      * }
1208      * </code> XMLStreamException may be thrown if there are any XML errors in
1209      * the underlying source. The "targetStart" argument must be greater than or
1210      * equal to 0 and less than the length of "target", Length must be greater
1211      * than 0 and "targetStart + length" must be less than or equal to length of
1212      * "target".
1213      *
1214      * @param sourceStart the index of the first character in the source array
1215      * to copy
1216      * @param target the destination array
1217      * @param targetStart the start offset in the target array
1218      * @param length the number of characters to copy
1219      * @return the number of characters actually copied
1220      * @throws XMLStreamException if the underlying XML source is not
1221      * well-formed
1222      * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length
1223      * of target
1224      * @throws IndexOutOfBoundwhile(isCharacters()) ;sException if length < 0 or targetStart + length
1225      * > length of target
1226      * @throws UnsupportedOperationException if this method is not supported
1227      * @throws NullPointerException is if target is null
1228      */
1229     public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
1230             throws XMLStreamException {
1231 
1232         if (target == null) {
1233             throw new NullPointerException("target char array can't be null");
1234         }
1235 
1236         if (targetStart < 0 || length < 0 || sourceStart < 0 || targetStart >= target.length
1237                 || (targetStart + length) > target.length) {
1238             throw new IndexOutOfBoundsException();
1239         }
1240 
1241         //getTextStart() + sourceStart should not be greater than the lenght of number of characters
1242         //present
1243         int copiedLength = 0;
1244         //int presentDataLen = getTextLength() - (getTextStart()+sourceStart);
1245         int available = getTextLength() - sourceStart;
1246         if (available < 0) {
1247             throw new IndexOutOfBoundsException("sourceStart is greater than"
1248                     + "number of characters associated with this event");
1249         }
1250         if (available < length) {
1251             copiedLength = available;
1252         } else {
1253             copiedLength = length;
1254         }
1255 
1256         System.arraycopy(getTextCharacters(), getTextStart() + sourceStart, target, targetStart, copiedLength);
1257         return copiedLength;
1258     }
1259 
1260     /**
1261      * Return true if the current event has text, false otherwise The following
1262      * events have text: CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT
1263      */
1264     public boolean hasText() {
1265         if (DEBUG) {
1266             pr("XMLReaderImpl#EVENT TYPE = " + fEventType);
1267         }
1268         if (fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT
1269                 || fEventType == XMLEvent.CDATA) {
1270             return fScanner.getCharacterData().length > 0;
1271         } else if (fEventType == XMLEvent.ENTITY_REFERENCE) {
1272             String name = fScanner.getEntityName();
1273             if (name != null) {
1274                 if (fScanner.foundBuiltInRefs) {
1275                     return true;
1276                 }
1277 
1278                 XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1279                 Entity en = entityStore.getEntity(name);
1280                 if (en == null) {
1281                     return false;




1282                 }
1283                 if (en.isExternal()) {
1284                     return ((Entity.ExternalEntity) en).entityLocation.getExpandedSystemId() != null;
1285                 } else {
1286                     return ((Entity.InternalEntity) en).text != null;
1287                 }
1288             } else {
1289                 return false;
1290             }
1291         } else if (fEventType == XMLEvent.DTD) {
1292             return fScanner.fSeenDoctypeDecl;
1293         }
1294         return false;
1295     }
1296 
1297     /**
1298      * Returns a boolean which indicates if this attribute was created by
1299      * default
1300      *
1301      * @param index the position of the attribute
1302      * @return true if this is a default attribute
1303      * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE
1304      */
1305     public boolean isAttributeSpecified(int index) {
1306         //check that current state should be either START_ELEMENT or ATTRIBUTE
1307         if ((fEventType == XMLEvent.START_ELEMENT) || (fEventType == XMLEvent.ATTRIBUTE)) {
1308             return fScanner.getAttributeIterator().isSpecified(index);
1309         } else {
1310             throw new IllegalStateException("Current state is not among the states "
1311                     + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
1312                     + getEventTypeString(XMLEvent.ATTRIBUTE)
1313                     + "valid for isAttributeSpecified()");
1314         }
1315     }
1316 
1317     /**
1318      * Returns true if the cursor points to a character data event
1319      *
1320      * @return true if the cursor points to character data, false otherwise
1321      */
1322     public boolean isCharacters() {
1323         return fEventType == XMLEvent.CHARACTERS;
1324     }
1325 
1326     /**
1327      * Skips any insignificant events (COMMENT and PROCESSING_INSTRUCTION) until
1328      * a START_ELEMENT or END_ELEMENT is reached. If other than space characters
1329      * are encountered, an exception is thrown. This method should be used when
1330      * processing element-only content because the parser is not able to
1331      * recognize ignorable whitespace if then DTD is missing or not interpreted.
1332      *
1333      * @return the event type of the element read
1334      * @throws XMLStreamException if the current event is not white space
1335      */
1336     public int nextTag() throws XMLStreamException {
1337 
1338         int eventType = next();
1339         while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
1340                 || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
1341                 // skip whitespace
1342                 || eventType == XMLStreamConstants.SPACE
1343                 || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
1344                 || eventType == XMLStreamConstants.COMMENT) {

1345             eventType = next();
1346         }
1347 
1348         if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
1349             throw new XMLStreamException(
1350                     "found: " + getEventTypeString(eventType)
1351                     + ", expected " + getEventTypeString(XMLStreamConstants.START_ELEMENT)
1352                     + " or " + getEventTypeString(XMLStreamConstants.END_ELEMENT),
1353                     getLocation());
1354         }
1355 
1356         return eventType;
1357     }
1358 
1359     /**
1360      * Checks if standalone was set in the document
1361      *
1362      * @return true if standalone was set in the document, or false otherwise
1363      */
1364     public boolean standaloneSet() {
1365         //xxx: it requires if the standalone was set in the document ? This is different that if the document
1366         // is standalone
1367         return fScanner.standaloneSet();
1368     }
1369 
1370     /**
1371      * @param qname
1372      * @return
1373      */
1374     public javax.xml.namespace.QName convertXNIQNametoJavaxQName(
1375             com.sun.org.apache.xerces.internal.xni.QName qname) {
1376         if (qname == null) {
1377             return null;
1378         }
1379         //xxx: prefix definition ?
1380         if (qname.prefix == null) {
1381             return new javax.xml.namespace.QName(qname.uri, qname.localpart);
1382         } else {
1383             return new javax.xml.namespace.QName(qname.uri, qname.localpart, qname.prefix);
1384         }
1385     }
1386 
1387     /**
1388      * Return the uri for the given prefix. The uri returned depends on the
1389      * current state of the processor.
1390      *
1391      * <p>
1392      * <strong>NOTE:</strong>The 'xml' prefix is bound as defined in
1393      * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in
1394      * XML</a>
1395      * specification to "http://www.w3.org/XML/1998/namespace".
1396      *
1397      * <p>
1398      * <strong>NOTE:</strong> The 'xmlns' prefix must be resolved to following
1399      * namespace
1400      * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
1401      *
1402      * @return the uri bound to the given prefix or null if it is not bound
1403      * @param prefix The prefix to lookup, may not be null
1404      * @throws IllegalStateException - if the prefix is null
1405      */
1406     public String getNamespaceURI(String prefix) {
1407         if (prefix == null) {
1408             throw new java.lang.IllegalArgumentException("prefix cannot be null.");
1409         }
1410 
1411         //first add the string to symbol table.. since internally identity comparisons are done.
1412         return fScanner.getNamespaceContext().getURI(fSymbolTable.addSymbol(prefix));
1413     }
1414 
1415     //xxx: this function is not being used.
1416     protected void setPropertyManager(PropertyManager propertyManager) {
1417         fPropertyManager = propertyManager;
1418         //REVISIT: we were supplying hashmap ealier
1419         fScanner.setProperty("stax-properties", propertyManager);
1420         fScanner.setPropertyManager(propertyManager);
1421     }
1422 
1423     /**
1424      * @return returns the reference to property manager.
1425      */
1426     protected PropertyManager getPropertyManager() {
1427         return fPropertyManager;
1428     }
1429 
1430     static void pr(String str) {
1431         System.out.println(str);
1432     }
1433 
1434     protected List<EntityDeclaration> getEntityDecls() {
1435         if (fEventType == XMLStreamConstants.DTD) {
1436             XMLEntityStorage entityStore = fEntityManager.getEntityStore();
1437             ArrayList<EntityDeclaration> list = null;
1438             Map<String, Entity> entities = entityStore.getEntities();
1439             if (entities.size() > 0) {
1440                 EntityDeclarationImpl decl = null;
1441                 list = new ArrayList<>(entities.size());
1442                 for (Map.Entry<String, Entity> entry : entities.entrySet()) {
1443                     String key = entry.getKey();
1444                     Entity en = entry.getValue();

1445                     decl = new EntityDeclarationImpl();
1446                     decl.setEntityName(key);
1447                     if (en.isExternal()) {
1448                         decl.setXMLResourceIdentifier(((Entity.ExternalEntity) en).entityLocation);
1449                         decl.setNotationName(((Entity.ExternalEntity) en).notation);
1450                     } else {
1451                         decl.setEntityReplacementText(((Entity.InternalEntity) en).text);
1452                     }


1453                     list.add(decl);
1454                 }
1455             }
1456             return list;
1457         }
1458         return null;
1459     }
1460 
1461     protected List<NotationDeclaration> getNotationDecls() {
1462         if (fEventType == XMLStreamConstants.DTD) {
1463             if (fScanner.fDTDScanner == null) {
1464                 return null;
1465             }
1466             DTDGrammar grammar = ((XMLDTDScannerImpl) (fScanner.fDTDScanner)).getGrammar();
1467             if (grammar == null) {
1468                 return null;
1469             }
1470             List<XMLNotationDecl> notations = grammar.getNotationDecls();
1471             ArrayList<NotationDeclaration> list = new ArrayList<>();
1472             for (XMLNotationDecl notation : notations) {
1473                 if (notation != null) {
1474                     list.add(new NotationDeclarationImpl(notation));
1475                 }
1476             }
1477             return list;
1478         }
1479         return null;
1480     }


1481 
1482 }//XMLReaderImpl
< prev index next >