1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Oct 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 package com.sun.org.apache.xml.internal.serialize;
  22 
  23 import com.sun.org.apache.xerces.internal.dom.AbortException;
  24 import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
  25 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
  26 import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
  27 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
  28 import com.sun.org.apache.xerces.internal.dom.DOMNormalizer;
  29 import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
  30 import com.sun.org.apache.xerces.internal.impl.Constants;
  31 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  32 import com.sun.org.apache.xerces.internal.util.DOMUtil;
  33 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
  34 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  35 import com.sun.org.apache.xerces.internal.util.XML11Char;
  36 import com.sun.org.apache.xerces.internal.util.XMLChar;
  37 import java.io.IOException;
  38 import java.io.OutputStream;
  39 import java.io.StringWriter;
  40 import java.io.UnsupportedEncodingException;
  41 import java.io.Writer;
  42 import java.lang.reflect.Method;
  43 import java.util.ArrayList;
  44 import java.util.List;
  45 import org.w3c.dom.Attr;
  46 import org.w3c.dom.Comment;
  47 import org.w3c.dom.DOMConfiguration;
  48 import org.w3c.dom.DOMError;
  49 import org.w3c.dom.DOMErrorHandler;
  50 import org.w3c.dom.DOMException;
  51 import org.w3c.dom.DOMStringList;
  52 import org.w3c.dom.Document;
  53 import org.w3c.dom.DocumentFragment;
  54 import org.w3c.dom.Element;
  55 import org.w3c.dom.NamedNodeMap;
  56 import org.w3c.dom.Node;
  57 import org.w3c.dom.ProcessingInstruction;
  58 import org.w3c.dom.ls.LSException;
  59 import org.w3c.dom.ls.LSOutput;
  60 import org.w3c.dom.ls.LSSerializer;
  61 import org.w3c.dom.ls.LSSerializerFilter;
  62 
  63 /**
  64  * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer by
  65  * delegating serialization calls to <CODE>XMLSerializer</CODE>. LSSerializer
  66  * provides an API for serializing (writing) a DOM document out in an XML
  67  * document. The XML data is written to an output stream. During serialization
  68  * of XML data, namespace fixup is done when possible as defined in DOM Level 3
  69  * Core, Appendix B.
  70  *
  71  * @author Elena Litani, IBM
  72  * @author Gopal Sharma, Sun Microsystems
  73  * @author Arun Yadav, Sun Microsystems
  74  * @author Sunitha Reddy, Sun Microsystems
  75  *
  76  * @deprecated As of JDK 9, Xerces 2.9.0, replaced by
  77  * {@link com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl}
  78  */
  79 @Deprecated
  80 public class DOMSerializerImpl implements LSSerializer, DOMConfiguration {
  81 
  82     // TODO: When DOM Level 3 goes to REC replace method calls using
  83     // reflection for: getXmlEncoding, getInputEncoding and getXmlEncoding
  84     // with regular static calls on the Document object.
  85     // data
  86     // serializer
  87     private XMLSerializer serializer;
  88 
  89     // XML 1.1 serializer
  90     private XML11Serializer xml11Serializer;
  91 
  92     //Recognized parameters
  93     private DOMStringList fRecognizedParameters;
  94 
  95     /**
  96      * REVISIT: Currently we handle 3 different configurations, would be nice
  97      * just have one configuration that has different recognized parameters
  98      * depending if it is used in Core/LS.
  99      */
 100     protected short features = 0;
 101 
 102     protected final static short NAMESPACES = 0x1 << 0;
 103     protected final static short WELLFORMED = 0x1 << 1;
 104     protected final static short ENTITIES = 0x1 << 2;
 105     protected final static short CDATA = 0x1 << 3;
 106     protected final static short SPLITCDATA = 0x1 << 4;
 107     protected final static short COMMENTS = 0x1 << 5;
 108     protected final static short DISCARDDEFAULT = 0x1 << 6;
 109     protected final static short INFOSET = 0x1 << 7;
 110     protected final static short XMLDECL = 0x1 << 8;
 111     protected final static short NSDECL = 0x1 << 9;
 112     protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1 << 10;
 113     protected final static short PRETTY_PRINT = 0x1 << 11;
 114 
 115     // well-formness checking
 116     private DOMErrorHandler fErrorHandler = null;
 117     private final DOMErrorImpl fError = new DOMErrorImpl();
 118     private final DOMLocatorImpl fLocator = new DOMLocatorImpl();
 119 
 120     /**
 121      * Constructs a new LSSerializer. The constructor turns on the namespace
 122      * support in <code>XMLSerializer</code> and initializes the following
 123      * fields: fNSBinder, fLocalNSBinder, fSymbolTable, fEmptySymbol,
 124      * fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures.
 125      */
 126     public DOMSerializerImpl() {
 127         // set default features
 128         features |= NAMESPACES;
 129         features |= ENTITIES;
 130         features |= COMMENTS;
 131         features |= CDATA;
 132         features |= SPLITCDATA;
 133         features |= WELLFORMED;
 134         features |= NSDECL;
 135         features |= DOM_ELEMENT_CONTENT_WHITESPACE;
 136         features |= DISCARDDEFAULT;
 137         features |= XMLDECL;
 138 
 139         serializer = new XMLSerializer();
 140         initSerializer(serializer);
 141     }
 142 
 143     //
 144     // LSSerializer methods
 145     //
 146     public DOMConfiguration getDomConfig() {
 147         return this;
 148     }
 149 
 150     /**
 151      * DOM L3-EXPERIMENTAL: Setter for boolean and object parameters
 152      */
 153     public void setParameter(String name, Object value) throws DOMException {
 154         if (value instanceof Boolean) {
 155             boolean state = ((Boolean) value).booleanValue();
 156             if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
 157                 if (state) {
 158                     features &= ~ENTITIES;
 159                     features &= ~CDATA;
 160                     features |= NAMESPACES;
 161                     features |= NSDECL;
 162                     features |= WELLFORMED;
 163                     features |= COMMENTS;
 164                 }
 165                 // false does not have any effect
 166             } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
 167                 features
 168                         = (short) (state ? features | XMLDECL : features & ~XMLDECL);
 169             } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
 170                 features
 171                         = (short) (state
 172                         ? features | NAMESPACES
 173                         : features & ~NAMESPACES);
 174                 serializer.fNamespaces = state;
 175             } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
 176                 features
 177                         = (short) (state
 178                         ? features | SPLITCDATA
 179                         : features & ~SPLITCDATA);
 180             } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
 181                 features
 182                         = (short) (state
 183                         ? features | DISCARDDEFAULT
 184                         : features & ~DISCARDDEFAULT);
 185             } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
 186                 features
 187                         = (short) (state
 188                         ? features | WELLFORMED
 189                         : features & ~WELLFORMED);
 190             } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
 191                 features
 192                         = (short) (state
 193                         ? features | ENTITIES
 194                         : features & ~ENTITIES);
 195             } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
 196                 features
 197                         = (short) (state
 198                         ? features | CDATA
 199                         : features & ~CDATA);
 200             } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
 201                 features
 202                         = (short) (state
 203                         ? features | COMMENTS
 204                         : features & ~COMMENTS);
 205             } else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
 206                 features
 207                         = (short) (state
 208                         ? features | PRETTY_PRINT
 209                         : features & ~PRETTY_PRINT);
 210             } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
 211                     || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
 212                     || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
 213                     || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
 214                     || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
 215                 //  || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
 216                 // true is not supported
 217                 if (state) {
 218                     String msg
 219                             = DOMMessageFormatter.formatMessage(
 220                                     DOMMessageFormatter.DOM_DOMAIN,
 221                                     "FEATURE_NOT_SUPPORTED",
 222                                     new Object[]{name});
 223                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
 224                 }
 225             } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
 226                 //namespace-declaration has effect only if namespaces is true
 227                 features
 228                         = (short) (state
 229                         ? features | NSDECL
 230                         : features & ~NSDECL);
 231                 serializer.fNamespacePrefixes = state;
 232             } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
 233                     || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
 234                 // false is not supported
 235                 if (!state) {
 236                     String msg
 237                             = DOMMessageFormatter.formatMessage(
 238                                     DOMMessageFormatter.DOM_DOMAIN,
 239                                     "FEATURE_NOT_SUPPORTED",
 240                                     new Object[]{name});
 241                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
 242                 }
 243             } else {
 244                 String msg
 245                         = DOMMessageFormatter.formatMessage(
 246                                 DOMMessageFormatter.DOM_DOMAIN,
 247                                 "FEATURE_NOT_FOUND",
 248                                 new Object[]{name});
 249                 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
 250             }
 251         } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
 252             if (value == null || value instanceof DOMErrorHandler) {
 253                 fErrorHandler = (DOMErrorHandler) value;
 254             } else {
 255                 String msg
 256                         = DOMMessageFormatter.formatMessage(
 257                                 DOMMessageFormatter.DOM_DOMAIN,
 258                                 "TYPE_MISMATCH_ERR",
 259                                 new Object[]{name});
 260                 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
 261             }
 262         } else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
 263                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
 264                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)
 265                 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
 266                 && value != null) {
 267             String msg
 268                     = DOMMessageFormatter.formatMessage(
 269                             DOMMessageFormatter.DOM_DOMAIN,
 270                             "FEATURE_NOT_SUPPORTED",
 271                             new Object[]{name});
 272             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
 273         } else {
 274             String msg
 275                     = DOMMessageFormatter.formatMessage(
 276                             DOMMessageFormatter.DOM_DOMAIN,
 277                             "FEATURE_NOT_FOUND",
 278                             new Object[]{name});
 279             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
 280         }
 281     }
 282 
 283     /**
 284      * DOM L3-EXPERIMENTAL: Check if parameter can be set
 285      */
 286     public boolean canSetParameter(String name, Object state) {
 287         if (state == null) {
 288             return true;
 289         }
 290 
 291         if (state instanceof Boolean) {
 292             boolean value = ((Boolean) state).booleanValue();
 293             if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)
 294                 || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)
 295                 || name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)
 296                 || name.equalsIgnoreCase(Constants.DOM_XMLDECL)
 297                 || name.equalsIgnoreCase(Constants.DOM_WELLFORMED)
 298                 || name.equalsIgnoreCase(Constants.DOM_INFOSET)
 299                 || name.equalsIgnoreCase(Constants.DOM_ENTITIES)
 300                 || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)
 301                 || name.equalsIgnoreCase(Constants.DOM_COMMENTS)
 302                 || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)
 303                 || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
 304                 // both values supported
 305                 return true;
 306             } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
 307                 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
 308                 || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
 309                 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
 310                 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
 311                 // || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
 312                 // true is not supported
 313                 return !value;
 314             } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
 315                 || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
 316                 // false is not supported
 317                 return value;
 318             }
 319         } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)
 320                 && state == null || state instanceof DOMErrorHandler) {
 321             return true;
 322         }
 323 
 324         return false;
 325     }
 326 
 327     /**
 328      * DOM Level 3 Core CR - Experimental.
 329      *
 330      * The list of the parameters supported by this
 331      * <code>DOMConfiguration</code> object and for which at least one value can
 332      * be set by the application. Note that this list can also contain parameter
 333      * names defined outside this specification.
 334      */
 335     public DOMStringList getParameterNames() {
 336 
 337         if (fRecognizedParameters == null) {
 338             List<String> parameters = new ArrayList<>();
 339 
 340             //Add DOM recognized parameters
 341             //REVISIT: Would have been nice to have a list of
 342             //recognized parameters.
 343             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             //parameters.add(Constants.DOM_SCHEMA_LOCATION);
 364             //parameters.add(Constants.DOM_SCHEMA_TYPE);
 365 
 366             //Add recognized xerces features and properties
 367             fRecognizedParameters = new DOMStringListImpl(parameters);
 368         }
 369 
 370         return fRecognizedParameters;
 371     }
 372 
 373     /**
 374      * DOM L3-EXPERIMENTAL: Getter for boolean and object parameters
 375      */
 376     public Object getParameter(String name) throws DOMException {
 377         if (name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
 378             return null;
 379         } else 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_FORMAT_PRETTY_PRINT)) {
 401             return ((features & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE;
 402         } else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
 403             if ((features & ENTITIES) == 0
 404                     && (features & CDATA) == 0
 405                     && (features & NAMESPACES) != 0
 406                     && (features & NSDECL) != 0
 407                     && (features & WELLFORMED) != 0
 408                     && (features & COMMENTS) != 0) {
 409                 return Boolean.TRUE;
 410             }
 411             return Boolean.FALSE;
 412         } else if (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 (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
 422                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
 423                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
 424             String msg
 425                     = DOMMessageFormatter.formatMessage(
 426                             DOMMessageFormatter.DOM_DOMAIN,
 427                             "FEATURE_NOT_SUPPORTED",
 428                             new Object[]{name});
 429             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
 430         } else {
 431             String msg
 432                     = DOMMessageFormatter.formatMessage(
 433                             DOMMessageFormatter.DOM_DOMAIN,
 434                             "FEATURE_NOT_FOUND",
 435                             new Object[]{name});
 436             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
 437         }
 438     }
 439 
 440     /**
 441      * DOM L3 EXPERIMENTAL: Serialize the specified node as described above in
 442      * the description of <code>LSSerializer</code>. The result of serializing
 443      * the node is returned as a string. Writing a Document or Entity node
 444      * produces a serialized form that is well formed XML. Writing other node
 445      * types produces a fragment of text in a form that is not fully defined by
 446      * this document, but that should be useful to a human for debugging or
 447      * diagnostic purposes.
 448      *
 449      * @param wnode The node to be written.
 450      * @return Returns the serialized data
 451      * @exception DOMException DOMSTRING_SIZE_ERR: The resulting string is too
 452      * long to fit in a <code>DOMString</code>.
 453      * @exception LSException SERIALIZE_ERR: Unable to serialize the node. DOM
 454      * applications should attach a <code>DOMErrorHandler</code> using the
 455      * parameter &quot;<i>error-handler</i>&quot; to get details on error.
 456      */
 457     public String writeToString(Node wnode) throws DOMException, LSException {
 458         // determine which serializer to use:
 459         XMLSerializer ser = null;
 460         String ver = _getXmlVersion(wnode);
 461         if (ver != null && ver.equals("1.1")) {
 462             if (xml11Serializer == null) {
 463                 xml11Serializer = new XML11Serializer();
 464                 initSerializer(xml11Serializer);
 465             }
 466             // copy setting from "main" serializer to XML 1.1 serializer
 467             copySettings(serializer, xml11Serializer);
 468             ser = xml11Serializer;
 469         } else {
 470             ser = serializer;
 471         }
 472 
 473         StringWriter destination = new StringWriter();
 474         try {
 475             prepareForSerialization(ser, wnode);
 476             ser._format.setEncoding("UTF-16");
 477             ser.setOutputCharStream(destination);
 478             if (wnode.getNodeType() == Node.DOCUMENT_NODE) {
 479                 ser.serialize((Document) wnode);
 480             } else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
 481                 ser.serialize((DocumentFragment) wnode);
 482             } else if (wnode.getNodeType() == Node.ELEMENT_NODE) {
 483                 ser.serialize((Element) wnode);
 484             } else if (wnode.getNodeType() == Node.TEXT_NODE
 485                     || wnode.getNodeType() == Node.COMMENT_NODE
 486                     || wnode.getNodeType() == Node.ENTITY_REFERENCE_NODE
 487                     || wnode.getNodeType() == Node.CDATA_SECTION_NODE
 488                     || wnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
 489                 ser.serialize(wnode);
 490             } else {
 491                 String msg = DOMMessageFormatter.formatMessage(
 492                         DOMMessageFormatter.SERIALIZER_DOMAIN,
 493                         "unable-to-serialize-node", null);
 494                 if (ser.fDOMErrorHandler != null) {
 495                     DOMErrorImpl error = new DOMErrorImpl();
 496                     error.fType = "unable-to-serialize-node";
 497                     error.fMessage = msg;
 498                     error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
 499                     ser.fDOMErrorHandler.handleError(error);
 500                 }
 501                 throw new LSException(LSException.SERIALIZE_ERR, msg);
 502             }
 503         } catch (LSException lse) {
 504             // Rethrow LSException.
 505             throw lse;
 506         } catch (AbortException e) {
 507             return null;
 508         } catch (RuntimeException e) {
 509             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
 510         } catch (IOException ioe) {
 511             // REVISIT: A generic IOException doesn't provide enough information
 512             // to determine that the serialized document is too large to fit
 513             // into a string. This could have thrown for some other reason. -- mrglavas
 514             String msg = DOMMessageFormatter.formatMessage(
 515                     DOMMessageFormatter.DOM_DOMAIN,
 516                     "STRING_TOO_LONG",
 517                     new Object[]{ioe.getMessage()});
 518             throw new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg);
 519         } finally {
 520             ser.clearDocumentState();
 521         }
 522         return destination.toString();
 523     }
 524 
 525     /**
 526      * DOM L3 EXPERIMENTAL: The end-of-line sequence of characters to be used in
 527      * the XML being written out. The only permitted values are these:
 528      * <dl>
 529      * <dt><code>null</code></dt>
 530      * <dd>
 531      * Use a default end-of-line sequence. DOM implementations should choose the
 532      * default to match the usual convention for text files in the environment
 533      * being used. Implementations must choose a default sequence that matches
 534      * one of those allowed by 2.11 "End-of-Line Handling". </dd>
 535      * <dt>CR</dt>
 536      * <dd>The carriage-return character (#xD).</dd>
 537      * <dt>CR-LF</dt>
 538      * <dd> The carriage-return and line-feed characters (#xD #xA). </dd>
 539      * <dt>LF</dt>
 540      * <dd> The line-feed character (#xA). </dd>
 541      * </dl>
 542      * <br>The default value for this attribute is <code>null</code>.
 543      */
 544     public void setNewLine(String newLine) {
 545         serializer._format.setLineSeparator(newLine);
 546     }
 547 
 548     /**
 549      * DOM L3 EXPERIMENTAL: The end-of-line sequence of characters to be used in
 550      * the XML being written out. The only permitted values are these:
 551      * <dl>
 552      * <dt><code>null</code></dt>
 553      * <dd>
 554      * Use a default end-of-line sequence. DOM implementations should choose the
 555      * default to match the usual convention for text files in the environment
 556      * being used. Implementations must choose a default sequence that matches
 557      * one of those allowed by 2.11 "End-of-Line Handling". </dd>
 558      * <dt>CR</dt>
 559      * <dd>The carriage-return character (#xD).</dd>
 560      * <dt>CR-LF</dt>
 561      * <dd> The carriage-return and line-feed characters (#xD #xA). </dd>
 562      * <dt>LF</dt>
 563      * <dd> The line-feed character (#xA). </dd>
 564      * </dl>
 565      * <br>The default value for this attribute is <code>null</code>.
 566      */
 567     public String getNewLine() {
 568         return serializer._format.getLineSeparator();
 569     }
 570 
 571     /**
 572      * When the application provides a filter, the serializer will call out to
 573      * the filter before serializing each Node. Attribute nodes are never passed
 574      * to the filter. The filter implementation can choose to remove the node
 575      * from the stream or to terminate the serialization early.
 576      */
 577     public LSSerializerFilter getFilter() {
 578         return serializer.fDOMFilter;
 579     }
 580 
 581     /**
 582      * When the application provides a filter, the serializer will call out to
 583      * the filter before serializing each Node. Attribute nodes are never passed
 584      * to the filter. The filter implementation can choose to remove the node
 585      * from the stream or to terminate the serialization early.
 586      */
 587     public void setFilter(LSSerializerFilter filter) {
 588         serializer.fDOMFilter = filter;
 589     }
 590 
 591     // this initializes a newly-created serializer
 592     private void initSerializer(XMLSerializer ser) {
 593         ser.fNSBinder = new NamespaceSupport();
 594         ser.fLocalNSBinder = new NamespaceSupport();
 595         ser.fSymbolTable = new SymbolTable();
 596     }
 597 
 598     // copies all settings that could have been modified
 599     // by calls to LSSerializer methods from one serializer to another.
 600     // IMPORTANT:  if new methods are implemented or more settings of
 601     // the serializer are made alterable, this must be
 602     // reflected in this method!
 603     private void copySettings(XMLSerializer src, XMLSerializer dest) {
 604         dest.fDOMErrorHandler = fErrorHandler;
 605         dest._format.setEncoding(src._format.getEncoding());
 606         dest._format.setLineSeparator(src._format.getLineSeparator());
 607         dest.fDOMFilter = src.fDOMFilter;
 608     }//copysettings
 609 
 610     /**
 611      * Serialize the specified node as described above in the general
 612      * description of the <code>LSSerializer</code> interface. The output is
 613      * written to the supplied <code>LSOutput</code>.
 614      * <br> When writing to a <code>LSOutput</code>, the encoding is found by
 615      * looking at the encoding information that is reachable through the
 616      * <code>LSOutput</code> and the item to be written (or its owner document)
 617      * in this order:
 618      * <ol>
 619      * <li> <code>LSOutput.encoding</code>,
 620      * </li>
 621      * <li>
 622      * <code>Document.actualEncoding</code>,
 623      * </li>
 624      * <li>
 625      * <code>Document.xmlEncoding</code>.
 626      * </li>
 627      * </ol>
 628      * <br> If no encoding is reachable through the above properties, a default
 629      * encoding of "UTF-8" will be used.
 630      * <br> If the specified encoding is not supported an "unsupported-encoding"
 631      * error is raised.
 632      * <br> If no output is specified in the <code>LSOutput</code>, a
 633      * "no-output-specified" error is raised.
 634      *
 635      * @param node The node to serialize.
 636      * @param destination The destination for the serialized DOM.
 637      * @return Returns <code>true</code> if <code>node</code> was successfully
 638      * serialized and <code>false</code> in case the node couldn't be
 639      * serialized.
 640      */
 641     public boolean write(Node node, LSOutput destination) throws LSException {
 642 
 643         if (node == null) {
 644             return false;
 645         }
 646 
 647         XMLSerializer ser = null;
 648         String ver = _getXmlVersion(node);
 649         //determine which serializer to use:
 650         if (ver != null && ver.equals("1.1")) {
 651             if (xml11Serializer == null) {
 652                 xml11Serializer = new XML11Serializer();
 653                 initSerializer(xml11Serializer);
 654             }
 655             //copy setting from "main" serializer to XML 1.1 serializer
 656             copySettings(serializer, xml11Serializer);
 657             ser = xml11Serializer;
 658         } else {
 659             ser = serializer;
 660         }
 661 
 662         String encoding = null;
 663         if ((encoding = destination.getEncoding()) == null) {
 664             encoding = _getInputEncoding(node);
 665             if (encoding == null) {
 666                 encoding = _getXmlEncoding(node);
 667                 if (encoding == null) {
 668                     encoding = "UTF-8";
 669                 }
 670             }
 671         }
 672         try {
 673             prepareForSerialization(ser, node);
 674             ser._format.setEncoding(encoding);
 675             OutputStream outputStream = destination.getByteStream();
 676             Writer writer = destination.getCharacterStream();
 677             String uri = destination.getSystemId();
 678             if (writer == null) {
 679                 if (outputStream == null) {
 680                     if (uri == null) {
 681                         String msg = DOMMessageFormatter.formatMessage(
 682                                 DOMMessageFormatter.SERIALIZER_DOMAIN,
 683                                 "no-output-specified", null);
 684                         if (ser.fDOMErrorHandler != null) {
 685                             DOMErrorImpl error = new DOMErrorImpl();
 686                             error.fType = "no-output-specified";
 687                             error.fMessage = msg;
 688                             error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
 689                             ser.fDOMErrorHandler.handleError(error);
 690                         }
 691                         throw new LSException(LSException.SERIALIZE_ERR, msg);
 692                     } else {
 693                         ser.setOutputByteStream(XMLEntityManager.createOutputStream(uri));
 694                     }
 695                 } else {
 696                     // byte stream was specified
 697                     ser.setOutputByteStream(outputStream);
 698                 }
 699             } else {
 700                 // character stream is specified
 701                 ser.setOutputCharStream(writer);
 702             }
 703 
 704             if (node.getNodeType() == Node.DOCUMENT_NODE) {
 705                 ser.serialize((Document) node);
 706             } else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
 707                 ser.serialize((DocumentFragment) node);
 708             } else if (node.getNodeType() == Node.ELEMENT_NODE) {
 709                 ser.serialize((Element) node);
 710             } else if (node.getNodeType() == Node.TEXT_NODE
 711                     || node.getNodeType() == Node.COMMENT_NODE
 712                     || node.getNodeType() == Node.ENTITY_REFERENCE_NODE
 713                     || node.getNodeType() == Node.CDATA_SECTION_NODE
 714                     || node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
 715                 ser.serialize(node);
 716             } else {
 717                 return false;
 718             }
 719         } catch (UnsupportedEncodingException ue) {
 720             if (ser.fDOMErrorHandler != null) {
 721                 DOMErrorImpl error = new DOMErrorImpl();
 722                 error.fException = ue;
 723                 error.fType = "unsupported-encoding";
 724                 error.fMessage = ue.getMessage();
 725                 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
 726                 ser.fDOMErrorHandler.handleError(error);
 727             }
 728             throw new LSException(LSException.SERIALIZE_ERR,
 729                     DOMMessageFormatter.formatMessage(
 730                             DOMMessageFormatter.SERIALIZER_DOMAIN,
 731                             "unsupported-encoding", null));
 732             //return false;
 733         } catch (LSException lse) {
 734             // Rethrow LSException.
 735             throw lse;
 736         } catch (AbortException e) {
 737             return false;
 738         } catch (RuntimeException e) {
 739             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
 740         } catch (Exception e) {
 741             if (ser.fDOMErrorHandler != null) {
 742                 DOMErrorImpl error = new DOMErrorImpl();
 743                 error.fException = e;
 744                 error.fMessage = e.getMessage();
 745                 error.fSeverity = DOMError.SEVERITY_ERROR;
 746                 ser.fDOMErrorHandler.handleError(error);
 747 
 748             }
 749             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
 750         } finally {
 751             ser.clearDocumentState();
 752         }
 753         return true;
 754 
 755     } //write
 756 
 757     /**
 758      * Serialize the specified node as described above in the general
 759      * description of the <code>LSSerializer</code> interface. The output is
 760      * written to the supplied URI.
 761      * <br> When writing to a URI, the encoding is found by looking at the
 762      * encoding information that is reachable through the item to be written (or
 763      * its owner document) in this order:
 764      * <ol>
 765      * <li>
 766      * <code>Document.inputEncoding</code>,
 767      * </li>
 768      * <li>
 769      * <code>Document.xmlEncoding</code>.
 770      * </li>
 771      * </ol>
 772      * <br> If no encoding is reachable through the above properties, a default
 773      * encoding of "UTF-8" will be used.
 774      * <br> If the specified encoding is not supported an "unsupported-encoding"
 775      * error is raised.
 776      *
 777      * @param node The node to serialize.
 778      * @param URI The URI to write to.
 779      * @return Returns <code>true</code> if <code>node</code> was successfully
 780      * serialized and <code>false</code> in case the node couldn't be
 781      * serialized.
 782      */
 783     public boolean writeToURI(Node node, String URI) throws LSException {
 784         if (node == null) {
 785             return false;
 786         }
 787 
 788         XMLSerializer ser = null;
 789         String ver = _getXmlVersion(node);
 790 
 791         if (ver != null && ver.equals("1.1")) {
 792             if (xml11Serializer == null) {
 793                 xml11Serializer = new XML11Serializer();
 794                 initSerializer(xml11Serializer);
 795             }
 796             // copy setting from "main" serializer to XML 1.1 serializer
 797             copySettings(serializer, xml11Serializer);
 798             ser = xml11Serializer;
 799         } else {
 800             ser = serializer;
 801         }
 802 
 803         String encoding = _getInputEncoding(node);
 804         if (encoding == null) {
 805             encoding = _getXmlEncoding(node);
 806             if (encoding == null) {
 807                 encoding = "UTF-8";
 808             }
 809         }
 810 
 811         try {
 812             prepareForSerialization(ser, node);
 813             ser._format.setEncoding(encoding);
 814             ser.setOutputByteStream(XMLEntityManager.createOutputStream(URI));
 815 
 816             if (node.getNodeType() == Node.DOCUMENT_NODE) {
 817                 ser.serialize((Document) node);
 818             } else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
 819                 ser.serialize((DocumentFragment) node);
 820             } else if (node.getNodeType() == Node.ELEMENT_NODE) {
 821                 ser.serialize((Element) node);
 822             } else if (node.getNodeType() == Node.TEXT_NODE
 823                     || node.getNodeType() == Node.COMMENT_NODE
 824                     || node.getNodeType() == Node.ENTITY_REFERENCE_NODE
 825                     || node.getNodeType() == Node.CDATA_SECTION_NODE
 826                     || node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
 827                 ser.serialize(node);
 828             } else {
 829                 return false;
 830             }
 831         } catch (LSException lse) {
 832             // Rethrow LSException.
 833             throw lse;
 834         } catch (AbortException e) {
 835             return false;
 836         } catch (RuntimeException e) {
 837             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
 838         } catch (Exception e) {
 839             if (ser.fDOMErrorHandler != null) {
 840                 DOMErrorImpl error = new DOMErrorImpl();
 841                 error.fException = e;
 842                 error.fMessage = e.getMessage();
 843                 error.fSeverity = DOMError.SEVERITY_ERROR;
 844                 ser.fDOMErrorHandler.handleError(error);
 845             }
 846             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
 847         } finally {
 848             ser.clearDocumentState();
 849         }
 850         return true;
 851     } //writeURI
 852 
 853     //
 854     //  Private methods
 855     //
 856     private void prepareForSerialization(XMLSerializer ser, Node node) {
 857         ser.reset();
 858         ser.features = features;
 859         ser.fDOMErrorHandler = fErrorHandler;
 860         ser.fNamespaces = (features & NAMESPACES) != 0;
 861         ser.fNamespacePrefixes = (features & NSDECL) != 0;
 862         ser._format.setIndenting((features & PRETTY_PRINT) != 0);
 863         ser._format.setOmitComments((features & COMMENTS) == 0);
 864         ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0);
 865 
 866         if ((features & WELLFORMED) != 0) {
 867             // REVISIT: this is inefficient implementation of well-formness. Instead, we should check
 868             // well-formness as we serialize the tree
 869             Node next, root;
 870             root = node;
 871             Method versionChanged;
 872             boolean verifyNames = true;
 873             Document document = (node.getNodeType() == Node.DOCUMENT_NODE)
 874                     ? (Document) node
 875                     : node.getOwnerDocument();
 876             try {
 877                 versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class<?>[]{});
 878                 if (versionChanged != null) {
 879                     verifyNames = ((Boolean) versionChanged.invoke(document, (Object[]) null)).booleanValue();
 880                 }
 881             } catch (Exception e) {
 882                 //no way to test the version...
 883                 //ignore the exception
 884             }
 885             if (node.getFirstChild() != null) {
 886                 while (node != null) {
 887                     verify(node, verifyNames, false);
 888                     // Move down to first child
 889                     next = node.getFirstChild();
 890                     // No child nodes, so walk tree
 891                     while (next == null) {
 892                         // Move to sibling if possible.
 893                         next = node.getNextSibling();
 894                         if (next == null) {
 895                             node = node.getParentNode();
 896                             if (root == node) {
 897                                 next = null;
 898                                 break;
 899                             }
 900                             next = node.getNextSibling();
 901                         }
 902                     }
 903                     node = next;
 904                 }
 905             } else {
 906                 verify(node, verifyNames, false);
 907             }
 908         }
 909     }
 910 
 911     private void verify(Node node, boolean verifyNames, boolean xml11Version) {
 912 
 913         int type = node.getNodeType();
 914         fLocator.fRelatedNode = node;
 915         boolean wellformed;
 916         switch (type) {
 917             case Node.DOCUMENT_NODE: {
 918                 break;
 919             }
 920             case Node.DOCUMENT_TYPE_NODE: {
 921                 break;
 922             }
 923             case Node.ELEMENT_NODE: {
 924                 if (verifyNames) {
 925                     if ((features & NAMESPACES) != 0) {
 926                         wellformed = CoreDocumentImpl.isValidQName(node.getPrefix(), node.getLocalName(), xml11Version);
 927                     } else {
 928                         wellformed = CoreDocumentImpl.isXMLName(node.getNodeName(), xml11Version);
 929                     }
 930                     if (!wellformed) {
 931                         if (fErrorHandler != null) {
 932                             String msg = DOMMessageFormatter.formatMessage(
 933                                     DOMMessageFormatter.DOM_DOMAIN,
 934                                     "wf-invalid-character-in-node-name",
 935                                     new Object[]{"Element", node.getNodeName()});
 936                             DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
 937                                     "wf-invalid-character-in-node-name");
 938                         }
 939                     }
 940                 }
 941 
 942                 NamedNodeMap attributes = (node.hasAttributes()) ? node.getAttributes() : null;
 943                 if (attributes != null) {
 944                     for (int i = 0; i < attributes.getLength(); ++i) {
 945                         Attr attr = (Attr) attributes.item(i);
 946                         fLocator.fRelatedNode = attr;
 947                         DOMNormalizer.isAttrValueWF(fErrorHandler, fError, fLocator,
 948                                 attributes, attr, attr.getValue(), xml11Version);
 949                         if (verifyNames) {
 950                             wellformed = CoreDocumentImpl.isXMLName(attr.getNodeName(), xml11Version);
 951                             if (!wellformed) {
 952                                 String msg
 953                                         = DOMMessageFormatter.formatMessage(
 954                                                 DOMMessageFormatter.DOM_DOMAIN,
 955                                                 "wf-invalid-character-in-node-name",
 956                                                 new Object[]{"Attr", node.getNodeName()});
 957                                 DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
 958                                         "wf-invalid-character-in-node-name");
 959                             }
 960                         }
 961                     }
 962 
 963                 }
 964 
 965                 break;
 966             }
 967 
 968             case Node.COMMENT_NODE: {
 969                 // only verify well-formness if comments included in the tree
 970                 if ((features & COMMENTS) != 0) {
 971                     DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment) node).getData(), xml11Version);
 972                 }
 973                 break;
 974             }
 975             case Node.ENTITY_REFERENCE_NODE: {
 976                 // only if entity is preserved in the tree
 977                 if (verifyNames && (features & ENTITIES) != 0) {
 978                     CoreDocumentImpl.isXMLName(node.getNodeName(), xml11Version);
 979                 }
 980                 break;
 981 
 982             }
 983             case Node.CDATA_SECTION_NODE: {
 984                 // verify content
 985                 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
 986                 // the ]]> string will be checked during serialization
 987                 break;
 988             }
 989             case Node.TEXT_NODE: {
 990                 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
 991                 break;
 992             }
 993             case Node.PROCESSING_INSTRUCTION_NODE: {
 994                 ProcessingInstruction pinode = (ProcessingInstruction) node;
 995                 String target = pinode.getTarget();
 996                 if (verifyNames) {
 997                     if (xml11Version) {
 998                         wellformed = XML11Char.isXML11ValidName(target);
 999                     } else {
1000                         wellformed = XMLChar.isValidName(target);
1001                     }
1002 
1003                     if (!wellformed) {
1004                         String msg
1005                                 = DOMMessageFormatter.formatMessage(
1006                                         DOMMessageFormatter.DOM_DOMAIN,
1007                                         "wf-invalid-character-in-node-name",
1008                                         new Object[]{"Element", node.getNodeName()});
1009                         DOMNormalizer.reportDOMError(
1010                                 fErrorHandler,
1011                                 fError,
1012                                 fLocator,
1013                                 msg,
1014                                 DOMError.SEVERITY_FATAL_ERROR,
1015                                 "wf-invalid-character-in-node-name");
1016                     }
1017                 }
1018                 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version);
1019                 break;
1020             }
1021         }
1022         fLocator.fRelatedNode = null;
1023     }
1024 
1025     private String _getXmlVersion(Node node) {
1026         Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
1027                 ? (Document) node : node.getOwnerDocument();
1028         if (doc != null) {
1029             try {
1030                 return doc.getXmlVersion();
1031             } // The VM ran out of memory or there was some other serious problem. Re-throw.
1032              catch (VirtualMachineError | ThreadDeath vme) {
1033                 throw vme;
1034             } // Ignore all other exceptions and errors
1035             catch (Throwable t) {
1036             }
1037         }
1038         return null;
1039     }
1040 
1041     private String _getInputEncoding(Node node) {
1042         Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
1043                 ? (Document) node : node.getOwnerDocument();
1044         if (doc != null) {
1045             try {
1046                 return doc.getInputEncoding();
1047             } // The VM ran out of memory or there was some other serious problem. Re-throw.
1048             catch (VirtualMachineError | ThreadDeath vme) {
1049                 throw vme;
1050             } // Ignore all other exceptions and errors
1051             catch (Throwable t) {
1052             }
1053         }
1054         return null;
1055     }
1056 
1057     private String _getXmlEncoding(Node node) {
1058         Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
1059                 ? (Document) node : node.getOwnerDocument();
1060         if (doc != null) {
1061             try {
1062                 return doc.getXmlEncoding();
1063             } // The VM ran out of memory or there was some other serious problem. Re-throw.
1064             catch (VirtualMachineError | ThreadDeath vme) {
1065                 throw vme;
1066             } // Ignore all other exceptions and errors
1067             catch (Throwable t) {
1068             }
1069         }
1070         return null;
1071     }
1072 
1073 } //DOMSerializerImpl