1 28 29 package com.caucho.quercus.lib.xml; 30 31 import com.caucho.quercus.annotation.Optional; 32 import com.caucho.quercus.env.BooleanValue; 33 import com.caucho.quercus.env.Env; 34 import com.caucho.quercus.env.LongValue; 35 import com.caucho.quercus.env.NullValue; 36 import com.caucho.quercus.env.StringValue; 37 import com.caucho.quercus.env.Value; 38 import com.caucho.util.L10N; 39 import com.caucho.vfs.Path; 40 41 import javax.xml.stream.*; 42 import java.io.IOException ; 43 import java.util.HashMap ; 44 import java.util.logging.Level ; 45 import java.util.logging.Logger ; 46 47 public class XmlReader 48 { 49 private static final Logger log 50 = Logger.getLogger(XmlReader.class.getName()); 51 private static final L10N L = new L10N(XmlReader.class); 52 53 private int _depth; 54 private int _lastNodeType; 55 private int _lastNonTextNode; 56 57 private int _currentNodeType; 58 59 private boolean _hasAttribute; 60 61 private XMLStreamReader _streamReader; 62 63 private static final HashMap <Integer , Integer > _constConvertMap 64 = new HashMap <Integer , Integer >(); 65 66 private HashMap <String , Integer > _startElements; 67 68 public static final int NONE = 0; 69 public static final int ELEMENT = 1; 70 public static final int ATTRIBUTE = 2; 71 public static final int TEXT = 3; 72 public static final int CDATA = 4; 73 public static final int ENTITY_REF = 5; 74 public static final int ENTITY = 6; 75 public static final int PI = 7; 76 public static final int COMMENT = 8; 77 public static final int DOC = 9; 78 public static final int DOC_TYPE = 10; 79 public static final int DOC_FRAGMENT = 11; 80 public static final int NOTATION = 12; 81 public static final int WHITESPACE = 13; 82 public static final int SIGNIFICANT_WHITESPACE = 14; 83 public static final int END_ELEMENT = 15; 84 public static final int END_ENTITY = 16; 85 public static final int XML_DECLARATION = 17; 86 87 public static final int LOADDTD = 1; 88 public static final int DEFAULTATTRS = 2; 89 public static final int VALIDATE = 3; 90 public static final int SUBST_ENTITIES = 4; 91 92 99 public XmlReader(@Optional String [] string) { 100 _depth = 0; 101 _lastNodeType = -1; 102 _currentNodeType = XMLStreamConstants.START_DOCUMENT; 103 104 _streamReader = null; 105 106 _startElements = new HashMap <String , Integer >(); 107 108 _hasAttribute = false; 109 } 110 111 118 private boolean streamIsOpen(Env env, String operation) { 119 if (! streamIsOpen()) { 120 env.warning(L.l("Load Data before trying to " + operation)); 121 122 return false; 123 } 124 125 return true; 126 } 127 128 133 private boolean streamIsOpen() { 134 return _streamReader != null; 135 } 136 137 142 public Value getAttributeCount() { 143 if (! streamIsOpen()) 144 return NullValue.NULL; 145 146 try { 147 if (_currentNodeType == XMLStreamConstants.CHARACTERS) 148 return LongValue.create(0); 149 150 return LongValue.create(_streamReader.getAttributeCount()); 151 } 152 catch (IllegalStateException ex) { 153 log.log(Level.WARNING, ex.toString(), ex); 154 155 return NullValue.NULL; 156 } 157 } 158 159 164 public Value getBaseURI() { 165 if (! streamIsOpen()) 166 return NullValue.NULL; 167 168 172 174 return NullValue.NULL; 175 } 176 177 182 public Value getDepth() { 183 if (! streamIsOpen()) 184 return NullValue.NULL; 185 186 return LongValue.create(_depth); 187 } 188 189 194 public Value getHasAttributes() { 195 if (! streamIsOpen()) 196 return NullValue.NULL; 197 198 try { 199 if (_currentNodeType == XMLStreamConstants.CHARACTERS) 200 return BooleanValue.FALSE; 201 202 return BooleanValue.create(_hasAttribute || _streamReader.getAttributeCount() > 0); 203 } 204 catch (IllegalStateException ex) { 205 log.log(Level.WARNING, ex.toString(), ex); 206 207 return NullValue.NULL; 208 } 209 } 210 211 216 public Value getHasValue() { 217 if (! streamIsOpen()) 218 return NullValue.NULL; 219 220 return BooleanValue.create(_streamReader.hasText()); 221 } 222 223 228 public Value getIsDefault() { 229 if (! streamIsOpen()) 230 return NullValue.NULL; 231 232 return BooleanValue.FALSE; 236 } 237 238 243 public Value getIsEmptyElement() { 244 if (! streamIsOpen()) 245 return NullValue.NULL; 246 247 return BooleanValue.FALSE; 252 } 253 254 259 public Value getLocalName() { 260 if (! streamIsOpen()) 261 return NullValue.NULL; 262 263 String name = ""; 264 265 if (_currentNodeType == XMLStreamConstants.CHARACTERS) 266 name = "#text"; 267 else if (_currentNodeType == XMLStreamConstants.COMMENT) 268 name = "#comment"; 269 else 270 name = _streamReader.getLocalName(); 271 272 return StringValue.create(name); 273 } 274 275 280 public Value getName(Env env) { 281 if (! streamIsOpen()) 282 return NullValue.NULL; 283 284 try { 285 String name = ""; 286 287 290 String prefix = null; 292 if (_currentNodeType == XMLStreamConstants.CHARACTERS) 293 name = "#text"; 294 else if (_currentNodeType == XMLStreamConstants.COMMENT) 295 name = "#comment"; 296 else { 297 if (prefix == null) 298 name = _streamReader.getName().toString(); 299 else 300 name = prefix + ":" + _streamReader.getLocalName().toString(); 301 } 302 303 return StringValue.create(name); 304 } 305 catch (IllegalStateException ex) { 306 log.log(Level.WARNING, ex.toString(), ex); 307 308 return NullValue.NULL; 309 } 310 } 311 312 317 public Value getNamespaceURI() { 318 if (! streamIsOpen()) 319 return NullValue.NULL; 320 321 return StringValue.create(_streamReader.getNamespaceURI()); 322 } 323 324 329 public Value getNodeType() { 330 if (! streamIsOpen()) 331 return NullValue.NULL; 332 333 339 340 int convertedInt = SIGNIFICANT_WHITESPACE; 341 342 if (! _streamReader.isWhiteSpace()) { 343 Integer convertedInteger = 344 _constConvertMap.get(_streamReader.getEventType()); 345 346 convertedInt = convertedInteger.intValue(); 347 } 348 349 return LongValue.create(convertedInt); 350 } 351 352 357 public Value getPrefix() { 358 if (! streamIsOpen()) 359 return NullValue.NULL; 360 361 return StringValue.create(_streamReader.getPrefix()); 362 } 363 364 369 public Value getValue() { 370 if (! streamIsOpen()) 371 return NullValue.NULL; 372 373 376 if (_currentNodeType != XMLStreamConstants.END_ELEMENT) 377 return StringValue.create(_streamReader.getText()); 378 379 return StringValue.create(null); 380 } 381 382 387 public Value getXmlLang() { 388 if (! streamIsOpen()) 389 return NullValue.NULL; 390 391 return StringValue.create(""); 393 } 394 395 400 public BooleanValue close() { 401 if (! streamIsOpen()) 402 return BooleanValue.TRUE; 403 404 try { 405 _streamReader.close(); 406 } 407 catch (XMLStreamException ex) { 408 log.log(Level.WARNING, ex.toString(), ex); 409 410 return BooleanValue.FALSE; 411 } 412 413 return BooleanValue.TRUE; 414 } 415 416 420 public Value expand() { 421 throw new UnsupportedOperationException (getClass().getName()); 422 } 423 424 429 public StringValue getAttribute(String name) { 430 throw new UnsupportedOperationException (getClass().getName()); 431 } 432 433 438 public StringValue getAttributeNo(int index) { 439 throw new UnsupportedOperationException (getClass().getName()); 440 } 441 442 448 public StringValue getAttributeNS(String localName, String namespaceURI) { 449 throw new UnsupportedOperationException (getClass().getName()); 450 } 451 452 457 public BooleanValue getParserProperty(int property) { 458 throw new UnsupportedOperationException (getClass().getName()); 459 } 460 461 465 public BooleanValue isValid() { 466 throw new UnsupportedOperationException (getClass().getName()); 467 } 468 469 474 public BooleanValue lookupNamespace(String prefix) { 475 throw new UnsupportedOperationException (getClass().getName()); 476 } 477 478 483 public BooleanValue moveToAttribute(String name) { 484 throw new UnsupportedOperationException (getClass().getName()); 485 } 486 487 492 public BooleanValue moveToAttributeNo(int index) { 493 throw new UnsupportedOperationException (getClass().getName()); 494 } 495 496 502 public BooleanValue moveToAttributeNs(String localName, String namespaceURI) { 503 throw new UnsupportedOperationException (getClass().getName()); 504 } 505 506 510 public BooleanValue moveToElement() { 511 throw new UnsupportedOperationException (getClass().getName()); 512 } 513 514 518 public BooleanValue moveToFirstAttribute() { 519 throw new UnsupportedOperationException (getClass().getName()); 520 } 521 522 526 public BooleanValue moveToNextAttribute() { 527 throw new UnsupportedOperationException (getClass().getName()); 528 } 529 530 535 public BooleanValue next(@Optional String localname) { 536 throw new UnsupportedOperationException (getClass().getName()); 537 } 538 539 545 public BooleanValue open(Env env, Path path) { 546 try { 547 XMLInputFactory factory = XMLInputFactory.newInstance(); 548 549 _streamReader = factory.createXMLStreamReader(path.openRead()); 550 } 551 catch (XMLStreamException ex) { 552 log.log(Level.WARNING, ex.toString(), ex); 553 554 env.warning(L.l("Unable to open source data")); 555 556 return BooleanValue.FALSE; 557 } 558 catch (IOException ex) { 559 log.log(Level.WARNING, ex.toString(), ex); 560 561 env.warning(L.l("Unable to open source data")); 562 563 return BooleanValue.FALSE; 564 } 565 566 return BooleanValue.TRUE; 567 } 568 569 573 private void updateLastNode() { 574 _lastNodeType = _currentNodeType; 575 576 if (_currentNodeType != XMLStreamConstants.CHARACTERS && 577 _currentNodeType != XMLStreamConstants.COMMENT) 578 _lastNonTextNode = _currentNodeType; 579 } 580 581 585 private void updateDepth(Env env) { 586 if (_lastNodeType == XMLStreamConstants.START_ELEMENT && 587 ! _streamReader.isEndElement()) 588 _depth++; 589 else if ((_lastNodeType == XMLStreamConstants.CHARACTERS || 590 _lastNodeType == XMLStreamConstants.COMMENT) && 591 _currentNodeType == XMLStreamConstants.END_ELEMENT) 592 _depth--; 593 } 594 595 599 private void updateAttribute(Env env) { 600 _hasAttribute = false; 601 602 String key = getName(env).toString() + _depth; 603 604 if (_currentNodeType == XMLStreamConstants.START_ELEMENT && 605 _streamReader.getAttributeCount() > 0) { 606 _startElements.put(key, _depth); 607 608 _hasAttribute = true; 609 } 610 611 if (_currentNodeType == XMLStreamConstants.END_ELEMENT && 612 _startElements.containsKey(key)) { 613 _hasAttribute = true; 614 615 _startElements.remove(key); 616 } 617 } 618 619 624 public BooleanValue read(Env env) { 625 if (! streamIsOpen(env, "read")) 626 return BooleanValue.FALSE; 627 628 try { 629 if (! _streamReader.hasNext()) 630 return BooleanValue.FALSE; 631 632 updateLastNode(); 633 634 _currentNodeType = _streamReader.next(); 635 636 if (_currentNodeType == XMLStreamConstants.SPACE) 637 return read(env); 638 639 if (_currentNodeType == XMLStreamConstants.END_DOCUMENT) 640 return BooleanValue.FALSE; 641 642 updateDepth(env); 643 644 updateAttribute(env); 645 646 } 647 catch (XMLStreamException ex) { 648 log.log(Level.WARNING, ex.toString(), ex); 649 650 env.warning(L.l("Unable to read :" + ex.toString())); 651 652 return BooleanValue.FALSE; 653 } 654 655 return BooleanValue.TRUE; 656 } 657 658 public LongValue getNextType() { 659 return LongValue.create(_currentNodeType); 660 } 661 662 668 public BooleanValue setParserProperty(int property, boolean value) { 669 throw new UnsupportedOperationException (getClass().getName()); 670 } 671 672 677 public BooleanValue setRelaxNGSchema(String filename) { 678 throw new UnsupportedOperationException (getClass().getName()); 679 } 680 681 686 public BooleanValue setRelaxNGSchemaSource(String source) { 687 throw new UnsupportedOperationException (getClass().getName()); 688 } 689 690 695 public BooleanValue XML(String source) { 696 throw new UnsupportedOperationException (getClass().getName()); 697 } 698 699 static { 700 _constConvertMap.put(XMLStreamConstants.ATTRIBUTE, 701 ATTRIBUTE); 702 _constConvertMap.put(XMLStreamConstants.CDATA, 703 CDATA); 704 _constConvertMap.put(XMLStreamConstants.CHARACTERS, 705 TEXT); 706 _constConvertMap.put(XMLStreamConstants.COMMENT, 707 COMMENT); 708 _constConvertMap.put(XMLStreamConstants.END_ELEMENT, 709 END_ELEMENT); 710 714 _constConvertMap.put(XMLStreamConstants.ENTITY_DECLARATION, 717 ENTITY); _constConvertMap.put(XMLStreamConstants.ENTITY_REFERENCE, 719 ENTITY_REF); 720 _constConvertMap.put(XMLStreamConstants.NOTATION_DECLARATION, 721 NOTATION); 722 _constConvertMap.put(XMLStreamConstants.PROCESSING_INSTRUCTION, 723 PI); 724 _constConvertMap.put(XMLStreamConstants.SPACE, 725 WHITESPACE); 726 _constConvertMap.put(XMLStreamConstants.START_ELEMENT, 727 ELEMENT); 728 732 _constConvertMap.put(XMLStreamConstants.DTD, NONE); 734 _constConvertMap.put(XMLStreamConstants.END_DOCUMENT, NONE); 735 _constConvertMap.put(XMLStreamConstants.NAMESPACE, NONE); 736 _constConvertMap.put(XMLStreamConstants.START_DOCUMENT, NONE); 737 _constConvertMap.put(0, NONE); _constConvertMap.put(-1, NONE); 739 _constConvertMap.put(-1, DOC); 740 _constConvertMap.put(-1, DOC_TYPE); 741 _constConvertMap.put(-1, DOC_FRAGMENT); 742 _constConvertMap.put(-1, DOC_TYPE); 743 _constConvertMap.put(-1, XML_DECLARATION); 744 } 745 } 746 | Popular Tags |