1 /* XIncludeFilter.java -- 2 Copyright (C) 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package gnu.xml.stream; 39 40 import java.io.InputStream; 41 import java.io.InputStreamReader; 42 import java.io.IOException; 43 import java.io.Reader; 44 import java.net.HttpURLConnection; 45 import java.net.URL; 46 import java.net.URLConnection; 47 import java.util.HashSet; 48 import java.util.NoSuchElementException; 49 import java.util.StringTokenizer; 50 import javax.xml.namespace.QName; 51 import javax.xml.parsers.DocumentBuilder; 52 import javax.xml.parsers.DocumentBuilderFactory; 53 import javax.xml.parsers.ParserConfigurationException; 54 import javax.xml.stream.XMLStreamConstants; 55 import javax.xml.stream.XMLStreamException; 56 import javax.xml.stream.XMLStreamReader; 57 import javax.xml.stream.util.StreamReaderDelegate; 58 59 import org.w3c.dom.Attr; 60 import org.w3c.dom.Document; 61 import org.w3c.dom.DOMImplementation; 62 import org.w3c.dom.NamedNodeMap; 63 import org.w3c.dom.Node; 64 import org.w3c.dom.ProcessingInstruction; 65 import org.w3c.dom.TypeInfo; 66 import org.w3c.dom.traversal.DocumentTraversal; 67 import org.w3c.dom.traversal.NodeFilter; 68 import org.w3c.dom.traversal.TreeWalker; 69 import org.w3c.dom.xpath.XPathEvaluator; 70 import org.w3c.dom.xpath.XPathNSResolver; 71 import org.w3c.dom.xpath.XPathResult; 72 import org.xml.sax.SAXException; 73 74 /** 75 * StAX filter for performing XInclude processing. 76 * 77 * @see http://www.w3.org/TR/xinclude/ 78 * @see http://www.w3.org/TR/xptr-framework/ 79 * @see http://www.w3.org/TR/xptr-element/ 80 * 81 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> 82 */ 83 class XIncludeFilter 84 extends StreamReaderDelegate 85 { 86 87 static final String XINCLUDE_NS_URI = "http://www.w3.org/2001/XInclude"; 88 static final int SHOW_FLAGS = 89 NodeFilter.SHOW_CDATA_SECTION | 90 NodeFilter.SHOW_COMMENT | 91 NodeFilter.SHOW_ELEMENT | 92 NodeFilter.SHOW_ENTITY_REFERENCE | 93 NodeFilter.SHOW_PROCESSING_INSTRUCTION | 94 NodeFilter.SHOW_TEXT; 95 96 final String systemId; 97 final boolean namespaceAware; 98 final boolean validating; 99 final boolean expandERefs; 100 String href; 101 int event; 102 boolean included; 103 XPathResult result; 104 int snapshotIndex; 105 Node current; 106 TreeWalker walker; 107 HashSet seen = new HashSet(); 108 boolean backtracking; 109 boolean lookahead; 110 111 Reader includedText; 112 char[] buf; 113 int len = -1; 114 boolean inInclude, inFallback, seenFallback; 115 116 DocumentBuilder builder; 117 XIncludeFilter(XMLStreamReader reader, String systemId, boolean namespaceAware, boolean validating, boolean expandERefs)118 XIncludeFilter(XMLStreamReader reader, String systemId, 119 boolean namespaceAware, boolean validating, 120 boolean expandERefs) 121 { 122 super(reader); 123 this.systemId = XMLParser.absolutize(null, systemId); 124 this.namespaceAware = namespaceAware; 125 this.validating = validating; 126 this.expandERefs = expandERefs; 127 } 128 getAttributeCount()129 public int getAttributeCount() 130 { 131 if (current != null) 132 { 133 NamedNodeMap attrs = current.getAttributes(); 134 return (attrs == null) ? 0 : attrs.getLength(); 135 } 136 return super.getAttributeCount(); 137 } 138 getAttributeLocalName(int index)139 public String getAttributeLocalName(int index) 140 { 141 if (current != null) 142 { 143 NamedNodeMap attrs = current.getAttributes(); 144 if (attrs == null) 145 return null; 146 Node attr = attrs.item(index); 147 return attr.getLocalName(); 148 } 149 return super.getAttributeLocalName(index); 150 } 151 getAttributeNamespace(int index)152 public String getAttributeNamespace(int index) 153 { 154 if (current != null) 155 { 156 NamedNodeMap attrs = current.getAttributes(); 157 if (attrs == null) 158 return null; 159 Node attr = attrs.item(index); 160 return attr.getNamespaceURI(); 161 } 162 return super.getAttributeNamespace(index); 163 } 164 getAttributePrefix(int index)165 public String getAttributePrefix(int index) 166 { 167 if (current != null) 168 { 169 NamedNodeMap attrs = current.getAttributes(); 170 if (attrs == null) 171 return null; 172 Node attr = attrs.item(index); 173 return attr.getPrefix(); 174 } 175 return super.getAttributePrefix(index); 176 } 177 getAttributeName(int index)178 public QName getAttributeName(int index) 179 { 180 if (current != null) 181 { 182 NamedNodeMap attrs = current.getAttributes(); 183 if (attrs == null) 184 return null; 185 Node attr = attrs.item(index); 186 String localName = attr.getLocalName(); 187 String uri = attr.getNamespaceURI(); 188 String prefix = attr.getPrefix(); 189 return new QName(uri, localName, prefix); 190 } 191 return super.getAttributeName(index); 192 } 193 getAttributeType(int index)194 public String getAttributeType(int index) 195 { 196 if (current != null) 197 { 198 NamedNodeMap attrs = current.getAttributes(); 199 if (attrs == null) 200 return null; 201 Attr attr = (Attr) attrs.item(index); 202 TypeInfo ti = attr.getSchemaTypeInfo(); 203 return (ti == null) ? "CDATA" : ti.getTypeName(); 204 } 205 return super.getAttributeType(index); 206 } 207 isAttributeSpecified(int index)208 public boolean isAttributeSpecified(int index) 209 { 210 if (current != null) 211 { 212 NamedNodeMap attrs = current.getAttributes(); 213 if (attrs == null) 214 return false; 215 Attr attr = (Attr) attrs.item(index); 216 return attr.getSpecified(); 217 } 218 return super.isAttributeSpecified(index); 219 } 220 getAttributeValue(int index)221 public String getAttributeValue(int index) 222 { 223 if (current != null) 224 { 225 NamedNodeMap attrs = current.getAttributes(); 226 if (attrs == null) 227 return null; 228 Node attr = attrs.item(index); 229 return attr.getNodeValue(); 230 } 231 return super.getAttributeValue(index); 232 } 233 getAttributeValue(String uri, String localName)234 public String getAttributeValue(String uri, String localName) 235 { 236 if (current != null) 237 { 238 NamedNodeMap attrs = current.getAttributes(); 239 if (attrs == null) 240 return null; 241 Node attr = attrs.getNamedItemNS(uri, localName); 242 return (attr == null) ? null : attr.getNodeValue(); 243 } 244 return super.getAttributeValue(uri, localName); 245 } 246 getElementText()247 public String getElementText() 248 throws XMLStreamException 249 { 250 if (current != null) 251 return current.getTextContent(); 252 return super.getElementText(); 253 } 254 getEventType()255 public int getEventType() 256 { 257 return event; 258 } 259 getLocalName()260 public String getLocalName() 261 { 262 if (current != null) 263 return current.getLocalName(); 264 return super.getLocalName(); 265 } 266 getName()267 public QName getName() 268 { 269 if (current != null) 270 { 271 String localName = current.getLocalName(); 272 String uri = current.getNamespaceURI(); 273 String prefix = current.getPrefix(); 274 return new QName(uri, localName, prefix); 275 } 276 return super.getName(); 277 } 278 getNamespaceURI()279 public String getNamespaceURI() 280 { 281 if (current != null) 282 return current.getNamespaceURI(); 283 return super.getNamespaceURI(); 284 } 285 286 // TODO namespaces 287 getPIData()288 public String getPIData() 289 { 290 if (current != null) 291 return ((ProcessingInstruction) current).getData(); 292 return super.getPIData(); 293 } 294 getPITarget()295 public String getPITarget() 296 { 297 if (current != null) 298 return ((ProcessingInstruction) current).getTarget(); 299 return super.getPITarget(); 300 } 301 getPrefix()302 public String getPrefix() 303 { 304 if (current != null) 305 return current.getPrefix(); 306 return super.getPrefix(); 307 } 308 getText()309 public String getText() 310 { 311 if (current != null) 312 return current.getNodeValue(); 313 if (walker != null) 314 { 315 Node n = walker.getCurrentNode(); 316 if (n != null) 317 return n.getTextContent(); 318 } 319 if (buf != null) 320 return new String(buf, 0, len); 321 return super.getText(); 322 } 323 getTextCharacters()324 public char[] getTextCharacters() 325 { 326 if (current != null) 327 { 328 buf = current.getNodeValue().toCharArray(); 329 len = buf.length; 330 } 331 if (buf != null) 332 return buf; 333 return super.getTextCharacters(); 334 } 335 getTextCharacters(int sourceStart, char[] target, int targetStart, int length)336 public int getTextCharacters(int sourceStart, char[] target, 337 int targetStart, int length) 338 throws XMLStreamException 339 { 340 if (current != null) 341 { 342 buf = current.getNodeValue().toCharArray(); 343 len = buf.length; 344 } 345 if (buf != null) 346 { 347 int max = Math.min(len - sourceStart, length); 348 if (max > 0) 349 System.arraycopy(buf, sourceStart, target, targetStart, max); 350 return max; 351 } 352 return super.getTextCharacters(sourceStart, target, targetStart, length); 353 } 354 getTextLength()355 public int getTextLength() 356 { 357 if (current != null) 358 { 359 buf = current.getNodeValue().toCharArray(); 360 len = buf.length; 361 } 362 if (buf != null) 363 return len; 364 return super.getTextLength(); 365 } 366 getTextStart()367 public int getTextStart() 368 { 369 if (current != null) 370 { 371 buf = current.getNodeValue().toCharArray(); 372 len = buf.length; 373 } 374 if (buf != null) 375 return 0; 376 return super.getTextStart(); 377 } 378 hasNext()379 public boolean hasNext() 380 throws XMLStreamException 381 { 382 if (!lookahead) 383 { 384 try 385 { 386 next(); 387 } 388 catch (NoSuchElementException e) 389 { 390 event = -1; 391 } 392 lookahead = true; 393 } 394 return (event != -1); 395 } 396 next()397 public int next() 398 throws XMLStreamException 399 { 400 if (lookahead) 401 { 402 lookahead = false; 403 return event; 404 } 405 buf = null; 406 len = 0; 407 if (walker != null) 408 { 409 Node c = walker.getCurrentNode(); 410 Node n = null; 411 if (c.getNodeType() == Node.ELEMENT_NODE) 412 { 413 boolean isStartElement = !seen.contains(c); 414 if (isStartElement) 415 { 416 seen.add(c); 417 current = c; 418 event = XMLStreamConstants.START_ELEMENT; 419 return event; 420 } 421 else if (backtracking) 422 { 423 n = walker.nextSibling(); 424 if (n != null) 425 backtracking = false; 426 } 427 else 428 { 429 n = walker.firstChild(); 430 if (n == null) 431 n = walker.nextSibling(); 432 } 433 } 434 else 435 { 436 n = walker.firstChild(); 437 if (n == null) 438 n = walker.nextSibling(); 439 } 440 if (n == null) 441 { 442 current = walker.parentNode(); 443 if (current != null && current.getNodeType() == Node.ELEMENT_NODE) 444 { 445 // end-element 446 backtracking = true; 447 event = XMLStreamConstants.END_ELEMENT; 448 return event; 449 } 450 else 451 { 452 walker = null; 453 current = null; 454 } 455 } 456 else 457 { 458 current = n; 459 switch (n.getNodeType()) 460 { 461 case Node.ELEMENT_NODE: 462 return next(); 463 case Node.TEXT_NODE: 464 String text = n.getNodeValue(); 465 buf = text.toCharArray(); 466 len = buf.length; 467 event = isSpace(buf, len) ? 468 XMLStreamConstants.SPACE : 469 XMLStreamConstants.CHARACTERS; 470 return event; 471 case Node.CDATA_SECTION_NODE: 472 event = XMLStreamConstants.CDATA; 473 return event; 474 case Node.COMMENT_NODE: 475 event = XMLStreamConstants.COMMENT; 476 return event; 477 case Node.PROCESSING_INSTRUCTION_NODE: 478 event = XMLStreamConstants.PROCESSING_INSTRUCTION; 479 return event; 480 case Node.ENTITY_REFERENCE_NODE: 481 event = XMLStreamConstants.ENTITY_REFERENCE; 482 return event; 483 default: 484 throw new IllegalStateException(); 485 } 486 } 487 } 488 if (result != null) 489 { 490 switch (result.getResultType()) 491 { 492 case XPathResult.BOOLEAN_TYPE: 493 boolean bval = result.getBooleanValue(); 494 String btext = bval ? "true" : "false"; 495 buf = btext.toCharArray(); 496 len = buf.length; 497 result = null; 498 event = XMLStreamConstants.CHARACTERS; 499 return event; 500 case XPathResult.NUMBER_TYPE: 501 double nval = result.getNumberValue(); 502 String ntext = Double.toString(nval); 503 buf = ntext.toCharArray(); 504 len = buf.length; 505 result = null; 506 event = XMLStreamConstants.CHARACTERS; 507 return event; 508 case XPathResult.STRING_TYPE: 509 String stext = result.getStringValue(); 510 buf = stext.toCharArray(); 511 len = buf.length; 512 result = null; 513 event = isSpace(buf, len) ? 514 XMLStreamConstants.SPACE : 515 XMLStreamConstants.CHARACTERS; 516 return event; 517 case XPathResult.ANY_UNORDERED_NODE_TYPE: 518 case XPathResult.FIRST_ORDERED_NODE_TYPE: 519 Node n1 = result.getSingleNodeValue(); 520 Document d1 = getDocument(n1); 521 walker = getDocumentTraversal(d1) 522 .createTreeWalker(n1, SHOW_FLAGS, null, expandERefs); 523 result = null; 524 return next(); 525 case XPathResult.ORDERED_NODE_ITERATOR_TYPE: 526 case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: 527 Node n2 = result.iterateNext(); 528 if (n2 == null) 529 { 530 result = null; 531 return next(); 532 } 533 Document d2 = getDocument(n2); 534 walker = getDocumentTraversal(d2) 535 .createTreeWalker(n2, SHOW_FLAGS, null, expandERefs); 536 return next(); 537 case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE: 538 case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE: 539 Node n3 = result.snapshotItem(snapshotIndex++); 540 if (n3 == null) 541 { 542 result = null; 543 return next(); 544 } 545 Document d3 = getDocument(n3); 546 walker = getDocumentTraversal(d3) 547 .createTreeWalker(n3, SHOW_FLAGS, null, expandERefs); 548 return next(); 549 default: 550 throw new IllegalStateException(); 551 } 552 } 553 if (includedText != null) 554 { 555 // fill buffer 556 if (buf == null) 557 buf = new char[2048]; 558 try 559 { 560 len = includedText.read(buf, 0, buf.length); 561 if (len == -1) 562 { 563 includedText = null; 564 buf = null; 565 return next(); 566 } 567 // chars or space? 568 return (event = isSpace(buf, len) ? 569 XMLStreamConstants.SPACE : 570 XMLStreamConstants.CHARACTERS); 571 } 572 catch (IOException e) 573 { 574 XMLStreamException e2 = new XMLStreamException(e.getMessage()); 575 e2.initCause(e); 576 throw e2; 577 } 578 } 579 event = super.next(); 580 switch (event) 581 { 582 case XMLStreamConstants.START_ELEMENT: 583 String uri = getNamespaceURI(); 584 if (XINCLUDE_NS_URI.equals(uri)) 585 { 586 String localName = getLocalName(); 587 if ("include".equals(localName)) 588 { 589 href = getAttributeValue(null, "href"); 590 String parse = getAttributeValue(null, "parse"); 591 String xpointer = getAttributeValue(null, "xpointer"); 592 String encoding = getAttributeValue(null, "encoding"); 593 String accept = getAttributeValue(null, "accept"); 594 String acceptLanguage = getAttributeValue(null, 595 "accept-language"); 596 if (includeResource(href, parse, xpointer, encoding, 597 accept, acceptLanguage)) 598 { 599 // Skip to xi:include end-element event 600 int depth = 0; 601 while (depth >= 0) 602 { 603 event = super.next(); 604 switch (event) 605 { 606 case XMLStreamConstants.START_ELEMENT: 607 depth++; 608 break; 609 case XMLStreamConstants.END_ELEMENT: 610 depth--; 611 } 612 } 613 } 614 else 615 inInclude = true; 616 } 617 else if (inInclude && "fallback".equals(localName)) 618 { 619 if (!seenFallback) 620 inFallback = seenFallback = true; 621 else 622 throw new XMLStreamException("duplicate xi:fallback element"); 623 } 624 else if (inInclude) 625 { 626 throw new XMLStreamException("illegal xi element '" + 627 localName + "'"); 628 } 629 return next(); 630 } 631 break; 632 case XMLStreamConstants.END_ELEMENT: 633 String uri2 = getNamespaceURI(); 634 if (XINCLUDE_NS_URI.equals(uri2)) 635 { 636 String localName = getLocalName(); 637 if ("include".equals(localName)) 638 { 639 if (!seenFallback && included) 640 { 641 String msg = "Unable to read " + href + 642 " and no xi:fallback element present"; 643 throw new XMLStreamException(msg); 644 } 645 included = false; 646 href = null; 647 inInclude = inFallback = seenFallback = false; 648 } 649 else if ("fallback".equals(localName)) 650 inFallback = false; 651 return next(); 652 } 653 break; 654 } 655 if (inInclude && !inFallback) 656 return next(); 657 return event; 658 } 659 isSpace(char[] text, int len)660 boolean isSpace(char[] text, int len) 661 { 662 boolean space = true; 663 for (int i = 0; i < len; i++) 664 { 665 char c = text[i]; 666 if (c != ' ' && c != '\t' && c != '\n' && c != '\r') 667 { 668 space = false; 669 break; 670 } 671 } 672 return space; 673 } 674 getBaseURI()675 String getBaseURI() 676 { 677 String base = (String) getParent().getProperty("gnu.xml.stream.baseURI"); 678 return (base == null) ? systemId : base; 679 } 680 includeResource(String href, String parse, String xpointer, String encoding, String accept, String acceptLanguage)681 boolean includeResource(String href, String parse, String xpointer, 682 String encoding, String accept, 683 String acceptLanguage) 684 { 685 included = false; 686 try 687 { 688 if (xpointer != null) 689 throw new XMLStreamException("xpointer attribute not yet supported"); 690 String base = getBaseURI(); 691 if (href == null || "".equals(href)) 692 href = base; 693 else 694 href = XMLParser.absolutize(base, href); 695 if (parse == null || "xml".equals(parse)) 696 { 697 seen.clear(); 698 result = null; 699 snapshotIndex = 0; 700 walker = null; 701 current = null; 702 backtracking = false; 703 704 URLConnection connection = getURLConnection(href, accept, 705 acceptLanguage); 706 InputStream in = connection.getInputStream(); 707 Document doc = getDocumentBuilder().parse(in, href); 708 DocumentTraversal dt = getDocumentTraversal(doc); 709 if (xpointer == null) 710 { 711 result = null; 712 Node item = doc.getDocumentElement(); 713 walker = dt.createTreeWalker(item, SHOW_FLAGS, null, 714 expandERefs); 715 } 716 else 717 { 718 result = null; 719 snapshotIndex = 0; 720 walker = null; 721 // shorthand or scheme-based? 722 int lpi = xpointer.indexOf('('); 723 int rpi = xpointer.indexOf(')', lpi); 724 if (lpi != -1 && rpi != -1) 725 { 726 String scheme = xpointer.substring(0, lpi); 727 if ("element".equals(scheme)) 728 { 729 // element() scheme 730 String elementSchemeData = 731 xpointer.substring(lpi + 1, rpi); 732 Node item = doc; 733 int si = elementSchemeData.indexOf('/'); 734 if (si == -1) 735 { 736 if (elementSchemeData.length() > 0) 737 item = doc.getElementById(elementSchemeData); 738 } 739 else 740 { 741 if (si > 0) 742 { 743 String context = 744 elementSchemeData.substring(0, si); 745 item = doc.getElementById(context); 746 elementSchemeData = 747 elementSchemeData.substring(si + 1); 748 } 749 StringTokenizer st = 750 new StringTokenizer(elementSchemeData, "/"); 751 while (st.hasMoreTokens() && item != null) 752 { 753 int n = Integer.parseInt(st.nextToken()); 754 Node ctx = item.getFirstChild(); 755 int count = 1; 756 while (ctx != null && count++ < n) 757 ctx = ctx.getNextSibling(); 758 item = ctx; 759 } 760 } 761 walker = dt.createTreeWalker(item, SHOW_FLAGS, null, 762 expandERefs); 763 included = true; 764 } 765 else if ("xpointer".equals(scheme)) 766 { 767 xpointer = xpointer.substring(lpi + 1, rpi); 768 XPathEvaluator eval = getXPathEvaluator(doc); 769 XPathNSResolver resolver = eval.createNSResolver(doc); 770 result = 771 (XPathResult) eval.evaluate(xpointer, doc, 772 resolver, 773 XPathResult.ANY_TYPE, 774 null); 775 // TODO xpointer() scheme functions 776 included = true; 777 } 778 else 779 { 780 String msg = "Unknown XPointer scheme: " + scheme; 781 throw new XMLStreamException(msg); 782 } 783 } 784 else 785 { 786 Node item = doc.getElementById(xpointer); 787 walker = dt.createTreeWalker(item, SHOW_FLAGS, null, 788 expandERefs); 789 included = true; 790 } 791 } 792 } 793 else if ("text".equals(parse)) 794 { 795 URLConnection connection = getURLConnection(href, accept, 796 acceptLanguage); 797 InputStream in = connection.getInputStream(); 798 if (encoding == null) 799 { 800 encoding = connection.getContentEncoding(); 801 if (encoding == null) 802 { 803 String contentType = connection.getContentType(); 804 if (contentType != null) 805 encoding = getParameter(contentType, "charset"); 806 } 807 } 808 if (encoding == null) 809 includedText = new InputStreamReader(in, "UTF-8"); 810 else 811 includedText = new InputStreamReader(in, encoding); 812 included = true; 813 } 814 else 815 throw new XMLStreamException("value of 'parse' attribute must be "+ 816 "'xml' or 'text'"); 817 return true; 818 } 819 catch (IOException e) 820 { 821 return false; 822 } 823 catch (XMLStreamException e) 824 { 825 return false; 826 } 827 catch (SAXException e) 828 { 829 return false; 830 } 831 } 832 getURLConnection(String href, String accept, String acceptLanguage)833 URLConnection getURLConnection(String href, String accept, 834 String acceptLanguage) 835 throws IOException 836 { 837 URL url = new URL(href); 838 URLConnection connection = url.openConnection(); 839 if (connection instanceof HttpURLConnection) 840 { 841 HttpURLConnection http = (HttpURLConnection) connection; 842 http.setInstanceFollowRedirects(true); 843 if (accept != null) 844 http.setRequestProperty("Accept", accept); 845 if (acceptLanguage != null) 846 http.setRequestProperty("Accept-Language", acceptLanguage); 847 } 848 return connection; 849 } 850 getDocument(Node node)851 Document getDocument(Node node) 852 { 853 if (node.getNodeType() == Node.DOCUMENT_NODE) 854 return (Document) node; 855 return node.getOwnerDocument(); 856 } 857 getDocumentBuilder()858 DocumentBuilder getDocumentBuilder() 859 throws XMLStreamException 860 { 861 if (builder == null) 862 { 863 try 864 { 865 DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); 866 f.setXIncludeAware(true); 867 f.setNamespaceAware(namespaceAware); 868 f.setValidating(validating); 869 builder = f.newDocumentBuilder(); 870 } 871 catch (ParserConfigurationException e) 872 { 873 XMLStreamException e2 = new XMLStreamException(e.getMessage()); 874 e2.initCause(e); 875 throw e2; 876 } 877 } 878 builder.reset(); 879 return builder; 880 } 881 getDocumentTraversal(Document doc)882 DocumentTraversal getDocumentTraversal(Document doc) 883 throws XMLStreamException 884 { 885 DOMImplementation dom = doc.getImplementation(); 886 if (!dom.hasFeature("Traversal", "2.0")) 887 throw new XMLStreamException("Traversal not supported"); 888 return (DocumentTraversal) doc; 889 } 890 getXPathEvaluator(Document doc)891 XPathEvaluator getXPathEvaluator(Document doc) 892 throws XMLStreamException 893 { 894 DOMImplementation dom = doc.getImplementation(); 895 if (!dom.hasFeature("XPath", "3.0")) 896 throw new XMLStreamException("XPath not supported"); 897 return (XPathEvaluator) doc; 898 } 899 getParameter(String contentType, String name)900 static String getParameter(String contentType, String name) 901 { 902 StringTokenizer st = new StringTokenizer(contentType, " ;"); 903 if (st.hasMoreTokens()) 904 st.nextToken(); 905 while (st.hasMoreTokens()) 906 { 907 String token = st.nextToken(); 908 int ei = token.indexOf('='); 909 if (ei != -1) 910 { 911 String key = token.substring(0, ei); 912 if (key.equals(name)) 913 { 914 String value = token.substring(ei + 1); 915 int len = value.length(); 916 if (len > 1 && 917 value.charAt(0) == '"' && 918 value.charAt(len - 1) == '"') 919 value = value.substring(1, len - 1); 920 else if (len > 1 && 921 value.charAt(0) == '\'' && 922 value.charAt(len - 1) == '\'') 923 value = value.substring(1, len - 1); 924 return value; 925 } 926 } 927 } 928 return null; 929 } 930 931 } 932