| 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 &n
|