jaxp/src/com/sun/org/apache/xml/internal/serializer/dom3/LSSerializerImpl.java
changeset 25834 aba3efbf4ec5
equal deleted inserted replaced
25833:054a597b18f8 25834:aba3efbf4ec5
       
     1 /*
       
     2  * Licensed to the Apache Software Foundation (ASF) under one
       
     3  * or more contributor license agreements. See the NOTICE file
       
     4  * distributed with this work for additional information
       
     5  * regarding copyright ownership. The ASF licenses this file
       
     6  * to you under the Apache License, Version 2.0 (the  "License");
       
     7  * you may not use this file except in compliance with the License.
       
     8  * You may obtain a copy of the License at
       
     9  *
       
    10  *     http://www.apache.org/licenses/LICENSE-2.0
       
    11  *
       
    12  * Unless required by applicable law or agreed to in writing, software
       
    13  * distributed under the License is distributed on an "AS IS" BASIS,
       
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    15  * See the License for the specific language governing permissions and
       
    16  * limitations under the License.
       
    17  */
       
    18 /*
       
    19  * $Id:  $
       
    20  */
       
    21 
       
    22 package com.sun.org.apache.xml.internal.serializer.dom3;
       
    23 
       
    24 import java.io.File;
       
    25 import java.io.FileOutputStream;
       
    26 import java.io.OutputStream;
       
    27 import java.io.OutputStreamWriter;
       
    28 import java.io.StringWriter;
       
    29 import java.io.UnsupportedEncodingException;
       
    30 import java.io.Writer;
       
    31 import java.net.HttpURLConnection;
       
    32 import java.net.URL;
       
    33 import java.net.URLConnection;
       
    34 import java.util.Properties;
       
    35 
       
    36 import com.sun.org.apache.xml.internal.serializer.DOM3Serializer;
       
    37 import com.sun.org.apache.xml.internal.serializer.Encodings;
       
    38 import com.sun.org.apache.xml.internal.serializer.Serializer;
       
    39 import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory;
       
    40 import com.sun.org.apache.xml.internal.serializer.SerializerFactory;
       
    41 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
       
    42 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
       
    43 import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver;
       
    44 import org.w3c.dom.DOMConfiguration;
       
    45 import org.w3c.dom.DOMError;
       
    46 import org.w3c.dom.DOMErrorHandler;
       
    47 import org.w3c.dom.DOMException;
       
    48 import org.w3c.dom.DOMStringList;
       
    49 import org.w3c.dom.Document;
       
    50 import org.w3c.dom.Node;
       
    51 import org.w3c.dom.ls.LSException;
       
    52 import org.w3c.dom.ls.LSOutput;
       
    53 import org.w3c.dom.ls.LSSerializer;
       
    54 import org.w3c.dom.ls.LSSerializerFilter;
       
    55 
       
    56 
       
    57 /**
       
    58  * Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer and
       
    59  * org.w3c.dom.ls.DOMConfiguration.  Serialization is achieved by delegating
       
    60  * serialization calls to <CODE>org.apache.xml.serializer.ToStream</CODE> or
       
    61  * one of its derived classes depending on the serialization method, while walking
       
    62  * the DOM in DOM3TreeWalker.
       
    63  * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSSerializer">org.w3c.dom.ls.LSSerializer</a>
       
    64  * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration">org.w3c.dom.DOMConfiguration</a>
       
    65  *
       
    66  * @version $Id:
       
    67  *
       
    68  * @xsl.usage internal
       
    69  */
       
    70 final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
       
    71 
       
    72     /** private data members */
       
    73     private Serializer fXMLSerializer = null;
       
    74 
       
    75     // Tracks DOMConfiguration features.
       
    76     protected int fFeatures = 0;
       
    77 
       
    78     // Common DOM serializer
       
    79     private  DOM3Serializer fDOMSerializer = null;
       
    80 
       
    81     // A filter set on the LSSerializer
       
    82     private LSSerializerFilter fSerializerFilter = null;
       
    83 
       
    84     // Stores the nodeArg parameter to speed up multiple writes of the same node.
       
    85     private Node fVisitedNode = null;
       
    86 
       
    87     // The end-of-line character sequence used in serialization.  "\n" is whats used on the web.
       
    88     private String fEndOfLine = "\n";
       
    89 
       
    90     // The DOMErrorhandler.
       
    91     private DOMErrorHandler fDOMErrorHandler = null;
       
    92 
       
    93     // The Configuration parameter to pass to the Underlying serilaizer.
       
    94     private Properties fDOMConfigProperties = null;
       
    95 
       
    96     // The encoding to use during serialization.
       
    97     private String fEncoding;
       
    98 
       
    99     // ************************************************************************
       
   100     // DOM Level 3 DOM Configuration parameter names
       
   101     // ************************************************************************
       
   102     // Parameter canonical-form, true [optional] - NOT SUPPORTED
       
   103     private final static int CANONICAL = 0x1 << 0;
       
   104 
       
   105     // Parameter cdata-sections, true [required] (default)
       
   106     private final static int CDATA = 0x1 << 1;
       
   107 
       
   108     // Parameter check-character-normalization, true [optional] - NOT SUPPORTED
       
   109     private final static int CHARNORMALIZE = 0x1 << 2;
       
   110 
       
   111     // Parameter comments, true [required] (default)
       
   112     private final static int COMMENTS = 0x1 << 3;
       
   113 
       
   114     // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
       
   115     private final static int DTNORMALIZE = 0x1 << 4;
       
   116 
       
   117     // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
       
   118     private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;
       
   119 
       
   120     // Parameter entities, true [required] (default)
       
   121     private final static int ENTITIES = 0x1 << 6;
       
   122 
       
   123     // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
       
   124     private final static int INFOSET = 0x1 << 7;
       
   125 
       
   126     // Parameter namespaces, true [required] (default)
       
   127     private final static int NAMESPACES = 0x1 << 8;
       
   128 
       
   129     // Parameter namespace-declarations, true [required] (default)
       
   130     private final static int NAMESPACEDECLS = 0x1 << 9;
       
   131 
       
   132     // Parameter normalize-characters, true [optional] - NOT SUPPORTED
       
   133     private final static int NORMALIZECHARS = 0x1 << 10;
       
   134 
       
   135     // Parameter split-cdata-sections, true [required] (default)
       
   136     private final static int SPLITCDATA = 0x1 << 11;
       
   137 
       
   138     // Parameter validate, true [optional] - NOT SUPPORTED
       
   139     private final static int VALIDATE = 0x1 << 12;
       
   140 
       
   141     // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
       
   142     private final static int SCHEMAVALIDATE = 0x1 << 13;
       
   143 
       
   144     // Parameter split-cdata-sections, true [required] (default)
       
   145     private final static int WELLFORMED = 0x1 << 14;
       
   146 
       
   147     // Parameter discard-default-content, true [required] (default)
       
   148     // Not sure how this will be used in level 2 Documents
       
   149     private final static int DISCARDDEFAULT = 0x1 << 15;
       
   150 
       
   151     // Parameter format-pretty-print, true [optional]
       
   152     private final static int PRETTY_PRINT = 0x1 << 16;
       
   153 
       
   154     // Parameter ignore-unknown-character-denormalizations, true [required] (default)
       
   155     // We currently do not support XML 1.1 character normalization
       
   156     private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;
       
   157 
       
   158     // Parameter discard-default-content, true [required] (default)
       
   159     private final static int XMLDECL = 0x1 << 18;
       
   160     // ************************************************************************
       
   161 
       
   162     // Recognized parameters for which atleast one value can be set
       
   163     private String fRecognizedParameters [] = {
       
   164             DOMConstants.DOM_CANONICAL_FORM,
       
   165             DOMConstants.DOM_CDATA_SECTIONS,
       
   166             DOMConstants.DOM_CHECK_CHAR_NORMALIZATION,
       
   167             DOMConstants.DOM_COMMENTS,
       
   168             DOMConstants.DOM_DATATYPE_NORMALIZATION,
       
   169             DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
       
   170             DOMConstants.DOM_ENTITIES,
       
   171             DOMConstants.DOM_INFOSET,
       
   172             DOMConstants.DOM_NAMESPACES,
       
   173             DOMConstants.DOM_NAMESPACE_DECLARATIONS,
       
   174             //DOMConstants.DOM_NORMALIZE_CHARACTERS,
       
   175             DOMConstants.DOM_SPLIT_CDATA,
       
   176             DOMConstants.DOM_VALIDATE,
       
   177             DOMConstants.DOM_VALIDATE_IF_SCHEMA,
       
   178             DOMConstants.DOM_WELLFORMED,
       
   179             DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
       
   180             DOMConstants.DOM_FORMAT_PRETTY_PRINT,
       
   181             DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS,
       
   182             DOMConstants.DOM_XMLDECL,
       
   183             DOMConstants.DOM_ERROR_HANDLER
       
   184     };
       
   185 
       
   186 
       
   187     /**
       
   188      * Constructor:  Creates a LSSerializerImpl object.  The underlying
       
   189      * XML 1.0 or XML 1.1 org.apache.xml.serializer.Serializer object is
       
   190      * created and initialized the first time any of the write methods are
       
   191      * invoked to serialize the Node.  Subsequent write methods on the same
       
   192      * LSSerializerImpl object will use the previously created Serializer object.
       
   193      */
       
   194     public LSSerializerImpl () {
       
   195         // set default parameters
       
   196         fFeatures |= CDATA;
       
   197         fFeatures |= COMMENTS;
       
   198         fFeatures |= ELEM_CONTENT_WHITESPACE;
       
   199         fFeatures |= ENTITIES;
       
   200         fFeatures |= NAMESPACES;
       
   201         fFeatures |= NAMESPACEDECLS;
       
   202         fFeatures |= SPLITCDATA;
       
   203         fFeatures |= WELLFORMED;
       
   204         fFeatures |= DISCARDDEFAULT;
       
   205         fFeatures |= XMLDECL;
       
   206 
       
   207         // New OutputFormat properties
       
   208         fDOMConfigProperties = new Properties();
       
   209 
       
   210         // Initialize properties to be passed on the underlying serializer
       
   211         initializeSerializerProps();
       
   212 
       
   213         // Read output_xml.properties and System Properties to initialize properties
       
   214         Properties  configProps = OutputPropertiesFactory.getDefaultMethodProperties("xml");
       
   215 
       
   216         // change xml version from 1.0 to 1.1
       
   217         //configProps.setProperty("version", "1.1");
       
   218 
       
   219         // Get a serializer that seriailizes according to the properties,
       
   220         // which in this case is to xml
       
   221         fXMLSerializer = SerializerFactory.getSerializer(configProps);
       
   222 
       
   223         // Initialize Serializer
       
   224         fXMLSerializer.setOutputFormat(fDOMConfigProperties);
       
   225     }
       
   226 
       
   227     /**
       
   228      * Initializes the underlying serializer's configuration depending on the
       
   229      * default DOMConfiguration parameters. This method must be called before a
       
   230      * node is to be serialized.
       
   231      *
       
   232      * @xsl.usage internal
       
   233      */
       
   234     public void initializeSerializerProps () {
       
   235         // canonical-form
       
   236         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   237                 + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_DEFAULT_FALSE);
       
   238 
       
   239         // cdata-sections
       
   240         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   241                 + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_DEFAULT_TRUE);
       
   242 
       
   243         // "check-character-normalization"
       
   244         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   245                 + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION,
       
   246                 DOMConstants.DOM3_DEFAULT_FALSE);
       
   247 
       
   248         // comments
       
   249         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   250                 + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE);
       
   251 
       
   252         // datatype-normalization
       
   253         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   254                 + DOMConstants.DOM_DATATYPE_NORMALIZATION,
       
   255                 DOMConstants.DOM3_DEFAULT_FALSE);
       
   256 
       
   257         // element-content-whitespace
       
   258         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   259                 + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
       
   260                 DOMConstants.DOM3_DEFAULT_TRUE);
       
   261 
       
   262         // entities
       
   263         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   264                 + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_TRUE);
       
   265         // preserve entities
       
   266         fDOMConfigProperties.setProperty(
       
   267                 OutputPropertiesFactory.S_KEY_ENTITIES, DOMConstants.S_XSL_VALUE_ENTITIES);
       
   268 
       
   269         // error-handler
       
   270         // Should we set our default ErrorHandler
       
   271         /*
       
   272          * if (fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER) != null) {
       
   273          * fDOMErrorHandler =
       
   274          * (DOMErrorHandler)fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER); }
       
   275          */
       
   276 
       
   277         // infoset
       
   278         if ((fFeatures & INFOSET) != 0) {
       
   279             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   280                     + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE);
       
   281             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   282                     + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
       
   283                     DOMConstants.DOM3_DEFAULT_TRUE);
       
   284             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   285                     + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE);
       
   286             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   287                     + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
       
   288                     DOMConstants.DOM3_DEFAULT_TRUE);
       
   289             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   290                     + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE);
       
   291             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   292                     + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_FALSE);
       
   293             // preserve entities
       
   294             fDOMConfigProperties.setProperty(
       
   295                     OutputPropertiesFactory.S_KEY_ENTITIES, "");
       
   296             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   297                     + DOMConstants.DOM_CDATA_SECTIONS,
       
   298                     DOMConstants.DOM3_DEFAULT_FALSE);
       
   299             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   300                     + DOMConstants.DOM_VALIDATE_IF_SCHEMA,
       
   301                     DOMConstants.DOM3_DEFAULT_FALSE);
       
   302             fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   303                     + DOMConstants.DOM_DATATYPE_NORMALIZATION,
       
   304                     DOMConstants.DOM3_DEFAULT_FALSE);
       
   305         }
       
   306 
       
   307         // namespaces
       
   308         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   309                 + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE);
       
   310 
       
   311         // namespace-declarations
       
   312         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   313                 + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
       
   314                 DOMConstants.DOM3_DEFAULT_TRUE);
       
   315 
       
   316         // normalize-characters
       
   317         /*
       
   318         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   319                 + DOMConstants.DOM_NORMALIZE_CHARACTERS,
       
   320                 DOMConstants.DOM3_DEFAULT_FALSE);
       
   321         */
       
   322 
       
   323         // split-cdata-sections
       
   324         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   325                 + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_DEFAULT_TRUE);
       
   326 
       
   327         // validate
       
   328         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   329                 + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_DEFAULT_FALSE);
       
   330 
       
   331         // validate-if-schema
       
   332         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   333                 + DOMConstants.DOM_VALIDATE_IF_SCHEMA,
       
   334                 DOMConstants.DOM3_DEFAULT_FALSE);
       
   335 
       
   336         // well-formed
       
   337         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   338                 + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE);
       
   339 
       
   340         // pretty-print
       
   341         fDOMConfigProperties.setProperty(
       
   342                 DOMConstants.S_XSL_OUTPUT_INDENT,
       
   343                 DOMConstants.DOM3_DEFAULT_FALSE);
       
   344         fDOMConfigProperties.setProperty(
       
   345                 OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, Integer.toString(4));
       
   346 
       
   347         //
       
   348 
       
   349         // discard-default-content
       
   350         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   351                 + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
       
   352                 DOMConstants.DOM3_DEFAULT_TRUE);
       
   353 
       
   354         // xml-declaration
       
   355         fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no");
       
   356 
       
   357     }
       
   358 
       
   359     // ************************************************************************
       
   360     // DOMConfiguraiton implementation
       
   361     // ************************************************************************
       
   362 
       
   363     /**
       
   364      * Checks if setting a parameter to a specific value is supported.
       
   365      *
       
   366      * @see org.w3c.dom.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object)
       
   367      * @since DOM Level 3
       
   368      * @param name A String containing the DOMConfiguration parameter name.
       
   369      * @param value An Object specifying the value of the corresponding parameter.
       
   370      */
       
   371     public boolean canSetParameter(String name, Object value) {
       
   372         if (value instanceof Boolean){
       
   373             if ( name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)
       
   374                     || name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)
       
   375                     || name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)
       
   376                     || name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)
       
   377                     || name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)
       
   378                     || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)
       
   379                     || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)
       
   380                     || name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)
       
   381                     || name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)
       
   382                     || name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)
       
   383                     || name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)
       
   384                     || name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)){
       
   385                 // both values supported
       
   386                 return true;
       
   387             }
       
   388             else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
       
   389                     || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
       
   390                     || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)
       
   391                     || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)
       
   392                     || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
       
   393                     // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
       
   394                     ) {
       
   395                 // true is not supported
       
   396                 return !((Boolean)value).booleanValue();
       
   397             }
       
   398             else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
       
   399                 // false is not supported
       
   400                 return ((Boolean)value).booleanValue();
       
   401             }
       
   402         }
       
   403         else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) &&
       
   404                 value == null || value instanceof DOMErrorHandler){
       
   405             return true;
       
   406         }
       
   407         return false;
       
   408     }
       
   409     /**
       
   410      * This method returns the value of a parameter if known.
       
   411      *
       
   412      * @see org.w3c.dom.DOMConfiguration#getParameter(java.lang.String)
       
   413      *
       
   414      * @param name A String containing the DOMConfiguration parameter name
       
   415      *             whose value is to be returned.
       
   416      * @return Object The value of the parameter if known.
       
   417      */
       
   418     public Object getParameter(String name) throws DOMException {
       
   419 
       
   420         if(name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)){
       
   421                       return null;
       
   422         } else if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) {
       
   423             return ((fFeatures & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   424         } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) {
       
   425             return ((fFeatures & CDATA) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   426         } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) {
       
   427             return ((fFeatures & ENTITIES) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   428         } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) {
       
   429             return ((fFeatures & NAMESPACES) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   430         } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) {
       
   431             return ((fFeatures & NAMESPACEDECLS) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   432         } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) {
       
   433             return ((fFeatures & SPLITCDATA) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   434         } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) {
       
   435             return ((fFeatures & WELLFORMED) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   436         }  else if (name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) {
       
   437             return ((fFeatures & DISCARDDEFAULT) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   438         } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
       
   439             return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   440         } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) {
       
   441             return ((fFeatures & XMLDECL) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   442         } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
       
   443             return ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) ? Boolean.TRUE : Boolean.FALSE;
       
   444         } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
       
   445             return Boolean.TRUE;
       
   446         } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
       
   447                 || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
       
   448                 || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)
       
   449                 // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
       
   450                 || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
       
   451                 || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
       
   452             return Boolean.FALSE;
       
   453         } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)){
       
   454             if ((fFeatures & ENTITIES) == 0 &&
       
   455                     (fFeatures & CDATA) == 0 &&
       
   456                     (fFeatures & ELEM_CONTENT_WHITESPACE) != 0 &&
       
   457                     (fFeatures & NAMESPACES) != 0 &&
       
   458                     (fFeatures & NAMESPACEDECLS) != 0 &&
       
   459                     (fFeatures & WELLFORMED) != 0 &&
       
   460                     (fFeatures & COMMENTS) != 0) {
       
   461                 return Boolean.TRUE;
       
   462             }
       
   463             return Boolean.FALSE;
       
   464         } else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) {
       
   465             return fDOMErrorHandler;
       
   466         } else if (
       
   467                 name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION)
       
   468                 || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) {
       
   469             return null;
       
   470         } else {
       
   471             // Here we have to add the Xalan specific DOM Message Formatter
       
   472             String msg = Utils.messages.createMessage(
       
   473                     MsgKey.ER_FEATURE_NOT_FOUND,
       
   474                     new Object[] { name });
       
   475             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
       
   476         }
       
   477     }
       
   478 
       
   479     /**
       
   480      * This method returns a of the parameters supported by this DOMConfiguration object
       
   481      * and for which at least one value can be set by the application
       
   482      *
       
   483      * @see org.w3c.dom.DOMConfiguration#getParameterNames()
       
   484      *
       
   485      * @return DOMStringList A list of DOMConfiguration parameters recognized
       
   486      *                       by the serializer
       
   487      */
       
   488     public DOMStringList getParameterNames() {
       
   489         return new DOMStringListImpl(fRecognizedParameters);
       
   490     }
       
   491 
       
   492     /**
       
   493      * This method sets the value of the named parameter.
       
   494      *
       
   495      * @see org.w3c.dom.DOMConfiguration#setParameter(java.lang.String, java.lang.Object)
       
   496      *
       
   497      * @param name A String containing the DOMConfiguration parameter name.
       
   498      * @param value An Object contaiing the parameters value to set.
       
   499      */
       
   500     public void setParameter(String name, Object value) throws DOMException {
       
   501         // If the value is a boolean
       
   502         if (value instanceof Boolean) {
       
   503             boolean state = ((Boolean) value).booleanValue();
       
   504 
       
   505             if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) {
       
   506                 fFeatures = state ? fFeatures | COMMENTS : fFeatures
       
   507                         & ~COMMENTS;
       
   508                 // comments
       
   509                 if (state) {
       
   510                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   511                             + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   512                 } else {
       
   513                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   514                             + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   515                 }
       
   516             } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) {
       
   517                 fFeatures =  state ? fFeatures | CDATA : fFeatures
       
   518                         & ~CDATA;
       
   519                 // cdata-sections
       
   520                 if (state) {
       
   521                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   522                             + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   523                 } else {
       
   524                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   525                             + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   526                 }
       
   527             } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) {
       
   528                 fFeatures = state ? fFeatures | ENTITIES : fFeatures
       
   529                         & ~ENTITIES;
       
   530                 // entities
       
   531                 if (state) {
       
   532                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   533                             + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   534                     fDOMConfigProperties.setProperty(
       
   535                             OutputPropertiesFactory.S_KEY_ENTITIES, DOMConstants.S_XSL_VALUE_ENTITIES);
       
   536                 } else {
       
   537                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   538                             + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   539                 }
       
   540             } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) {
       
   541                 fFeatures = state ? fFeatures | NAMESPACES : fFeatures
       
   542                         & ~NAMESPACES;
       
   543                 // namespaces
       
   544                 if (state) {
       
   545                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   546                             + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   547                 } else {
       
   548                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   549                             + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   550                 }
       
   551             } else if (name
       
   552                     .equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) {
       
   553                 fFeatures = state ? fFeatures | NAMESPACEDECLS
       
   554                         : fFeatures & ~NAMESPACEDECLS;
       
   555                 // namespace-declarations
       
   556                 if (state) {
       
   557                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   558                             + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   559                 } else {
       
   560                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   561                             + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   562                 }
       
   563             } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) {
       
   564                 fFeatures = state ? fFeatures | SPLITCDATA : fFeatures
       
   565                         & ~SPLITCDATA;
       
   566                 // split-cdata-sections
       
   567                 if (state) {
       
   568                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   569                             + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   570                 } else {
       
   571                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   572                             + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   573                 }
       
   574             } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) {
       
   575                 fFeatures = state ? fFeatures | WELLFORMED : fFeatures
       
   576                         & ~WELLFORMED;
       
   577                 // well-formed
       
   578                 if (state) {
       
   579                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   580                             + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   581                 } else {
       
   582                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   583                             + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   584                 }
       
   585             } else if (name
       
   586                     .equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) {
       
   587                 fFeatures = state ? fFeatures | DISCARDDEFAULT
       
   588                         : fFeatures & ~DISCARDDEFAULT;
       
   589                 // discard-default-content
       
   590                 if (state) {
       
   591                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   592                             + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   593                 } else {
       
   594                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   595                             + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   596                 }
       
   597             } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
       
   598                 fFeatures = state ? fFeatures | PRETTY_PRINT : fFeatures
       
   599                         & ~PRETTY_PRINT;
       
   600                 if (state) {
       
   601                     fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_INDENT,DOMConstants.DOM3_EXPLICIT_TRUE);
       
   602                     fDOMConfigProperties.setProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, Integer.toString(4));
       
   603                 } else {
       
   604                     fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_INDENT,DOMConstants.DOM3_EXPLICIT_FALSE);
       
   605                 }
       
   606             } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) {
       
   607                 fFeatures = state ? fFeatures | XMLDECL : fFeatures
       
   608                         & ~XMLDECL;
       
   609                 if (state) {
       
   610                     fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no");
       
   611                 } else {
       
   612                     fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "yes");
       
   613                 }
       
   614             } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
       
   615                 fFeatures = state ? fFeatures | ELEM_CONTENT_WHITESPACE : fFeatures
       
   616                         & ~ELEM_CONTENT_WHITESPACE;
       
   617                 // element-content-whitespace
       
   618                 if (state) {
       
   619                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   620                             + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   621                 } else {
       
   622                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   623                             + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   624                 }
       
   625             } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
       
   626                 // false is not supported
       
   627                 if (!state) {
       
   628                     // Here we have to add the Xalan specific DOM Message Formatter
       
   629                     String msg = Utils.messages.createMessage(
       
   630                             MsgKey.ER_FEATURE_NOT_SUPPORTED,
       
   631                             new Object[] { name });
       
   632                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
       
   633                 } else {
       
   634                     fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   635                             + DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   636                 }
       
   637             } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)
       
   638                     || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)
       
   639                     || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)
       
   640                     || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION)
       
   641                     || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)
       
   642                     // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
       
   643                     ) {
       
   644                 // true is not supported
       
   645                 if (state) {
       
   646                     String msg = Utils.messages.createMessage(
       
   647                             MsgKey.ER_FEATURE_NOT_SUPPORTED,
       
   648                             new Object[] { name });
       
   649                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
       
   650                 } else {
       
   651                     if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)) {
       
   652                         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   653                                 + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   654                     } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
       
   655                         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   656                                 + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   657                     } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)) {
       
   658                         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   659                                 + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   660                     } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) {
       
   661                         fDOMConfigProperties.setProperty(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION
       
   662                                 + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   663                     } else if (name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)) {
       
   664                         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   665                                 + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   666                     } /* else if (name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)) {
       
   667                         fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   668                                 + DOMConstants.DOM_NORMALIZE_CHARACTERS, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   669                     } */
       
   670                 }
       
   671             } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)) {
       
   672                 if (state) {
       
   673                     fFeatures &= ~ENTITIES;
       
   674                     fFeatures &= ~CDATA;
       
   675                     fFeatures &= ~SCHEMAVALIDATE;
       
   676                     fFeatures &= ~DTNORMALIZE;
       
   677                     fFeatures |= NAMESPACES;
       
   678                     fFeatures |= NAMESPACEDECLS;
       
   679                     fFeatures |= WELLFORMED;
       
   680                     fFeatures |= ELEM_CONTENT_WHITESPACE;
       
   681                     fFeatures |= COMMENTS;
       
   682                 }
       
   683 
       
   684                 // infoset
       
   685                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   686                         + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   687                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   688                         + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   689                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   690                         + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   691                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   692                         + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   693                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   694                         + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE);
       
   695 
       
   696                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   697                         + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   698                 fDOMConfigProperties.setProperty(
       
   699                         OutputPropertiesFactory.S_KEY_ENTITIES, "");
       
   700 
       
   701                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   702                         + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   703                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   704                         + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   705                 fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS
       
   706                         + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE);
       
   707             } else if (name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)) {
       
   708                 String msg = Utils.messages.createMessage(
       
   709                     MsgKey.ER_FEATURE_NOT_SUPPORTED,
       
   710                     new Object[] { name });
       
   711                 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
       
   712             } else {
       
   713                 // Setting this to false has no effect
       
   714             }
       
   715         } // If the parameter value is not a boolean
       
   716         else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) {
       
   717             if (value == null || value instanceof DOMErrorHandler) {
       
   718                 fDOMErrorHandler = (DOMErrorHandler)value;
       
   719             } else {
       
   720                 String msg = Utils.messages.createMessage(
       
   721                         MsgKey.ER_TYPE_MISMATCH_ERR,
       
   722                         new Object[] { name });
       
   723                 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
       
   724             }
       
   725         } else if (
       
   726                 name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION)
       
   727                 || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)
       
   728                 || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)
       
   729                 && value != null) {
       
   730             String msg = Utils.messages.createMessage(
       
   731                     MsgKey.ER_FEATURE_NOT_SUPPORTED,
       
   732                     new Object[] { name });
       
   733             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
       
   734         } else {
       
   735             String msg = Utils.messages.createMessage(
       
   736                     MsgKey.ER_FEATURE_NOT_FOUND,
       
   737                     new Object[] { name });
       
   738             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
       
   739         }
       
   740     }
       
   741     // ************************************************************************
       
   742 
       
   743 
       
   744     // ************************************************************************
       
   745     // DOMConfiguraiton implementation
       
   746     // ************************************************************************
       
   747 
       
   748     /**
       
   749      * Returns the DOMConfiguration of the LSSerializer.
       
   750      *
       
   751      * @see org.w3c.dom.ls.LSSerializer#getDomConfig()
       
   752      * @since DOM Level 3
       
   753      * @return A DOMConfiguration object.
       
   754      */
       
   755     public DOMConfiguration getDomConfig() {
       
   756         return (DOMConfiguration)this;
       
   757     }
       
   758 
       
   759     /**
       
   760      * Returns the DOMConfiguration of the LSSerializer.
       
   761      *
       
   762      * @see org.w3c.dom.ls.LSSerializer#getFilter()
       
   763      * @since DOM Level 3
       
   764      * @return A LSSerializerFilter object.
       
   765      */
       
   766     public LSSerializerFilter getFilter() {
       
   767         return fSerializerFilter;
       
   768     }
       
   769 
       
   770     /**
       
   771      * Returns the End-Of-Line sequence of characters to be used in the XML
       
   772      * being serialized.  If none is set a default "\n" is returned.
       
   773      *
       
   774      * @see org.w3c.dom.ls.LSSerializer#getNewLine()
       
   775      * @since DOM Level 3
       
   776      * @return A String containing the end-of-line character sequence  used in
       
   777      * serialization.
       
   778      */
       
   779     public String getNewLine() {
       
   780         return fEndOfLine;
       
   781     }
       
   782 
       
   783     /**
       
   784      * Set a LSSerilizerFilter on the LSSerializer.  When set, the filter is
       
   785      * called before each node is serialized which depending on its implemention
       
   786      * determines if the node is to be serialized or not.
       
   787      *
       
   788      * @see org.w3c.dom.ls.LSSerializer#setFilter
       
   789      * @since DOM Level 3
       
   790      * @param filter A LSSerializerFilter to be applied to the stream to serialize.
       
   791      */
       
   792     public void setFilter(LSSerializerFilter filter) {
       
   793         fSerializerFilter = filter;
       
   794     }
       
   795 
       
   796     /**
       
   797      * Sets the End-Of-Line sequence of characters to be used in the XML
       
   798      * being serialized.  Setting this attribute to null will reset its
       
   799      * value to the default value i.e. "\n".
       
   800      *
       
   801      * @see org.w3c.dom.ls.LSSerializer#setNewLine
       
   802      * @since DOM Level 3
       
   803      * @param newLine a String that is the end-of-line character sequence to be used in
       
   804      * serialization.
       
   805      */
       
   806     public void setNewLine(String newLine) {
       
   807         fEndOfLine = newLine !=null? newLine: fEndOfLine;
       
   808     }
       
   809 
       
   810     /**
       
   811      * Serializes the specified node to the specified LSOutput and returns true if the Node
       
   812      * was successfully serialized.
       
   813      *
       
   814      * @see org.w3c.dom.ls.LSSerializer#write(org.w3c.dom.Node, org.w3c.dom.ls.LSOutput)
       
   815      * @since DOM Level 3
       
   816      * @param nodeArg The Node to serialize.
       
   817      * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the
       
   818      * LSSerializer was unable to serialize the node.
       
   819      *
       
   820      */
       
   821     public boolean write(Node nodeArg, LSOutput destination) throws LSException {
       
   822         // If the destination is null
       
   823         if (destination == null) {
       
   824             String msg = Utils.messages
       
   825             .createMessage(
       
   826                     MsgKey.ER_NO_OUTPUT_SPECIFIED,
       
   827                     null);
       
   828             if (fDOMErrorHandler != null) {
       
   829                 fDOMErrorHandler.handleError(new DOMErrorImpl(
       
   830                         DOMError.SEVERITY_FATAL_ERROR, msg,
       
   831                         MsgKey.ER_NO_OUTPUT_SPECIFIED));
       
   832             }
       
   833             throw new LSException(LSException.SERIALIZE_ERR, msg);
       
   834         }
       
   835 
       
   836         // If nodeArg is null, return false.  Should we throw and LSException instead?
       
   837         if (nodeArg == null ) {
       
   838             return false;
       
   839         }
       
   840 
       
   841         // Obtain a reference to the serializer to use
       
   842         // Serializer serializer = getXMLSerializer(xmlVersion);
       
   843         Serializer serializer = fXMLSerializer;
       
   844         serializer.reset();
       
   845 
       
   846         // If the node has not been seen
       
   847         if ( nodeArg != fVisitedNode) {
       
   848             // Determine the XML Document version of the Node
       
   849             String xmlVersion = getXMLVersion(nodeArg);
       
   850 
       
   851             // Determine the encoding: 1.LSOutput.encoding, 2.Document.inputEncoding, 3.Document.xmlEncoding.
       
   852             fEncoding = destination.getEncoding();
       
   853             if (fEncoding == null ) {
       
   854                 fEncoding = getInputEncoding(nodeArg);
       
   855                 fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg);
       
   856             }
       
   857 
       
   858             // If the encoding is not recognized throw an exception.
       
   859             // Note: The serializer defaults to UTF-8 when created
       
   860             if (!Encodings.isRecognizedEncoding(fEncoding)) {
       
   861                 String msg = Utils.messages
       
   862                 .createMessage(
       
   863                         MsgKey.ER_UNSUPPORTED_ENCODING,
       
   864                         null);
       
   865                 if (fDOMErrorHandler != null) {
       
   866                     fDOMErrorHandler.handleError(new DOMErrorImpl(
       
   867                             DOMError.SEVERITY_FATAL_ERROR, msg,
       
   868                             MsgKey.ER_UNSUPPORTED_ENCODING));
       
   869                 }
       
   870                 throw new LSException(LSException.SERIALIZE_ERR, msg);
       
   871             }
       
   872 
       
   873             serializer.getOutputFormat().setProperty("version", xmlVersion);
       
   874 
       
   875             // Set the output encoding and xml version properties
       
   876             fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
       
   877             fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding);
       
   878 
       
   879             // If the node to be serialized is not a Document, Element, or Entity
       
   880             // node
       
   881             // then the XML declaration, or text declaration, should be never be
       
   882             // serialized.
       
   883             if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE
       
   884                     || nodeArg.getNodeType() != Node.ELEMENT_NODE
       
   885                     || nodeArg.getNodeType() != Node.ENTITY_NODE)
       
   886                     && ((fFeatures & XMLDECL) != 0)) {
       
   887                 fDOMConfigProperties.setProperty(
       
   888                         DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
       
   889                         DOMConstants.DOM3_DEFAULT_FALSE);
       
   890             }
       
   891 
       
   892             fVisitedNode = nodeArg;
       
   893         }
       
   894 
       
   895         // Update the serializer properties
       
   896         fXMLSerializer.setOutputFormat(fDOMConfigProperties);
       
   897 
       
   898         //
       
   899         try {
       
   900 
       
   901             // The LSSerializer will use the LSOutput object to determine
       
   902             // where to serialize the output to in the following order the
       
   903             // first one that is not null and not an empty string will be
       
   904             // used: 1.LSOutput.characterStream, 2.LSOutput.byteStream,
       
   905             // 3. LSOutput.systemId
       
   906             // 1.LSOutput.characterStream
       
   907             Writer writer = destination.getCharacterStream();
       
   908             if (writer == null ) {
       
   909 
       
   910                 // 2.LSOutput.byteStream
       
   911                 OutputStream outputStream = destination.getByteStream();
       
   912                 if ( outputStream == null) {
       
   913 
       
   914                     // 3. LSOutput.systemId
       
   915                     String uri = destination.getSystemId();
       
   916                     if (uri == null) {
       
   917                         String msg = Utils.messages
       
   918                         .createMessage(
       
   919                                 MsgKey.ER_NO_OUTPUT_SPECIFIED,
       
   920                                 null);
       
   921                         if (fDOMErrorHandler != null) {
       
   922                             fDOMErrorHandler.handleError(new DOMErrorImpl(
       
   923                                     DOMError.SEVERITY_FATAL_ERROR, msg,
       
   924                                     MsgKey.ER_NO_OUTPUT_SPECIFIED));
       
   925                         }
       
   926                         throw new LSException(LSException.SERIALIZE_ERR, msg);
       
   927 
       
   928                     } else {
       
   929                         // Expand the System Id and obtain an absolute URI for it.
       
   930                         String absoluteURI = SystemIDResolver.getAbsoluteURI(uri);
       
   931 
       
   932                         URL url = new URL(absoluteURI);
       
   933                         OutputStream urlOutStream = null;
       
   934                         String protocol = url.getProtocol();
       
   935                         String host = url.getHost();
       
   936 
       
   937                         // For file protocols, there is no need to use a URL to get its
       
   938                         // corresponding OutputStream
       
   939 
       
   940                         // Scheme names consist of a sequence of characters. The lower case
       
   941                         // letters "a"--"z", digits, and the characters plus ("+"), period
       
   942                         // ("."), and hyphen ("-") are allowed. For resiliency, programs
       
   943                         // interpreting URLs should treat upper case letters as equivalent to
       
   944                         // lower case in scheme names (e.g., allow "HTTP" as well as "http").
       
   945                         if (protocol.equalsIgnoreCase("file")
       
   946                                 && (host == null || host.length() == 0 || host.equals("localhost"))) {
       
   947                             // do we also need to check for host.equals(hostname)
       
   948                             urlOutStream = new FileOutputStream(new File(url.getPath()));
       
   949 
       
   950                         } else {
       
   951                             // This should support URL's whose schemes are mentioned in
       
   952                             // RFC1738 other than file
       
   953 
       
   954                             URLConnection urlCon = url.openConnection();
       
   955                             urlCon.setDoInput(false);
       
   956                             urlCon.setDoOutput(true);
       
   957                             urlCon.setUseCaches(false);
       
   958                             urlCon.setAllowUserInteraction(false);
       
   959 
       
   960                             // When writing to a HTTP URI, a HTTP PUT is performed.
       
   961                             if (urlCon instanceof HttpURLConnection) {
       
   962                                 HttpURLConnection httpCon = (HttpURLConnection) urlCon;
       
   963                                 httpCon.setRequestMethod("PUT");
       
   964                             }
       
   965                             urlOutStream = urlCon.getOutputStream();
       
   966                         }
       
   967                         // set the OutputStream to that obtained from the systemId
       
   968                         serializer.setWriter(new OutputStreamWriter(urlOutStream));
       
   969                     }
       
   970                 } else {
       
   971                     // 2.LSOutput.byteStream
       
   972                     serializer.setWriter(new OutputStreamWriter(outputStream, fEncoding));
       
   973                 }
       
   974             } else {
       
   975                 // 1.LSOutput.characterStream
       
   976                 serializer.setWriter(writer);
       
   977             }
       
   978 
       
   979             // The associated media type by default is set to text/xml on
       
   980             // org.apache.xml.serializer.SerializerBase.
       
   981 
       
   982             // Get a reference to the serializer then lets you serilize a DOM
       
   983             // Use this hack till Xalan support JAXP1.3
       
   984             if (fDOMSerializer == null) {
       
   985                fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
       
   986             }
       
   987 
       
   988             // Set the error handler on the DOM3Serializer interface implementation
       
   989             if (fDOMErrorHandler != null) {
       
   990                 fDOMSerializer.setErrorHandler(fDOMErrorHandler);
       
   991             }
       
   992 
       
   993             // Set the filter on the DOM3Serializer interface implementation
       
   994             if (fSerializerFilter != null) {
       
   995                 fDOMSerializer.setNodeFilter(fSerializerFilter);
       
   996             }
       
   997 
       
   998             // Set the NewLine character to be used
       
   999             fDOMSerializer.setNewLine(fEndOfLine);
       
  1000 
       
  1001             // Serializer your DOM, where node is an org.w3c.dom.Node
       
  1002             // Assuming that Xalan's serializer can serialize any type of DOM node
       
  1003             fDOMSerializer.serializeDOM3(nodeArg);
       
  1004 
       
  1005         } catch( UnsupportedEncodingException ue) {
       
  1006 
       
  1007             String msg = Utils.messages
       
  1008             .createMessage(
       
  1009                     MsgKey.ER_UNSUPPORTED_ENCODING,
       
  1010                     null);
       
  1011             if (fDOMErrorHandler != null) {
       
  1012                 fDOMErrorHandler.handleError(new DOMErrorImpl(
       
  1013                         DOMError.SEVERITY_FATAL_ERROR, msg,
       
  1014                         MsgKey.ER_UNSUPPORTED_ENCODING, ue));
       
  1015             }
       
  1016             throw new LSException(LSException.SERIALIZE_ERR, ue.getMessage());
       
  1017         } catch (LSException lse) {
       
  1018             // Rethrow LSException.
       
  1019             throw lse;
       
  1020         } catch (RuntimeException e) {
       
  1021             e.printStackTrace();
       
  1022             throw new LSException(LSException.SERIALIZE_ERR, e!=null?e.getMessage():"NULL Exception") ;
       
  1023         }  catch (Exception e) {
       
  1024             if (fDOMErrorHandler != null) {
       
  1025                 fDOMErrorHandler.handleError(new DOMErrorImpl(
       
  1026                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
       
  1027                         null, e));
       
  1028             }
       
  1029             e.printStackTrace();
       
  1030             throw new LSException(LSException.SERIALIZE_ERR, e.toString());
       
  1031         }
       
  1032         return true;
       
  1033     }
       
  1034 
       
  1035     /**
       
  1036      * Serializes the specified node and returns a String with the serialized
       
  1037      * data to the caller.
       
  1038      *
       
  1039      * @see org.w3c.dom.ls.LSSerializer#writeToString(org.w3c.dom.Node)
       
  1040      * @since DOM Level 3
       
  1041      * @param nodeArg The Node to serialize.
       
  1042      * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the
       
  1043      * LSSerializer was unable to serialize the node.
       
  1044      *
       
  1045      */
       
  1046     public String writeToString(Node nodeArg) throws DOMException, LSException {
       
  1047         // return null is nodeArg is null.  Should an Exception be thrown instead?
       
  1048         if (nodeArg == null) {
       
  1049             return null;
       
  1050         }
       
  1051 
       
  1052         // Should we reset the serializer configuration before each write operation?
       
  1053         // Obtain a reference to the serializer to use
       
  1054         Serializer serializer = fXMLSerializer;
       
  1055         serializer.reset();
       
  1056 
       
  1057         if (nodeArg != fVisitedNode){
       
  1058             // Determine the XML Document version of the Node
       
  1059             String xmlVersion = getXMLVersion(nodeArg);
       
  1060 
       
  1061             serializer.getOutputFormat().setProperty("version", xmlVersion);
       
  1062 
       
  1063             // Set the output encoding and xml version properties
       
  1064             fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
       
  1065             fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, "UTF-16");
       
  1066 
       
  1067             // If the node to be serialized is not a Document, Element, or Entity
       
  1068             // node
       
  1069             // then the XML declaration, or text declaration, should be never be
       
  1070             // serialized.
       
  1071             if  ((nodeArg.getNodeType() != Node.DOCUMENT_NODE
       
  1072                     || nodeArg.getNodeType() != Node.ELEMENT_NODE
       
  1073                     || nodeArg.getNodeType() != Node.ENTITY_NODE)
       
  1074                     && ((fFeatures & XMLDECL) != 0)) {
       
  1075                 fDOMConfigProperties.setProperty(
       
  1076                         DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
       
  1077                         DOMConstants.DOM3_DEFAULT_FALSE);
       
  1078             }
       
  1079 
       
  1080             fVisitedNode = nodeArg;
       
  1081         }
       
  1082         // Update the serializer properties
       
  1083         fXMLSerializer.setOutputFormat(fDOMConfigProperties);
       
  1084 
       
  1085         // StringWriter to Output to
       
  1086         StringWriter output = new StringWriter();
       
  1087 
       
  1088         //
       
  1089         try {
       
  1090 
       
  1091             // Set the Serializer's Writer to a StringWriter
       
  1092             serializer.setWriter(output);
       
  1093 
       
  1094             // Get a reference to the serializer then lets you serilize a DOM
       
  1095             // Use this hack till Xalan support JAXP1.3
       
  1096             if (fDOMSerializer == null) {
       
  1097                 fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
       
  1098             }
       
  1099 
       
  1100             // Set the error handler on the DOM3Serializer interface implementation
       
  1101             if (fDOMErrorHandler != null) {
       
  1102                 fDOMSerializer.setErrorHandler(fDOMErrorHandler);
       
  1103             }
       
  1104 
       
  1105             // Set the filter on the DOM3Serializer interface implementation
       
  1106             if (fSerializerFilter != null) {
       
  1107                 fDOMSerializer.setNodeFilter(fSerializerFilter);
       
  1108             }
       
  1109 
       
  1110             // Set the NewLine character to be used
       
  1111             fDOMSerializer.setNewLine(fEndOfLine);
       
  1112 
       
  1113             // Serializer your DOM, where node is an org.w3c.dom.Node
       
  1114             fDOMSerializer.serializeDOM3(nodeArg);
       
  1115         } catch (LSException lse) {
       
  1116             // Rethrow LSException.
       
  1117             throw lse;
       
  1118         } catch (RuntimeException e) {
       
  1119             e.printStackTrace();
       
  1120             throw new LSException(LSException.SERIALIZE_ERR, e.toString());
       
  1121         }  catch (Exception e) {
       
  1122             if (fDOMErrorHandler != null) {
       
  1123                 fDOMErrorHandler.handleError(new DOMErrorImpl(
       
  1124                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
       
  1125                         null, e));
       
  1126             }
       
  1127             e.printStackTrace();
       
  1128             throw new LSException(LSException.SERIALIZE_ERR, e.toString());
       
  1129         }
       
  1130 
       
  1131         // return the serialized string
       
  1132         return output.toString();
       
  1133     }
       
  1134 
       
  1135     /**
       
  1136      * Serializes the specified node to the specified URI and returns true if the Node
       
  1137      * was successfully serialized.
       
  1138      *
       
  1139      * @see org.w3c.dom.ls.LSSerializer#writeToURI(org.w3c.dom.Node, String)
       
  1140      * @since DOM Level 3
       
  1141      * @param nodeArg The Node to serialize.
       
  1142      * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the
       
  1143      * LSSerializer was unable to serialize the node.
       
  1144      *
       
  1145      */
       
  1146     public boolean writeToURI(Node nodeArg, String uri) throws LSException {
       
  1147         // If nodeArg is null, return false.  Should we throw and LSException instead?
       
  1148         if (nodeArg == null ) {
       
  1149             return false;
       
  1150         }
       
  1151 
       
  1152         // Obtain a reference to the serializer to use
       
  1153         Serializer serializer = fXMLSerializer;
       
  1154         serializer.reset();
       
  1155 
       
  1156         if (nodeArg != fVisitedNode) {
       
  1157             // Determine the XML Document version of the Node
       
  1158             String xmlVersion = getXMLVersion(nodeArg);
       
  1159 
       
  1160             // Determine the encoding: 1.LSOutput.encoding,
       
  1161             // 2.Document.inputEncoding, 3.Document.xmlEncoding.
       
  1162             fEncoding = getInputEncoding(nodeArg);
       
  1163             if (fEncoding == null ) {
       
  1164                 fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg);
       
  1165             }
       
  1166 
       
  1167             serializer.getOutputFormat().setProperty("version", xmlVersion);
       
  1168 
       
  1169             // Set the output encoding and xml version properties
       
  1170             fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion);
       
  1171             fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding);
       
  1172 
       
  1173             // If the node to be serialized is not a Document, Element, or Entity
       
  1174             // node
       
  1175             // then the XML declaration, or text declaration, should be never be
       
  1176             // serialized.
       
  1177             if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE
       
  1178                     || nodeArg.getNodeType() != Node.ELEMENT_NODE
       
  1179                     || nodeArg.getNodeType() != Node.ENTITY_NODE)
       
  1180                     && ((fFeatures & XMLDECL) != 0))  {
       
  1181                 fDOMConfigProperties.setProperty(
       
  1182                         DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL,
       
  1183                         DOMConstants.DOM3_DEFAULT_FALSE);
       
  1184             }
       
  1185 
       
  1186             fVisitedNode = nodeArg;
       
  1187         }
       
  1188 
       
  1189         // Update the serializer properties
       
  1190         fXMLSerializer.setOutputFormat(fDOMConfigProperties);
       
  1191 
       
  1192         //
       
  1193         try {
       
  1194             // If the specified encoding is not supported an
       
  1195             // "unsupported-encoding" fatal error is raised. ??
       
  1196             if (uri == null) {
       
  1197                 String msg = Utils.messages.createMessage(
       
  1198                         MsgKey.ER_NO_OUTPUT_SPECIFIED, null);
       
  1199                 if (fDOMErrorHandler != null) {
       
  1200                     fDOMErrorHandler.handleError(new DOMErrorImpl(
       
  1201                             DOMError.SEVERITY_FATAL_ERROR, msg,
       
  1202                             MsgKey.ER_NO_OUTPUT_SPECIFIED));
       
  1203                 }
       
  1204                 throw new LSException(LSException.SERIALIZE_ERR, msg);
       
  1205 
       
  1206             } else {
       
  1207                 // REVISIT: Can this be used to get an absolute expanded URI
       
  1208                 String absoluteURI = SystemIDResolver.getAbsoluteURI(uri);
       
  1209 
       
  1210                 URL url = new URL(absoluteURI);
       
  1211                 OutputStream urlOutStream = null;
       
  1212                 String protocol = url.getProtocol();
       
  1213                 String host = url.getHost();
       
  1214 
       
  1215                 // For file protocols, there is no need to use a URL to get its
       
  1216                 // corresponding OutputStream
       
  1217 
       
  1218                 // Scheme names consist of a sequence of characters. The lower
       
  1219                 // case letters "a"--"z", digits, and the characters plus ("+"),
       
  1220                 // period ("."), and hyphen ("-") are allowed. For resiliency,
       
  1221                 // programs interpreting URLs should treat upper case letters as
       
  1222                 // equivalent to lower case in scheme names
       
  1223                 // (e.g., allow "HTTP" as well as "http").
       
  1224                 if (protocol.equalsIgnoreCase("file")
       
  1225                         && (host == null || host.length() == 0 || host
       
  1226                                 .equals("localhost"))) {
       
  1227                     // do we also need to check for host.equals(hostname)
       
  1228                     urlOutStream = new FileOutputStream(new File(url.getPath()));
       
  1229 
       
  1230                 } else {
       
  1231                     // This should support URL's whose schemes are mentioned in
       
  1232                     // RFC1738 other than file
       
  1233 
       
  1234                     URLConnection urlCon = url.openConnection();
       
  1235                     urlCon.setDoInput(false);
       
  1236                     urlCon.setDoOutput(true);
       
  1237                     urlCon.setUseCaches(false);
       
  1238                     urlCon.setAllowUserInteraction(false);
       
  1239 
       
  1240                     // When writing to a HTTP URI, a HTTP PUT is performed.
       
  1241                     if (urlCon instanceof HttpURLConnection) {
       
  1242                         HttpURLConnection httpCon = (HttpURLConnection) urlCon;
       
  1243                         httpCon.setRequestMethod("PUT");
       
  1244                     }
       
  1245                     urlOutStream = urlCon.getOutputStream();
       
  1246                 }
       
  1247                 // set the OutputStream to that obtained from the systemId
       
  1248                 serializer.setWriter(new OutputStreamWriter(urlOutStream, fEncoding));
       
  1249             }
       
  1250 
       
  1251             // Get a reference to the serializer then lets you serilize a DOM
       
  1252             // Use this hack till Xalan support JAXP1.3
       
  1253             if (fDOMSerializer == null) {
       
  1254                 fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer();
       
  1255             }
       
  1256 
       
  1257             // Set the error handler on the DOM3Serializer interface implementation
       
  1258             if (fDOMErrorHandler != null) {
       
  1259                 fDOMSerializer.setErrorHandler(fDOMErrorHandler);
       
  1260             }
       
  1261 
       
  1262             // Set the filter on the DOM3Serializer interface implementation
       
  1263             if (fSerializerFilter != null) {
       
  1264                 fDOMSerializer.setNodeFilter(fSerializerFilter);
       
  1265             }
       
  1266 
       
  1267             // Set the NewLine character to be used
       
  1268             fDOMSerializer.setNewLine(fEndOfLine);
       
  1269 
       
  1270             // Serializer your DOM, where node is an org.w3c.dom.Node
       
  1271             // Assuming that Xalan's serializer can serialize any type of DOM
       
  1272             // node
       
  1273             fDOMSerializer.serializeDOM3(nodeArg);
       
  1274 
       
  1275         } catch (LSException lse) {
       
  1276             // Rethrow LSException.
       
  1277             throw lse;
       
  1278         } catch (RuntimeException e) {
       
  1279             e.printStackTrace();
       
  1280             throw new LSException(LSException.SERIALIZE_ERR, e.toString());
       
  1281         }  catch (Exception e) {
       
  1282             if (fDOMErrorHandler != null) {
       
  1283                 fDOMErrorHandler.handleError(new DOMErrorImpl(
       
  1284                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
       
  1285                         null, e));
       
  1286             }
       
  1287             e.printStackTrace();
       
  1288             throw new LSException(LSException.SERIALIZE_ERR, e.toString());
       
  1289         }
       
  1290 
       
  1291         return true;
       
  1292     }
       
  1293     // ************************************************************************
       
  1294 
       
  1295 
       
  1296     // ************************************************************************
       
  1297     // Implementaion methods
       
  1298     // ************************************************************************
       
  1299 
       
  1300     /**
       
  1301      * Determines the XML Version of the Document Node to serialize.  If the Document Node
       
  1302      * is not a DOM Level 3 Node, then the default version returned is 1.0.
       
  1303      *
       
  1304      * @param  nodeArg The Node to serialize
       
  1305      * @return A String containing the version pseudo-attribute of the XMLDecl.
       
  1306      * @throws Throwable if the DOM implementation does not implement Document.getXmlVersion()
       
  1307      */
       
  1308     //protected String getXMLVersion(Node nodeArg) throws Throwable {
       
  1309     protected String getXMLVersion(Node nodeArg) {
       
  1310         Document doc = null;
       
  1311 
       
  1312         // Determine the XML Version of the document
       
  1313         if (nodeArg != null) {
       
  1314             if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
       
  1315                 // The Document node is the Node argument
       
  1316                 doc = (Document)nodeArg;
       
  1317             } else {
       
  1318                 // The Document node is the Node argument's ownerDocument
       
  1319                 doc = nodeArg.getOwnerDocument();
       
  1320             }
       
  1321 
       
  1322             // Determine the DOM Version.
       
  1323             if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
       
  1324                 try {
       
  1325                     return doc.getXmlVersion();
       
  1326                 } catch (AbstractMethodError e) {
       
  1327                     //ignore, impl does not support the method
       
  1328                 }
       
  1329             }
       
  1330         }
       
  1331         // The version will be treated as "1.0" which may result in
       
  1332         // an ill-formed document being serialized.
       
  1333         // If nodeArg does not have an ownerDocument, treat this as XML 1.0
       
  1334         return "1.0";
       
  1335     }
       
  1336 
       
  1337     /**
       
  1338      * Determines the XML Encoding of the Document Node to serialize.  If the Document Node
       
  1339      * is not a DOM Level 3 Node, then the default encoding "UTF-8" is returned.
       
  1340      *
       
  1341      * @param  nodeArg The Node to serialize
       
  1342      * @return A String containing the encoding pseudo-attribute of the XMLDecl.
       
  1343      * @throws Throwable if the DOM implementation does not implement Document.getXmlEncoding()
       
  1344      */
       
  1345     protected String getXMLEncoding(Node nodeArg) {
       
  1346         Document doc = null;
       
  1347 
       
  1348         // Determine the XML Encoding of the document
       
  1349         if (nodeArg != null) {
       
  1350             if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
       
  1351                 // The Document node is the Node argument
       
  1352                 doc = (Document)nodeArg;
       
  1353             } else {
       
  1354                 // The Document node is the Node argument's ownerDocument
       
  1355                 doc = nodeArg.getOwnerDocument();
       
  1356             }
       
  1357 
       
  1358             // Determine the XML Version.
       
  1359             if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
       
  1360                 return doc.getXmlEncoding();
       
  1361             }
       
  1362         }
       
  1363         // The default encoding is UTF-8 except for the writeToString method
       
  1364         return "UTF-8";
       
  1365     }
       
  1366 
       
  1367     /**
       
  1368      * Determines the Input Encoding of the Document Node to serialize.  If the Document Node
       
  1369      * is not a DOM Level 3 Node, then null is returned.
       
  1370      *
       
  1371      * @param  nodeArg The Node to serialize
       
  1372      * @return A String containing the input encoding.
       
  1373      */
       
  1374     protected String getInputEncoding(Node nodeArg)  {
       
  1375         Document doc = null;
       
  1376 
       
  1377         // Determine the Input Encoding of the document
       
  1378         if (nodeArg != null) {
       
  1379             if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) {
       
  1380                 // The Document node is the Node argument
       
  1381                 doc = (Document)nodeArg;
       
  1382             } else {
       
  1383                 // The Document node is the Node argument's ownerDocument
       
  1384                 doc = nodeArg.getOwnerDocument();
       
  1385             }
       
  1386 
       
  1387             // Determine the DOM Version.
       
  1388             if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) {
       
  1389                 return doc.getInputEncoding();
       
  1390             }
       
  1391         }
       
  1392         // The default encoding returned is null
       
  1393         return null;
       
  1394     }
       
  1395 
       
  1396     /**
       
  1397      * This method returns the LSSerializer's error handler.
       
  1398      *
       
  1399      * @return Returns the fDOMErrorHandler.
       
  1400      */
       
  1401     public DOMErrorHandler getErrorHandler() {
       
  1402         return fDOMErrorHandler;
       
  1403     }
       
  1404 
       
  1405 }