XMLStreamReaderImpl.java revision 798:00fa5efc9ace
1/* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 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 26package com.sun.org.apache.xerces.internal.impl; 27 28import com.sun.xml.internal.stream.Entity; 29import com.sun.xml.internal.stream.StaxErrorReporter; 30import com.sun.xml.internal.stream.XMLEntityStorage; 31import com.sun.xml.internal.stream.events.EntityDeclarationImpl; 32import com.sun.xml.internal.stream.events.NotationDeclarationImpl; 33import javax.xml.namespace.NamespaceContext; 34import com.sun.org.apache.xerces.internal.xni.XNIException; 35import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 36import javax.xml.XMLConstants; 37import javax.xml.namespace.QName; 38import javax.xml.stream.Location; 39import javax.xml.stream.events.XMLEvent; 40import com.sun.org.apache.xerces.internal.util.NamespaceContextWrapper; 41import com.sun.org.apache.xerces.internal.util.SymbolTable; 42import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl; 43import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar; 44import java.io.BufferedInputStream; 45import java.io.BufferedReader; 46import java.io.IOException; 47import java.io.InputStream; 48import java.io.Reader; 49import java.util.ArrayList; 50import java.util.Enumeration; 51import java.util.Iterator; 52import java.util.List; 53import javax.xml.stream.XMLInputFactory; 54import javax.xml.stream.XMLStreamConstants; 55import javax.xml.stream.XMLStreamException; 56import com.sun.org.apache.xerces.internal.util.XMLChar; 57import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; 58import com.sun.org.apache.xerces.internal.util.NamespaceSupport; 59import 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 */ 69public 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); 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 = (XMLEntityScanner)fEntityManager.getEntityScanner() ; 611 fEntityManager.fCurrentEntity.mayReadChunks = true; 612 fScanner.setScannerState(XMLEvent.START_DOCUMENT); 613 614 fScanner.fEntityDepth = oldEntityDepth; 615 fScanner.fNamespaceContext = oldNamespaceContext; 616 fEventType = fScanner.next(); 617 } 618 619 620 621 final static String getEventTypeString(int eventType) { 622 switch (eventType){ 623 case XMLEvent.START_ELEMENT: 624 return "START_ELEMENT"; 625 case XMLEvent.END_ELEMENT: 626 return "END_ELEMENT"; 627 case XMLEvent.PROCESSING_INSTRUCTION: 628 return "PROCESSING_INSTRUCTION"; 629 case XMLEvent.CHARACTERS: 630 return "CHARACTERS"; 631 case XMLEvent.COMMENT: 632 return "COMMENT"; 633 case XMLEvent.START_DOCUMENT: 634 return "START_DOCUMENT"; 635 case XMLEvent.END_DOCUMENT: 636 return "END_DOCUMENT"; 637 case XMLEvent.ENTITY_REFERENCE: 638 return "ENTITY_REFERENCE"; 639 case XMLEvent.ATTRIBUTE: 640 return "ATTRIBUTE"; 641 case XMLEvent.DTD: 642 return "DTD"; 643 case XMLEvent.CDATA: 644 return "CDATA"; 645 case XMLEvent.SPACE: 646 return "SPACE"; 647 } 648 return "UNKNOWN_EVENT_TYPE, " + String.valueOf(eventType); 649 } 650 651 /** Returns the count of attributes on this START_ELEMENT, 652 * this method is only valid on a START_ELEMENT or ATTRIBUTE. This 653 * count excludes namespace definitions. Attribute indices are 654 * zero-based. 655 * @return returns the number of attributes 656 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 657 */ 658 public int getAttributeCount() { 659 //xxx: recognize SAX properties namespace, namespace-prefix to get XML Namespace declarations 660 //does length includes namespace declarations ? 661 662 //State should be either START_ELEMENT or ATTRIBUTE 663 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 664 return fScanner.getAttributeIterator().getLength() ; 665 } else{ 666 throw new java.lang.IllegalStateException( "Current state is not among the states " 667 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 668 + getEventTypeString(XMLEvent.ATTRIBUTE) 669 + "valid for getAttributeCount()") ; 670 } 671 }//getAttributeCount 672 673 /** Returns the localName of the attribute at the provided 674 * index 675 * @param index the position of the attribute 676 * @return the localName of the attribute 677 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 678 */ 679 public QName getAttributeName(int index) { 680 //State should be either START_ELEMENT or ATTRIBUTE 681 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 682 return convertXNIQNametoJavaxQName(fScanner.getAttributeIterator().getQualifiedName(index)) ; 683 } else{ 684 throw new java.lang.IllegalStateException("Current state is not among the states " 685 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 686 + getEventTypeString(XMLEvent.ATTRIBUTE) 687 + "valid for getAttributeName()") ; 688 } 689 }//getAttributeName 690 691 /** 692 * @param index 693 * @return 694 */ 695 public String getAttributeLocalName(int index) { 696 //State should be either START_ELEMENT or ATTRIBUTE 697 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 698 return fScanner.getAttributeIterator().getLocalName(index) ; 699 } else{ 700 throw new java.lang.IllegalStateException() ; 701 } 702 }//getAttributeName 703 704 /** Returns the namespace of the attribute at the provided 705 * index 706 * @param index the position of the attribute 707 * @return the namespace URI (can be null) 708 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 709 */ 710 public String getAttributeNamespace(int index) { 711 //State should be either START_ELEMENT or ATTRIBUTE 712 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 713 return fScanner.getAttributeIterator().getURI(index); 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 getAttributeNamespace()") ; 719 } 720 721 }//getAttributeNamespace 722 723 /** Returns the prefix of this attribute at the 724 * provided index 725 * @param index the position of the attribute 726 * @return the prefix of the attribute 727 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 728 */ 729 public String getAttributePrefix(int index) { 730 //State should be either START_ELEMENT or ATTRIBUTE 731 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 732 return fScanner.getAttributeIterator().getPrefix(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 getAttributePrefix()") ; 738 } 739 }//getAttributePrefix 740 741 /** Returns the qname of the attribute at the provided index 742 * 743 * @param index the position of the attribute 744 * @return the QName of the attribute 745 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 746 */ 747 public javax.xml.namespace.QName getAttributeQName(int index) { 748 //State should be either START_ELEMENT or ATTRIBUTE 749 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 750 // create new object at runtime.. 751 String localName = fScanner.getAttributeIterator().getLocalName(index) ; 752 String uri = fScanner.getAttributeIterator().getURI(index) ; 753 return new javax.xml.namespace.QName(uri, localName) ; 754 } else{ 755 throw new java.lang.IllegalStateException("Current state is not among the states " 756 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 757 + getEventTypeString(XMLEvent.ATTRIBUTE) 758 + "valid for getAttributeQName()") ; 759 } 760 }//getAttributeQName 761 762 /** Returns the XML type of the attribute at the provided 763 * index 764 * @param index the position of the attribute 765 * @return the XML type of the attribute 766 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 767 */ 768 public String getAttributeType(int index) { 769 //State should be either START_ELEMENT or ATTRIBUTE 770 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 771 return fScanner.getAttributeIterator().getType(index) ; 772 } else{ 773 throw new java.lang.IllegalStateException("Current state is not among the states " 774 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 775 + getEventTypeString(XMLEvent.ATTRIBUTE) 776 + "valid for getAttributeType()") ; 777 } 778 779 }//getAttributeType 780 781 /** Returns the value of the attribute at the 782 * index 783 * @param index the position of the attribute 784 * @return the attribute value 785 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 786 */ 787 public String getAttributeValue(int index) { 788 //State should be either START_ELEMENT or ATTRIBUTE 789 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 790 return fScanner.getAttributeIterator().getValue(index) ; 791 } else{ 792 throw new java.lang.IllegalStateException("Current state is not among the states " 793 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 794 + getEventTypeString(XMLEvent.ATTRIBUTE) 795 + "valid for getAttributeValue()") ; 796 } 797 798 }//getAttributeValue 799 800 /** 801 * @param namespaceURI 802 * @param localName 803 * @return 804 */ 805 public String getAttributeValue(String namespaceURI, String localName) { 806 //State should be either START_ELEMENT or ATTRIBUTE 807 if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { 808 XMLAttributesImpl attributes = fScanner.getAttributeIterator(); 809 if (namespaceURI == null) { //sjsxp issue 70 810 return attributes.getValue(attributes.getIndexByLocalName(localName)) ; 811 } else { 812 return fScanner.getAttributeIterator().getValue( 813 namespaceURI.length() == 0 ? null : namespaceURI, localName) ; 814 } 815 816 } else{ 817 throw new java.lang.IllegalStateException("Current state is not among the states " 818 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 819 + getEventTypeString(XMLEvent.ATTRIBUTE) 820 + "valid for getAttributeValue()") ; 821 } 822 823 } 824 825 /** Reads the content of a text-only element. Precondition: 826 * the current event is START_ELEMENT. Postcondition: 827 * The current event is the corresponding END_ELEMENT. 828 * @throws XMLStreamException if the current event is not a START_ELEMENT or if 829 * a non text element is encountered 830 */ 831 public String getElementText() throws XMLStreamException { 832 833 if(getEventType() != XMLStreamConstants.START_ELEMENT) { 834 throw new XMLStreamException( 835 "parser must be on START_ELEMENT to read next text", getLocation()); 836 } 837 int eventType = next(); 838 StringBuffer content = new StringBuffer(); 839 while(eventType != XMLStreamConstants.END_ELEMENT ) { 840 if(eventType == XMLStreamConstants.CHARACTERS 841 || eventType == XMLStreamConstants.CDATA 842 || eventType == XMLStreamConstants.SPACE 843 || eventType == XMLStreamConstants.ENTITY_REFERENCE) { 844 content.append(getText()); 845 } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION 846 || eventType == XMLStreamConstants.COMMENT) { 847 // skipping 848 } else if(eventType == XMLStreamConstants.END_DOCUMENT) { 849 throw new XMLStreamException("unexpected end of document when reading element text content"); 850 } else if(eventType == XMLStreamConstants.START_ELEMENT) { 851 throw new XMLStreamException( 852 "elementGetText() function expects text only elment but START_ELEMENT was encountered.", getLocation()); 853 } else { 854 throw new XMLStreamException( 855 "Unexpected event type "+ eventType, getLocation()); 856 } 857 eventType = next(); 858 } 859 return content.toString(); 860 } 861 862 /** Return the current location of the processor. 863 * If the Location is unknown the processor should return 864 * an implementation of Location that returns -1 for the 865 * location and null for the publicId and systemId. 866 * The location information is only valid until next() is 867 * called. 868 */ 869 public Location getLocation() { 870 return new Location() { 871 String _systemId = fEntityScanner.getExpandedSystemId(); 872 String _publicId = fEntityScanner.getPublicId(); 873 int _offset = fEntityScanner.getCharacterOffset(); 874 int _columnNumber = fEntityScanner.getColumnNumber(); 875 int _lineNumber = fEntityScanner.getLineNumber(); 876 public String getLocationURI(){ 877 return _systemId; 878 } 879 880 public int getCharacterOffset(){ 881 return _offset; 882 } 883 884 public int getColumnNumber() { 885 return _columnNumber; 886 } 887 888 public int getLineNumber(){ 889 return _lineNumber; 890 } 891 892 public String getPublicId(){ 893 return _publicId; 894 } 895 896 public String getSystemId(){ 897 return _systemId; 898 } 899 900 public String toString(){ 901 StringBuffer sbuffer = new StringBuffer() ; 902 sbuffer.append("Line number = " + getLineNumber()); 903 sbuffer.append("\n") ; 904 sbuffer.append("Column number = " + getColumnNumber()); 905 sbuffer.append("\n") ; 906 sbuffer.append("System Id = " + getSystemId()); 907 sbuffer.append("\n") ; 908 sbuffer.append("Public Id = " + getPublicId()); 909 sbuffer.append("\n") ; 910 sbuffer.append("Location Uri= " + getLocationURI()); 911 sbuffer.append("\n") ; 912 sbuffer.append("CharacterOffset = " + getCharacterOffset()); 913 sbuffer.append("\n") ; 914 return sbuffer.toString(); 915 } 916 } ; 917 918 } 919 920 /** Returns a QName for the current START_ELEMENT or END_ELEMENT event 921 * @return the QName for the current START_ELEMENT or END_ELEMENT event 922 */ 923 public javax.xml.namespace.QName getName() { 924 if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT) 925 return convertXNIQNametoJavaxQName(fScanner.getElementQName()); 926 else 927 throw new java.lang.IllegalStateException("Illegal to call getName() "+ 928 "when event type is "+ getEventTypeString(fEventType) + "." 929 + " Valid states are " + getEventTypeString(XMLEvent.START_ELEMENT) + ", " 930 + getEventTypeString(XMLEvent.END_ELEMENT)); 931 } 932 933 /** Returns a read only namespace context for the current 934 * position. The context is transient and only valid until 935 * a call to next() changes the state of the reader. 936 * @return return a namespace context 937 */ 938 public NamespaceContext getNamespaceContext() { 939 return fNamespaceContextWrapper ; 940 } 941 942 /** Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT, 943 * this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE. On 944 * an END_ELEMENT the count is of the namespaces that are about to go 945 * out of scope. This is the equivalent of the information reported 946 * by SAX callback for an end element event. 947 * @return returns the number of namespace declarations on this specific element 948 * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE 949 */ 950 public int getNamespaceCount() { 951 //namespaceContext is dynamic object. 952 //REVISIT: check if it specifies all conditions mentioned in the javadoc 953 if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){ 954 return fScanner.getNamespaceContext().getDeclaredPrefixCount() ; 955 } else{ 956 throw new IllegalStateException("Current event state is " + getEventTypeString(fEventType) 957 + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT) 958 + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", " 959 + getEventTypeString(XMLEvent.NAMESPACE) 960 + " valid for getNamespaceCount()." ); 961 } 962 } 963 964 /** Returns the prefix for the namespace declared at the 965 * index. Returns null if this is the default namespace 966 * declaration 967 * 968 * @param index the position of the namespace declaration 969 * @return returns the namespace prefix 970 * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE 971 */ 972 public String getNamespacePrefix(int index) { 973 if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){ 974 //namespaceContext is dynamic object. 975 String prefix = fScanner.getNamespaceContext().getDeclaredPrefixAt(index) ; 976 return prefix.equals("") ? null : prefix ; 977 } 978 else{ 979 throw new IllegalStateException("Current state " + getEventTypeString(fEventType) 980 + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT) 981 + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", " 982 + getEventTypeString(XMLEvent.NAMESPACE) 983 + " valid for getNamespacePrefix()." ); 984 } 985 } 986 987 /** Returns the uri for the namespace declared at the 988 * index. 989 * 990 * @param index the position of the namespace declaration 991 * @return returns the namespace uri 992 * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE 993 */ 994 public String getNamespaceURI(int index) { 995 if(fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.END_ELEMENT || fEventType == XMLEvent.NAMESPACE){ 996 //namespaceContext is dynamic object. 997 return fScanner.getNamespaceContext().getURI(fScanner.getNamespaceContext().getDeclaredPrefixAt(index)); 998 } 999 else{ 1000 throw new IllegalStateException("Current state " + getEventTypeString(fEventType) 1001 + " is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT) 1002 + ", " + getEventTypeString(XMLEvent.END_ELEMENT) + ", " 1003 + getEventTypeString(XMLEvent.NAMESPACE) 1004 + " valid for getNamespaceURI()." ); 1005 } 1006 1007 } 1008 1009 /** Get the value of a feature/property from the underlying implementation 1010 * @param name The name of the property, may not be null 1011 * @return The value of the property 1012 * @throws IllegalArgumentException if name is null 1013 */ 1014 public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException { 1015 if(name == null) throw new java.lang.IllegalArgumentException() ; 1016 if (fPropertyManager != null ){ 1017 if(name.equals(fPropertyManager.STAX_NOTATIONS)){ 1018 return getNotationDecls(); 1019 }else if(name.equals(fPropertyManager.STAX_ENTITIES)){ 1020 return getEntityDecls(); 1021 }else 1022 return fPropertyManager.getProperty(name); 1023 } 1024 return null; 1025 } 1026 1027 /** Returns the current value of the parse event as a string, 1028 * this returns the string value of a CHARACTERS event, 1029 * returns the value of a COMMENT, the replacement value 1030 * for an ENTITY_REFERENCE, 1031 * or the String value of the DTD 1032 * @return the current text or null 1033 * @throws java.lang.IllegalStateException if this state is not 1034 * a valid text state. 1035 */ 1036 public String getText() { 1037 if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT 1038 || fEventType == XMLEvent.CDATA || fEventType == XMLEvent.SPACE){ 1039 //this requires creation of new string 1040 //fEventType == XMLEvent.ENTITY_REFERENCE 1041 return fScanner.getCharacterData().toString() ; 1042 } else if(fEventType == XMLEvent.ENTITY_REFERENCE){ 1043 String name = fScanner.getEntityName(); 1044 if(name != null){ 1045 if(fScanner.foundBuiltInRefs) 1046 return fScanner.getCharacterData().toString(); 1047 1048 XMLEntityStorage entityStore = fEntityManager.getEntityStore(); 1049 Entity en = entityStore.getEntity(name); 1050 if(en == null) 1051 return null; 1052 if(en.isExternal()) 1053 return ((Entity.ExternalEntity)en).entityLocation.getExpandedSystemId(); 1054 else 1055 return ((Entity.InternalEntity)en).text; 1056 }else 1057 return null; 1058 } 1059 else if(fEventType == XMLEvent.DTD){ 1060 if(fDTDDecl != null){ 1061 return fDTDDecl; 1062 } 1063 XMLStringBuffer tmpBuffer = fScanner.getDTDDecl(); 1064 fDTDDecl = tmpBuffer.toString(); 1065 return fDTDDecl; 1066 } else{ 1067 throw new IllegalStateException("Current state " + getEventTypeString(fEventType) 1068 + " is not among the states" + getEventTypeString(XMLEvent.CHARACTERS) + ", " 1069 + getEventTypeString(XMLEvent.COMMENT) + ", " 1070 + getEventTypeString(XMLEvent.CDATA) + ", " 1071 + getEventTypeString(XMLEvent.SPACE) + ", " 1072 + getEventTypeString(XMLEvent.ENTITY_REFERENCE) + ", " 1073 + getEventTypeString(XMLEvent.DTD) + " valid for getText() " ) ; 1074 } 1075 }//getText 1076 1077 1078 /** 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. 1079 * If the namespaceURI is null it is not checked for equality, if the localName is null it is not checked for equality. 1080 * @param type the event type 1081 * @param namespaceURI the uri of the event, may be null 1082 * @param localName the localName of the event, may be null 1083 * @throws XMLStreamException if the required values are not matched. 1084 */ 1085 public void require(int type, String namespaceURI, String localName) throws XMLStreamException { 1086 if( type != fEventType) 1087 throw new XMLStreamException("Event type " + getEventTypeString(type) + " specified did " + 1088 "not match with current parser event " + getEventTypeString(fEventType)); 1089 if( namespaceURI != null && !namespaceURI.equals(getNamespaceURI()) ) 1090 throw new XMLStreamException("Namespace URI " + namespaceURI +" specified did not match " + 1091 "with current namespace URI"); 1092 if(localName != null && !localName.equals(getLocalName())) 1093 throw new XMLStreamException("LocalName " + localName +" specified did not match with " + 1094 "current local name"); 1095 return; 1096 } 1097 1098 /** Gets the the text associated with a CHARACTERS, SPACE or CDATA event. 1099 * Text starting a "sourceStart" is copied into "destination" starting at "targetStart". 1100 * Up to "length" characters are copied. The number of characters actually copied is returned. 1101 * 1102 * The "sourceStart" argument must be greater or equal to 0 and less than or equal to 1103 * the number of characters associated with the event. Usually, one requests text starting at a "sourceStart" of 0. 1104 * If the number of characters actually copied is less than the "length", then there is no more text. 1105 * Otherwise, subsequent calls need to be made until all text has been retrieved. For example: 1106 * 1107 * <code> 1108 * int length = 1024; 1109 * char[] myBuffer = new char[ length ]; 1110 * 1111 * for ( int sourceStart = 0 ; ; sourceStart += length ) 1112 * { 1113 * int nCopied = stream.getTextCharacters( sourceStart, myBuffer, 0, length ); 1114 * 1115 * if (nCopied < length) 1116 * break; 1117 * } 1118 * </code> 1119 * XMLStreamException may be thrown if there are any XML errors in the underlying source. 1120 * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target", 1121 * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target". 1122 * 1123 * @param sourceStart the index of the first character in the source array to copy 1124 * @param target the destination array 1125 * @param targetStart the start offset in the target array 1126 * @param length the number of characters to copy 1127 * @return the number of characters actually copied 1128 * @throws XMLStreamException if the underlying XML source is not well-formed 1129 * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target 1130 * @throws IndexOutOfBoundwhile(isCharacters()) ;sException if length < 0 or targetStart + length > length of target 1131 * @throws UnsupportedOperationException if this method is not supported 1132 * @throws NullPointerException is if target is null 1133 */ 1134 public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { 1135 1136 if(target == null){ 1137 throw new NullPointerException("target char array can't be null") ; 1138 } 1139 1140 if(targetStart < 0 || length < 0 || sourceStart < 0 || targetStart >= target.length || 1141 (targetStart + length ) > target.length) { 1142 throw new IndexOutOfBoundsException(); 1143 } 1144 1145 //getTextStart() + sourceStart should not be greater than the lenght of number of characters 1146 //present 1147 int copiedLength = 0; 1148 //int presentDataLen = getTextLength() - (getTextStart()+sourceStart); 1149 int available = getTextLength() - sourceStart; 1150 if(available < 0){ 1151 throw new IndexOutOfBoundsException("sourceStart is greater than" + 1152 "number of characters associated with this event"); 1153 } 1154 if(available < length){ 1155 copiedLength = available; 1156 } else{ 1157 copiedLength = length; 1158 } 1159 1160 System.arraycopy(getTextCharacters(), getTextStart() + sourceStart , target, targetStart, copiedLength); 1161 return copiedLength; 1162 } 1163 1164 /** Return true if the current event has text, false otherwise 1165 * The following events have text: 1166 * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT 1167 */ 1168 public boolean hasText() { 1169 if(DEBUG) pr("XMLReaderImpl#EVENT TYPE = " + fEventType ) ; 1170 if( fEventType == XMLEvent.CHARACTERS || fEventType == XMLEvent.COMMENT || fEventType == XMLEvent.CDATA) { 1171 return fScanner.getCharacterData().length > 0; 1172 } else if(fEventType == XMLEvent.ENTITY_REFERENCE) { 1173 String name = fScanner.getEntityName(); 1174 if(name != null){ 1175 if(fScanner.foundBuiltInRefs) 1176 return true; 1177 1178 XMLEntityStorage entityStore = fEntityManager.getEntityStore(); 1179 Entity en = entityStore.getEntity(name); 1180 if(en == null) 1181 return false; 1182 if(en.isExternal()){ 1183 return ((Entity.ExternalEntity)en).entityLocation.getExpandedSystemId() != null; 1184 } else{ 1185 return ((Entity.InternalEntity)en).text != null ; 1186 } 1187 }else 1188 return false; 1189 } else { 1190 if(fEventType == XMLEvent.DTD) 1191 return fScanner.fSeenDoctypeDecl; 1192 } 1193 return false; 1194 } 1195 1196 /** Returns a boolean which indicates if this 1197 * attribute was created by default 1198 * @param index the position of the attribute 1199 * @return true if this is a default attribute 1200 * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE 1201 */ 1202 public boolean isAttributeSpecified(int index) { 1203 //check that current state should be either START_ELEMENT or ATTRIBUTE 1204 if( (fEventType == XMLEvent.START_ELEMENT) || (fEventType == XMLEvent.ATTRIBUTE)){ 1205 return fScanner.getAttributeIterator().isSpecified(index) ; 1206 } else{ 1207 throw new IllegalStateException("Current state is not among the states " 1208 + getEventTypeString(XMLEvent.START_ELEMENT) + " , " 1209 + getEventTypeString(XMLEvent.ATTRIBUTE) 1210 + "valid for isAttributeSpecified()") ; 1211 } 1212 } 1213 1214 /** Returns true if the cursor points to a character data event 1215 * @return true if the cursor points to character data, false otherwise 1216 */ 1217 public boolean isCharacters() { 1218 return fEventType == XMLEvent.CHARACTERS ; 1219 } 1220 1221 /** Skips any insignificant events (COMMENT and PROCESSING_INSTRUCTION) 1222 * until a START_ELEMENT or 1223 * END_ELEMENT is reached. If other than space characters are 1224 * encountered, an exception is thrown. This method should 1225 * be used when processing element-only content because 1226 * the parser is not able to recognize ignorable whitespace if 1227 * then DTD is missing or not interpreted. 1228 * @return the event type of the element read 1229 * @throws XMLStreamException if the current event is not white space 1230 */ 1231 public int nextTag() throws XMLStreamException { 1232 1233 int eventType = next(); 1234 while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace 1235 || (eventType == XMLStreamConstants.CDATA && isWhiteSpace()) 1236 // skip whitespace 1237 || eventType == XMLStreamConstants.SPACE 1238 || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION 1239 || eventType == XMLStreamConstants.COMMENT 1240 ) { 1241 eventType = next(); 1242 } 1243 1244 if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) { 1245 throw new XMLStreamException( 1246 "found: " + getEventTypeString(eventType) 1247 + ", expected " + getEventTypeString(XMLStreamConstants.START_ELEMENT) 1248 + " or " + getEventTypeString(XMLStreamConstants.END_ELEMENT), 1249 getLocation()); 1250 } 1251 1252 return eventType; 1253 } 1254 1255 /** Checks if standalone was set in the document 1256 * @return true if standalone was set in the document, or false otherwise 1257 */ 1258 public boolean standaloneSet() { 1259 //xxx: it requires if the standalone was set in the document ? This is different that if the document 1260 // is standalone 1261 return fScanner.standaloneSet() ; 1262 } 1263 1264 /** 1265 * @param qname 1266 * @return 1267 */ 1268 public javax.xml.namespace.QName convertXNIQNametoJavaxQName(com.sun.org.apache.xerces.internal.xni.QName qname){ 1269 if (qname == null) return null; 1270 //xxx: prefix definition ? 1271 if(qname.prefix == null){ 1272 return new javax.xml.namespace.QName(qname.uri, qname.localpart) ; 1273 } else{ 1274 return new javax.xml.namespace.QName(qname.uri, qname.localpart, qname.prefix) ; 1275 } 1276 } 1277 1278 /** Return the uri for the given prefix. 1279 * The uri returned depends on the current state of the processor. 1280 * 1281 * <p><strong>NOTE:</strong>The 'xml' prefix is bound as defined in 1282 * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a> 1283 * specification to "http://www.w3.org/XML/1998/namespace". 1284 * 1285 * <p><strong>NOTE:</strong> The 'xmlns' prefix must be resolved to following namespace 1286 * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a> 1287 * @return the uri bound to the given prefix or null if it is not bound 1288 * @param prefix The prefix to lookup, may not be null 1289 * @throws IllegalStateException - if the prefix is null 1290 */ 1291 public String getNamespaceURI(String prefix) { 1292 if(prefix == null) throw new java.lang.IllegalArgumentException("prefix cannot be null.") ; 1293 1294 //first add the string to symbol table.. since internally identity comparisons are done. 1295 return fScanner.getNamespaceContext().getURI(fSymbolTable.addSymbol(prefix)) ; 1296 } 1297 1298 //xxx: this function is not being used. 1299 protected void setPropertyManager(PropertyManager propertyManager){ 1300 fPropertyManager = propertyManager ; 1301 //REVISIT: we were supplying hashmap ealier 1302 fScanner.setProperty("stax-properties",propertyManager); 1303 fScanner.setPropertyManager(propertyManager) ; 1304 } 1305 1306 /** 1307 * @return returns the reference to property manager. 1308 */ 1309 protected PropertyManager getPropertyManager(){ 1310 return fPropertyManager ; 1311 } 1312 1313 static void pr(String str) { 1314 System.out.println(str) ; 1315 } 1316 1317 protected List getEntityDecls(){ 1318 if(fEventType == XMLStreamConstants.DTD){ 1319 XMLEntityStorage entityStore = fEntityManager.getEntityStore(); 1320 ArrayList list = null; 1321 if(entityStore.hasEntities()){ 1322 EntityDeclarationImpl decl = null; 1323 list = new ArrayList(entityStore.getEntitySize()); 1324 Enumeration enu = entityStore.getEntityKeys(); 1325 while(enu.hasMoreElements()){ 1326 String key = (String)enu.nextElement(); 1327 Entity en = (Entity)entityStore.getEntity(key); 1328 decl = new EntityDeclarationImpl(); 1329 decl.setEntityName(key); 1330 if(en.isExternal()){ 1331 decl.setXMLResourceIdentifier(((Entity.ExternalEntity)en).entityLocation); 1332 decl.setNotationName(((Entity.ExternalEntity)en).notation); 1333 } 1334 else 1335 decl.setEntityReplacementText(((Entity.InternalEntity)en).text); 1336 list.add(decl); 1337 } 1338 } 1339 return list; 1340 } 1341 return null; 1342 } 1343 1344 protected List getNotationDecls(){ 1345 if(fEventType == XMLStreamConstants.DTD){ 1346 if(fScanner.fDTDScanner == null) return null; 1347 DTDGrammar grammar = ((XMLDTDScannerImpl)(fScanner.fDTDScanner)).getGrammar(); 1348 if(grammar == null) return null; 1349 List notations = grammar.getNotationDecls(); 1350 1351 Iterator it = notations.iterator(); 1352 ArrayList list = new ArrayList(); 1353 while(it.hasNext()){ 1354 XMLNotationDecl ni = (XMLNotationDecl)it.next(); 1355 if(ni!= null){ 1356 list.add(new NotationDeclarationImpl(ni)); 1357 } 1358 } 1359 return list; 1360 } 1361 return null; 1362 } 1363 1364 1365 1366}//XMLReaderImpl 1367