1 16 17 package org.apache.xml.serialize; 18 19 import java.io.FileOutputStream ; 20 import java.io.IOException ; 21 import java.io.OutputStream ; 22 import java.io.StringWriter ; 23 import java.io.UnsupportedEncodingException ; 24 import java.io.Writer ; 25 import java.lang.reflect.Method ; 26 import java.net.HttpURLConnection ; 27 import java.net.URL ; 28 import java.net.URLConnection ; 29 import java.util.StringTokenizer ; 30 import java.util.Vector ; 31 32 import org.apache.xerces.dom.CoreDocumentImpl; 33 import org.apache.xerces.dom.DOMErrorImpl; 34 import org.apache.xerces.dom.DOMLocatorImpl; 35 import org.apache.xerces.dom.DOMMessageFormatter; 36 import org.apache.xerces.dom.DOMNormalizer; 37 import org.apache.xerces.dom.DOMStringListImpl; 38 import org.w3c.dom.DOMConfiguration ; 39 import org.w3c.dom.DOMError ; 40 import org.w3c.dom.DOMErrorHandler ; 41 import org.w3c.dom.DOMStringList ; 42 import org.apache.xerces.impl.Constants; 43 import org.apache.xerces.impl.XMLEntityManager; 44 import org.apache.xerces.util.NamespaceSupport; 45 import org.apache.xerces.util.SymbolTable; 46 import org.apache.xerces.util.XML11Char; 47 import org.apache.xerces.util.XMLChar; 48 import org.w3c.dom.Attr ; 49 import org.w3c.dom.Comment ; 50 import org.w3c.dom.DOMException ; 51 import org.w3c.dom.Document ; 52 import org.w3c.dom.DocumentFragment ; 53 import org.w3c.dom.Element ; 54 import org.w3c.dom.NamedNodeMap ; 55 import org.w3c.dom.Node ; 56 import org.w3c.dom.ProcessingInstruction ; 57 import org.w3c.dom.ls.LSException ; 58 import org.w3c.dom.ls.LSOutput ; 59 import org.w3c.dom.ls.LSSerializer ; 60 import org.w3c.dom.ls.LSSerializerFilter ; 61 62 63 76 public class DOMSerializerImpl implements LSSerializer , DOMConfiguration { 77 78 82 private XMLSerializer serializer; 85 86 private XML11Serializer xml11Serializer; 88 89 private DOMStringList fRecognizedParameters; 91 92 95 protected short features = 0; 96 97 protected final static short NAMESPACES = 0x1<<0; 98 protected final static short WELLFORMED = 0x1<<1; 99 protected final static short ENTITIES = 0x1<<2; 100 protected final static short CDATA = 0x1<<3; 101 protected final static short SPLITCDATA = 0x1<<4; 102 protected final static short COMMENTS = 0x1<<5; 103 protected final static short DISCARDDEFAULT = 0x1<<6; 104 protected final static short INFOSET = 0x1<<7; 105 protected final static short XMLDECL = 0x1<<8; 106 protected final static short NSDECL = 0x1<<9; 107 protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1<<10; 108 109 private DOMErrorHandler fErrorHandler = null; 111 private final DOMErrorImpl fError = new DOMErrorImpl(); 112 private final DOMLocatorImpl fLocator = new DOMLocatorImpl(); 113 private static final RuntimeException abort = new RuntimeException (); 114 115 121 public DOMSerializerImpl() { 122 features |= NAMESPACES; 124 features |= ENTITIES; 125 features |= COMMENTS; 126 features |= CDATA; 127 features |= SPLITCDATA; 128 features |= WELLFORMED; 129 features |= NSDECL; 130 features |= DOM_ELEMENT_CONTENT_WHITESPACE; 131 features |= DISCARDDEFAULT; 132 features |= XMLDECL; 133 134 serializer = new XMLSerializer(); 135 initSerializer(serializer); 136 } 137 138 139 140 144 public DOMConfiguration getDomConfig(){ 145 return this; 146 } 147 148 151 public void setParameter(String name, Object value) throws DOMException { 152 if (value instanceof Boolean ) { 153 boolean state = ((Boolean ) value).booleanValue(); 154 if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){ 155 if (state){ 156 features &= ~ENTITIES; 157 features &= ~CDATA; 158 features |= NAMESPACES; 159 features |= NSDECL; 160 features |= WELLFORMED; 161 features |= COMMENTS; 162 } 163 } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) { 165 features = 166 (short) (state ? features | XMLDECL : features & ~XMLDECL); 167 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 168 features = 169 (short) (state 170 ? features | NAMESPACES 171 : features & ~NAMESPACES); 172 serializer.fNamespaces = state; 173 } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 174 features = 175 (short) (state 176 ? features | SPLITCDATA 177 : features & ~SPLITCDATA); 178 } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) { 179 features = 180 (short) (state 181 ? features | DISCARDDEFAULT 182 : features & ~DISCARDDEFAULT); 183 } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 184 features = 185 (short) (state 186 ? features | WELLFORMED 187 : features & ~WELLFORMED); 188 } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)){ 189 features = 190 (short) (state 191 ? features | ENTITIES 192 : features & ~ENTITIES); 193 } 194 else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)){ 195 features = 196 (short) (state 197 ? features | CDATA 198 : features & ~CDATA); 199 } 200 else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)){ 201 features = 202 (short) (state 203 ? features | COMMENTS 204 : features & ~COMMENTS); 205 } 206 else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 207 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 208 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 209 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 210 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION) 211 || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT) 212 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) { 213 if (state) { 215 String msg = 216 DOMMessageFormatter.formatMessage( 217 DOMMessageFormatter.DOM_DOMAIN, 218 "FEATURE_NOT_SUPPORTED", 219 new Object [] { name }); 220 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg); 221 } 222 }else if ( 223 name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 224 features = 226 (short) (state 227 ? features | NSDECL 228 : features & ~NSDECL); 229 serializer.fNamespacePrefixes = state; 230 } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) 231 || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 232 if (!state) { 234 String msg = 235 DOMMessageFormatter.formatMessage( 236 DOMMessageFormatter.DOM_DOMAIN, 237 "FEATURE_NOT_SUPPORTED", 238 new Object [] { name }); 239 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg); 240 } 241 } else { 242 String msg = 243 DOMMessageFormatter.formatMessage( 244 DOMMessageFormatter.DOM_DOMAIN, 245 "FEATURE_NOT_FOUND", 246 new Object [] { name }); 247 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg); 248 } 249 } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 250 if (value == null || value instanceof DOMErrorHandler ) { 251 fErrorHandler = (DOMErrorHandler )value; 252 } else { 253 String msg = 254 DOMMessageFormatter.formatMessage( 255 DOMMessageFormatter.DOM_DOMAIN, 256 "TYPE_MISMATCH_ERR", 257 new Object [] { name }); 258 throw new DOMException (DOMException.TYPE_MISMATCH_ERR, msg); 259 } 260 } else if ( 261 name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER) 262 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION) 263 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE) 264 && value != null) { 265 String msg = 266 DOMMessageFormatter.formatMessage( 267 DOMMessageFormatter.DOM_DOMAIN, 268 "FEATURE_NOT_SUPPORTED", 269 new Object [] { name }); 270 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg); 271 } else { 272 String msg = 273 DOMMessageFormatter.formatMessage( 274 DOMMessageFormatter.DOM_DOMAIN, 275 "FEATURE_NOT_FOUND", 276 new Object [] { name }); 277 throw new DOMException (DOMException.NOT_FOUND_ERR, msg); 278 } 279 } 280 281 284 public boolean canSetParameter(String name, Object state) { 285 if (state == null){ 286 return true; 287 } 288 289 if (state instanceof Boolean ){ 290 boolean value = ((Boolean )state).booleanValue(); 291 if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES) 292 || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA) 293 || name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT) 294 || name.equalsIgnoreCase(Constants.DOM_XMLDECL) 295 || name.equalsIgnoreCase(Constants.DOM_WELLFORMED) 296 || name.equalsIgnoreCase(Constants.DOM_INFOSET) 297 || name.equalsIgnoreCase(Constants.DOM_ENTITIES) 298 || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS) 299 || name.equalsIgnoreCase(Constants.DOM_COMMENTS) 300 || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)){ 301 return true; 303 } 304 else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 305 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 306 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 307 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 308 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION) 309 || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT) 310 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) { 311 return !value; 313 } 314 else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) 315 || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 316 return value; 318 } 319 } 320 else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER) && 321 state == null || state instanceof DOMErrorHandler ){ 322 return true; 323 } 324 return false; 325 } 326 327 335 public DOMStringList getParameterNames() { 336 337 if (fRecognizedParameters == null){ 338 Vector parameters = new Vector (); 339 340 parameters.add(Constants.DOM_NAMESPACES); 344 parameters.add(Constants.DOM_SPLIT_CDATA); 345 parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT); 346 parameters.add(Constants.DOM_XMLDECL); 347 parameters.add(Constants.DOM_CANONICAL_FORM); 348 parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); 349 parameters.add(Constants.DOM_VALIDATE); 350 parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); 351 parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); 352 parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT); 353 parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); 354 parameters.add(Constants.DOM_WELLFORMED); 355 parameters.add(Constants.DOM_INFOSET); 356 parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); 357 parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); 358 parameters.add(Constants.DOM_ENTITIES); 359 parameters.add(Constants.DOM_CDATA_SECTIONS); 360 parameters.add(Constants.DOM_COMMENTS); 361 parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS); 362 parameters.add(Constants.DOM_ERROR_HANDLER); 363 366 368 fRecognizedParameters = new DOMStringListImpl(parameters); 369 370 } 371 372 return fRecognizedParameters; 373 } 374 375 378 public Object getParameter(String name) throws DOMException { 379 if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) { 380 return ((features & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE; 381 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 382 return (features & NAMESPACES) != 0 ? Boolean.TRUE : Boolean.FALSE; 383 } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) { 384 return (features & XMLDECL) != 0 ? Boolean.TRUE : Boolean.FALSE; 385 } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) { 386 return (features & CDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 387 } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) { 388 return (features & ENTITIES) != 0 ? Boolean.TRUE : Boolean.FALSE; 389 } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 390 return (features & SPLITCDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 391 } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 392 return (features & WELLFORMED) != 0 ? Boolean.TRUE : Boolean.FALSE; 393 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 394 return (features & NSDECL) != 0 ? Boolean.TRUE : Boolean.FALSE; 395 } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) || 396 name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 397 return Boolean.TRUE; 398 }else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)){ 399 return ((features & DISCARDDEFAULT)!=0)?Boolean.TRUE:Boolean.FALSE; 400 }else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){ 401 if ((features & ENTITIES) == 0 && 402 (features & CDATA) == 0 && 403 (features & NAMESPACES) != 0 && 404 (features & NSDECL) != 0 && 405 (features & WELLFORMED) != 0 && 406 (features & COMMENTS) != 0) { 407 return Boolean.TRUE; 408 } 409 return Boolean.FALSE; 410 } else if (name.equalsIgnoreCase (Constants.DOM_FORMAT_PRETTY_PRINT) 411 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS) 412 || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 413 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 414 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 415 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 416 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 417 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 418 return Boolean.FALSE; 419 } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 420 return fErrorHandler; 421 } else if ( 422 name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER) 423 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION) 424 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { 425 String msg = 426 DOMMessageFormatter.formatMessage( 427 DOMMessageFormatter.DOM_DOMAIN, 428 "FEATURE_NOT_SUPPORTED", 429 new Object [] { name }); 430 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg); 431 } else { 432 String msg = 433 DOMMessageFormatter.formatMessage( 434 DOMMessageFormatter.DOM_DOMAIN, 435 "FEATURE_NOT_FOUND", 436 new Object [] { name }); 437 throw new DOMException (DOMException.NOT_FOUND_ERR, msg); 438 } 439 } 440 441 442 461 public String writeToString(Node wnode) throws DOMException , LSException { 462 Document doc = (wnode.getNodeType() == Node.DOCUMENT_NODE)?(Document )wnode:wnode.getOwnerDocument(); 464 Method getVersion = null; 465 XMLSerializer ser = null; 466 String ver = null; 467 try { 469 getVersion = doc.getClass().getMethod("getXmlVersion", new Class []{}); 470 if(getVersion != null ) { 471 ver = (String )getVersion.invoke(doc, (Object []) null); 472 } 473 } catch (Exception e) { 474 } 477 if(ver != null && ver.equals("1.1")) { 478 if(xml11Serializer == null) { 479 xml11Serializer = new XML11Serializer(); 480 initSerializer(xml11Serializer); 481 } 482 copySettings(serializer, xml11Serializer); 484 ser = xml11Serializer; 485 } else { 486 ser = serializer; 487 } 488 489 StringWriter destination = new StringWriter (); 490 try { 491 prepareForSerialization(ser, wnode); 492 ser._format.setEncoding("UTF-16"); 493 ser.setOutputCharStream(destination); 494 if (wnode.getNodeType() == Node.DOCUMENT_NODE) { 495 ser.serialize((Document )wnode); 496 } 497 else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) { 498 ser.serialize((DocumentFragment )wnode); 499 } 500 else if (wnode.getNodeType() == Node.ELEMENT_NODE) { 501 ser.serialize((Element )wnode); 502 } 503 else { 504 String msg = DOMMessageFormatter.formatMessage( 505 DOMMessageFormatter.SERIALIZER_DOMAIN, 506 "unable-to-serialize-node", null); 507 if (ser.fDOMErrorHandler != null) { 508 DOMErrorImpl error = new DOMErrorImpl(); 509 error.fType = "unable-to-serialize-node"; 510 error.fMessage = msg; 511 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 512 ser.fDOMErrorHandler.handleError(error); 513 } 514 throw new LSException (LSException.SERIALIZE_ERR, msg); 515 } 516 } catch (LSException lse) { 517 throw lse; 519 } catch (RuntimeException e) { 520 if (e == DOMNormalizer.abort){ 521 return null; 523 } 524 throw new LSException (LSException.SERIALIZE_ERR, e.toString()); 525 } catch (IOException ioe) { 526 String msg = DOMMessageFormatter.formatMessage( 530 DOMMessageFormatter.DOM_DOMAIN, 531 "STRING_TOO_LONG", 532 new Object [] { ioe.getMessage()}); 533 throw new DOMException (DOMException.DOMSTRING_SIZE_ERR,msg); 534 } 535 return destination.toString(); 536 } 537 538 561 public void setNewLine(String newLine) { 562 serializer._format.setLineSeparator(newLine); 563 } 564 565 566 589 public String getNewLine() { 590 return serializer._format.getLineSeparator(); 591 } 592 593 594 600 public LSSerializerFilter getFilter(){ 601 return serializer.fDOMFilter; 602 } 603 609 public void setFilter(LSSerializerFilter filter){ 610 serializer.fDOMFilter = filter; 611 } 612 613 private void initSerializer(XMLSerializer ser) { 615 ser.fNSBinder = new NamespaceSupport(); 616 ser.fLocalNSBinder = new NamespaceSupport(); 617 ser.fSymbolTable = new SymbolTable(); 618 } 619 620 private void copySettings(XMLSerializer src, XMLSerializer dest) { 626 dest.fDOMErrorHandler = fErrorHandler; 627 dest._format.setEncoding(src._format.getEncoding()); 628 dest._format.setLineSeparator(src._format.getLineSeparator()); 629 dest.fDOMFilter = src.fDOMFilter; 630 } 632 662 public boolean write(Node node, LSOutput destination) throws LSException { 663 664 if (node == null) 665 return false; 666 667 Method getVersion = null; 668 XMLSerializer ser = null; 669 String ver = null; 670 Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE) 671 ? (Document ) node 672 : node.getOwnerDocument(); 673 try { 675 getVersion = fDocument.getClass().getMethod("getXmlVersion", new Class [] {}); 676 if (getVersion != null) { 677 ver = (String ) getVersion.invoke(fDocument, (Object []) null); 678 } 679 } catch (Exception e) { 680 } 683 if (ver != null && ver.equals("1.1")) { 685 if (xml11Serializer == null) { 686 xml11Serializer = new XML11Serializer(); 687 initSerializer(xml11Serializer); 688 } 689 copySettings(serializer, xml11Serializer); 691 ser = xml11Serializer; 692 } else { 693 ser = serializer; 694 } 695 696 String encoding = null; 697 if ((encoding = destination.getEncoding()) == null) { 698 try { 699 Method getEncoding = 700 fDocument.getClass().getMethod("getInputEncoding", new Class [] {}); 701 if (getEncoding != null) { 702 encoding = (String ) getEncoding.invoke(fDocument, (Object []) null); 703 } 704 } catch (Exception e) { 705 } 707 if (encoding == null) { 708 try { 709 Method getEncoding = 710 fDocument.getClass().getMethod("getXmlEncoding", new Class [] {}); 711 if (getEncoding != null) { 712 encoding = (String ) getEncoding.invoke(fDocument, (Object []) null); 713 } 714 } catch (Exception e) { 715 } 717 if (encoding == null) { 718 encoding = "UTF-8"; 719 } 720 } 721 } 722 try { 723 prepareForSerialization(ser, node); 724 ser._format.setEncoding(encoding); 725 OutputStream outputStream = destination.getByteStream(); 726 Writer writer = destination.getCharacterStream(); 727 String uri = destination.getSystemId(); 728 if (writer == null) { 729 if (outputStream == null) { 730 if (uri == null) { 731 String msg = DOMMessageFormatter.formatMessage( 732 DOMMessageFormatter.SERIALIZER_DOMAIN, 733 "no-output-specified", null); 734 if (ser.fDOMErrorHandler != null) { 735 DOMErrorImpl error = new DOMErrorImpl(); 736 error.fType = "no-output-specified"; 737 error.fMessage = msg; 738 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 739 ser.fDOMErrorHandler.handleError(error); 740 } 741 throw new LSException (LSException.SERIALIZE_ERR, msg); 742 } 743 else { 744 String expanded = XMLEntityManager.expandSystemId(uri, null, true); 746 URL url = new URL (expanded != null ? expanded : uri); 747 OutputStream out = null; 748 String protocol = url.getProtocol(); 749 String host = url.getHost(); 750 if (protocol.equals("file") 752 && (host == null || host.length() == 0 || host.equals("localhost"))) { 753 out = new FileOutputStream (getPathWithoutEscapes(url.getFile())); 754 } 755 else { 758 URLConnection urlCon = url.openConnection(); 759 urlCon.setDoInput(false); 760 urlCon.setDoOutput(true); 761 urlCon.setUseCaches(false); if (urlCon instanceof HttpURLConnection ) { 763 HttpURLConnection httpCon = (HttpURLConnection ) urlCon; 766 httpCon.setRequestMethod("PUT"); 767 } 768 out = urlCon.getOutputStream(); 769 } 770 ser.setOutputByteStream(out); 771 } 772 } 773 else { 774 ser.setOutputByteStream(outputStream); 776 } 777 } 778 else { 779 ser.setOutputCharStream(writer); 781 } 782 783 if (node.getNodeType() == Node.DOCUMENT_NODE) 784 ser.serialize((Document ) node); 785 else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) 786 ser.serialize((DocumentFragment ) node); 787 else if (node.getNodeType() == Node.ELEMENT_NODE) 788 ser.serialize((Element ) node); 789 else 790 return false; 791 } catch( UnsupportedEncodingException ue) { 792 if (ser.fDOMErrorHandler != null) { 793 DOMErrorImpl error = new DOMErrorImpl(); 794 error.fException = ue; 795 error.fType = "unsupported-encoding"; 796 error.fMessage = ue.getMessage(); 797 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 798 ser.fDOMErrorHandler.handleError(error); 799 } 800 throw new LSException (LSException.SERIALIZE_ERR, 801 DOMMessageFormatter.formatMessage( 802 DOMMessageFormatter.SERIALIZER_DOMAIN, 803 "unsupported-encoding", null)); 804 } catch (LSException lse) { 806 throw lse; 808 } catch (RuntimeException e) { 809 if (e == DOMNormalizer.abort){ 810 return false; 812 } 813 throw new LSException (LSException.SERIALIZE_ERR, e.toString()); 814 } catch (Exception e) { 815 if (ser.fDOMErrorHandler != null) { 816 DOMErrorImpl error = new DOMErrorImpl(); 817 error.fException = e; 818 error.fMessage = e.getMessage(); 819 error.fSeverity = DOMError.SEVERITY_ERROR; 820 ser.fDOMErrorHandler.handleError(error); 821 822 } 823 e.printStackTrace(); 824 throw new LSException (LSException.SERIALIZE_ERR, e.toString()); 825 } 826 return true; 827 828 } 830 855 public boolean writeToURI(Node node, String URI) throws LSException { 856 if (node == null){ 857 return false; 858 } 859 860 Method getXmlVersion = null; 861 XMLSerializer ser = null; 862 String ver = null; 863 String encoding = null; 864 865 Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE) 866 ? (Document ) node 867 : node.getOwnerDocument(); 868 try { 870 getXmlVersion = 871 fDocument.getClass().getMethod("getXmlVersion", new Class [] {}); 872 if (getXmlVersion != null) { 873 ver = (String ) getXmlVersion.invoke(fDocument, (Object []) null); 874 } 875 } catch (Exception e) { 876 } 879 if (ver != null && ver.equals("1.1")) { 880 if (xml11Serializer == null) { 881 xml11Serializer = new XML11Serializer(); 882 initSerializer(xml11Serializer); 883 } 884 copySettings(serializer, xml11Serializer); 886 ser = xml11Serializer; 887 } else { 888 ser = serializer; 889 } 890 891 try { 892 Method getEncoding = 893 fDocument.getClass().getMethod("getInputEncoding", new Class [] {}); 894 if (getEncoding != null) { 895 encoding = (String ) getEncoding.invoke(fDocument, (Object []) null); 896 } 897 } catch (Exception e) { 898 } 900 if (encoding == null) { 901 try { 902 Method getEncoding = 903 fDocument.getClass().getMethod("getXmlEncoding", new Class [] {}); 904 if (getEncoding != null) { 905 encoding = (String ) getEncoding.invoke(fDocument, (Object []) null); 906 } 907 } catch (Exception e) { 908 } 910 if (encoding == null) { 911 encoding = "UTF-8"; 912 } 913 } 914 915 try { 916 prepareForSerialization(ser, node); 917 ser._format.setEncoding(encoding); 918 919 String expanded = XMLEntityManager.expandSystemId(URI, null, true); 921 URL url = new URL (expanded != null ? expanded : URI); 922 OutputStream out = null; 923 String protocol = url.getProtocol(); 924 String host = url.getHost(); 925 if (protocol.equals("file") 927 && (host == null || host.length() == 0 || host.equals("localhost"))) { 928 out = new FileOutputStream (getPathWithoutEscapes(url.getFile())); 929 } 930 else { 933 URLConnection urlCon = url.openConnection(); 934 urlCon.setDoInput(false); 935 urlCon.setDoOutput(true); 936 urlCon.setUseCaches(false); if (urlCon instanceof HttpURLConnection ) { 938 HttpURLConnection httpCon = (HttpURLConnection ) urlCon; 941 httpCon.setRequestMethod("PUT"); 942 } 943 out = urlCon.getOutputStream(); 944 } 945 ser.setOutputByteStream(out); 946 947 if (node.getNodeType() == Node.DOCUMENT_NODE) 948 ser.serialize((Document ) node); 949 else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) 950 ser.serialize((DocumentFragment ) node); 951 else if (node.getNodeType() == Node.ELEMENT_NODE) 952 ser.serialize((Element ) node); 953 else 954 return false; 955 } catch (LSException lse) { 956 throw lse; 958 } catch (RuntimeException e) { 959 if (e == DOMNormalizer.abort){ 960 return false; 962 } 963 throw new LSException (LSException.SERIALIZE_ERR, e.toString()); 964 } catch (Exception e) { 965 if (ser.fDOMErrorHandler != null) { 966 DOMErrorImpl error = new DOMErrorImpl(); 967 error.fException = e; 968 error.fMessage = e.getMessage(); 969 error.fSeverity = DOMError.SEVERITY_ERROR; 970 ser.fDOMErrorHandler.handleError(error); 971 } 972 throw new LSException (LSException.SERIALIZE_ERR, e.toString()); 973 } 974 return true; 975 } 977 978 982 private void prepareForSerialization(XMLSerializer ser, Node node) { 983 ser.reset(); 984 ser.features = features; 985 ser.fDOMErrorHandler = fErrorHandler; 986 ser.fNamespaces = (features & NAMESPACES) != 0; 987 ser.fNamespacePrefixes = (features & NSDECL) != 0; 988 ser._format.setOmitComments((features & COMMENTS)==0); 989 ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0); 990 991 if ((features & WELLFORMED) != 0) { 992 Node next, root; 995 root = node; 996 Method versionChanged; 997 boolean verifyNames = true; 998 Document document =(node.getNodeType() == Node.DOCUMENT_NODE) 999 ? (Document ) node 1000 : node.getOwnerDocument(); 1001 try { 1002 versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class [] {}); 1003 if (versionChanged != null) { 1004 verifyNames = ((Boolean )versionChanged.invoke(document, (Object []) null)).booleanValue(); 1005 } 1006 } catch (Exception e) { 1007 } 1010 if (node.getFirstChild() != null) { 1011 while (node != null) { 1012 verify(node, verifyNames, false); 1013 next = node.getFirstChild(); 1015 while (next == null) { 1017 next = node.getNextSibling(); 1019 if (next == null) { 1020 node = node.getParentNode(); 1021 if (root == node){ 1022 next = null; 1023 break; 1024 } 1025 next = node.getNextSibling(); 1026 } 1027 } 1028 node = next; 1029 } 1030 } 1031 else { 1032 verify(node, verifyNames, false); 1033 } 1034 } 1035 } 1036 1037 1038 private void verify (Node node, boolean verifyNames, boolean xml11Version){ 1039 1040 int type = node.getNodeType(); 1041 fLocator.fRelatedNode = node; 1042 boolean wellformed; 1043 switch (type) { 1044 case Node.DOCUMENT_NODE:{ 1045 break; 1046 } 1047 case Node.DOCUMENT_TYPE_NODE:{ 1048 break; 1049 } 1050 case Node.ELEMENT_NODE:{ 1051 if (verifyNames){ 1052 if((features & NAMESPACES) != 0){ 1053 wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), xml11Version) ; 1054 } 1055 else{ 1056 wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version); 1057 } 1058 if (!wellformed){ 1059 if (!wellformed){ 1060 if (fErrorHandler != null) { 1061 String msg = DOMMessageFormatter.formatMessage( 1062 DOMMessageFormatter.DOM_DOMAIN, 1063 "wf-invalid-character-in-node-name", 1064 new Object []{"Element", node.getNodeName()}); 1065 DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, 1066 "wf-invalid-character-in-node-name"); 1067 } 1068 1069 } 1070 } 1071 } 1072 1073 NamedNodeMap attributes = (node.hasAttributes()) ? node.getAttributes() : null; 1074 if (attributes != null) { 1075 for (int i = 0; i < attributes.getLength(); ++i) { 1076 Attr attr = (Attr ) attributes.item(i); 1077 fLocator.fRelatedNode = attr; 1078 DOMNormalizer.isAttrValueWF( fErrorHandler, fError, fLocator, 1079 attributes, attr, attr.getValue(), xml11Version); 1080 if (verifyNames) { 1081 wellformed = CoreDocumentImpl.isXMLName( attr.getNodeName(), xml11Version); 1082 if (!wellformed) { 1083 String msg = 1084 DOMMessageFormatter.formatMessage( 1085 DOMMessageFormatter.DOM_DOMAIN, 1086 "wf-invalid-character-in-node-name", 1087 new Object [] { "Attr", node.getNodeName()}); 1088 DOMNormalizer.reportDOMError( fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, 1089 "wf-invalid-character-in-node-name"); 1090 } 1091 } 1092 } 1093 1094 } 1095 1096 break; 1097 } 1098 1099 case Node.COMMENT_NODE: { 1100 if ((features & COMMENTS) != 0) 1102 DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment )node).getData(), xml11Version); 1103 break; 1104 } 1105 case Node.ENTITY_REFERENCE_NODE: { 1106 if (verifyNames && (features & ENTITIES) != 0){ 1108 CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version); 1109 } 1110 break; 1111 1112 } 1113 case Node.CDATA_SECTION_NODE: { 1114 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version); 1116 break; 1118 } 1119 case Node.TEXT_NODE:{ 1120 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version); 1121 break; 1122 } 1123 case Node.PROCESSING_INSTRUCTION_NODE:{ 1124 ProcessingInstruction pinode = (ProcessingInstruction )node ; 1125 String target = pinode.getTarget(); 1126 if (verifyNames) { 1127 if (xml11Version) { 1128 wellformed = XML11Char.isXML11ValidName(target); 1129 } else { 1130 wellformed = XMLChar.isValidName(target); 1131 } 1132 1133 if (!wellformed) { 1134 String msg = 1135 DOMMessageFormatter.formatMessage( 1136 DOMMessageFormatter.DOM_DOMAIN, 1137 "wf-invalid-character-in-node-name", 1138 new Object [] { "Element", node.getNodeName()}); 1139 DOMNormalizer.reportDOMError( 1140 fErrorHandler, 1141 fError, 1142 fLocator, 1143 msg, 1144 DOMError.SEVERITY_FATAL_ERROR, 1145 "wf-invalid-character-in-node-name"); 1146 } 1147 } 1148 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version); 1149 break; 1150 } 1151 } 1152 1153 } 1154 1155 private String getPathWithoutEscapes(String origPath) { 1156 if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) { 1157 StringTokenizer tokenizer = new StringTokenizer (origPath, "%"); 1159 StringBuffer result = new StringBuffer (origPath.length()); 1160 int size = tokenizer.countTokens(); 1161 result.append(tokenizer.nextToken()); 1162 for(int i = 1; i < size; ++i) { 1163 String token = tokenizer.nextToken(); 1164 result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue()); 1166 result.append(token.substring(2)); 1167 } 1168 return result.toString(); 1169 } 1170 return origPath; 1171 } 1172 1173} 1175 1176 1177 1178 | Popular Tags |