| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /* |
| * $Id$ |
| */ |
| |
| package org.apache.xml.serializer.dom3; |
| |
| import java.io.FileOutputStream; |
| import java.io.OutputStream; |
| import java.io.StringWriter; |
| import java.io.UnsupportedEncodingException; |
| import java.io.Writer; |
| import java.net.HttpURLConnection; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| import org.apache.xml.serializer.DOM3Serializer; |
| import org.apache.xml.serializer.Encodings; |
| import org.apache.xml.serializer.OutputPropertiesFactory; |
| import org.apache.xml.serializer.Serializer; |
| import org.apache.xml.serializer.SerializerFactory; |
| import org.apache.xml.serializer.utils.MsgKey; |
| import org.apache.xml.serializer.utils.SystemIDResolver; |
| import org.apache.xml.serializer.utils.Utils; |
| import org.w3c.dom.DOMConfiguration; |
| import org.w3c.dom.DOMError; |
| import org.w3c.dom.DOMErrorHandler; |
| import org.w3c.dom.DOMException; |
| import org.w3c.dom.DOMStringList; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.ls.LSException; |
| import org.w3c.dom.ls.LSOutput; |
| import org.w3c.dom.ls.LSSerializer; |
| import org.w3c.dom.ls.LSSerializerFilter; |
| |
| /** |
| * Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer and |
| * org.w3c.dom.ls.DOMConfiguration. Serialization is achieved by delegating |
| * serialization calls to <CODE>org.apache.xml.serializer.ToStream</CODE> or |
| * one of its derived classes depending on the serialization method, while walking |
| * the DOM in DOM3TreeWalker. |
| * @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> |
| * @see <a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMConfiguration">org.w3c.dom.DOMConfiguration</a> |
| * |
| * @version $Id: |
| * |
| * @xsl.usage internal |
| */ |
| final public class LSSerializerImpl implements DOMConfiguration, LSSerializer { |
| |
| // The default end-of-line character sequence used in serialization. |
| private static final String DEFAULT_END_OF_LINE; |
| static { |
| String lineSeparator = (String) AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| try { |
| return System.getProperty("line.separator"); |
| } |
| catch (SecurityException ex) {} |
| return null; |
| } |
| }); |
| // The DOM Level 3 Load and Save specification requires that implementations choose a default |
| // sequence which matches one allowed by XML 1.0 (or XML 1.1). If the value of "line.separator" |
| // isn't one of the XML 1.0 end-of-line sequences then we select "\n" as the default value. |
| DEFAULT_END_OF_LINE = lineSeparator != null && |
| (lineSeparator.equals("\r\n") || lineSeparator.equals("\r")) ? lineSeparator : "\n"; |
| } |
| |
| /** private data members */ |
| private Serializer fXMLSerializer = null; |
| |
| // Tracks DOMConfiguration features. |
| protected int fFeatures = 0; |
| |
| // Common DOM serializer |
| private DOM3Serializer fDOMSerializer = null; |
| |
| // A filter set on the LSSerializer |
| private LSSerializerFilter fSerializerFilter = null; |
| |
| // Stores the nodeArg parameter to speed up multiple writes of the same node. |
| private Node fVisitedNode = null; |
| |
| // The end-of-line character sequence used in serialization. "\n" is whats used on the web. |
| private String fEndOfLine = DEFAULT_END_OF_LINE; |
| |
| // The DOMErrorhandler. |
| private DOMErrorHandler fDOMErrorHandler = null; |
| |
| // The Configuration parameter to pass to the Underlying serilaizer. |
| private Properties fDOMConfigProperties = null; |
| |
| // The encoding to use during serialization. |
| private String fEncoding; |
| |
| // ************************************************************************ |
| // DOM Level 3 DOM Configuration parameter names |
| // ************************************************************************ |
| // Parameter canonical-form, true [optional] - NOT SUPPORTED |
| private final static int CANONICAL = 0x1 << 0; |
| |
| // Parameter cdata-sections, true [required] (default) |
| private final static int CDATA = 0x1 << 1; |
| |
| // Parameter check-character-normalization, true [optional] - NOT SUPPORTED |
| private final static int CHARNORMALIZE = 0x1 << 2; |
| |
| // Parameter comments, true [required] (default) |
| private final static int COMMENTS = 0x1 << 3; |
| |
| // Parameter datatype-normalization, true [optional] - NOT SUPPORTED |
| private final static int DTNORMALIZE = 0x1 << 4; |
| |
| // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED |
| private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5; |
| |
| // Parameter entities, true [required] (default) |
| private final static int ENTITIES = 0x1 << 6; |
| |
| // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer |
| private final static int INFOSET = 0x1 << 7; |
| |
| // Parameter namespaces, true [required] (default) |
| private final static int NAMESPACES = 0x1 << 8; |
| |
| // Parameter namespace-declarations, true [required] (default) |
| private final static int NAMESPACEDECLS = 0x1 << 9; |
| |
| // Parameter normalize-characters, true [optional] - NOT SUPPORTED |
| private final static int NORMALIZECHARS = 0x1 << 10; |
| |
| // Parameter split-cdata-sections, true [required] (default) |
| private final static int SPLITCDATA = 0x1 << 11; |
| |
| // Parameter validate, true [optional] - NOT SUPPORTED |
| private final static int VALIDATE = 0x1 << 12; |
| |
| // Parameter validate-if-schema, true [optional] - NOT SUPPORTED |
| private final static int SCHEMAVALIDATE = 0x1 << 13; |
| |
| // Parameter split-cdata-sections, true [required] (default) |
| private final static int WELLFORMED = 0x1 << 14; |
| |
| // Parameter discard-default-content, true [required] (default) |
| // Not sure how this will be used in level 2 Documents |
| private final static int DISCARDDEFAULT = 0x1 << 15; |
| |
| // Parameter format-pretty-print, true [optional] |
| private final static int PRETTY_PRINT = 0x1 << 16; |
| |
| // Parameter ignore-unknown-character-denormalizations, true [required] (default) |
| // We currently do not support XML 1.1 character normalization |
| private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17; |
| |
| // Parameter discard-default-content, true [required] (default) |
| private final static int XMLDECL = 0x1 << 18; |
| // ************************************************************************ |
| |
| // Recognized parameters for which atleast one value can be set |
| private String fRecognizedParameters [] = { |
| DOMConstants.DOM_CANONICAL_FORM, |
| DOMConstants.DOM_CDATA_SECTIONS, |
| DOMConstants.DOM_CHECK_CHAR_NORMALIZATION, |
| DOMConstants.DOM_COMMENTS, |
| DOMConstants.DOM_DATATYPE_NORMALIZATION, |
| DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, |
| DOMConstants.DOM_ENTITIES, |
| DOMConstants.DOM_INFOSET, |
| DOMConstants.DOM_NAMESPACES, |
| DOMConstants.DOM_NAMESPACE_DECLARATIONS, |
| //DOMConstants.DOM_NORMALIZE_CHARACTERS, |
| DOMConstants.DOM_SPLIT_CDATA, |
| DOMConstants.DOM_VALIDATE, |
| DOMConstants.DOM_VALIDATE_IF_SCHEMA, |
| DOMConstants.DOM_WELLFORMED, |
| DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, |
| DOMConstants.DOM_FORMAT_PRETTY_PRINT, |
| DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, |
| DOMConstants.DOM_XMLDECL, |
| DOMConstants.DOM_ERROR_HANDLER |
| }; |
| |
| |
| /** |
| * Constructor: Creates a LSSerializerImpl object. The underlying |
| * XML 1.0 or XML 1.1 org.apache.xml.serializer.Serializer object is |
| * created and initialized the first time any of the write methods are |
| * invoked to serialize the Node. Subsequent write methods on the same |
| * LSSerializerImpl object will use the previously created Serializer object. |
| */ |
| public LSSerializerImpl () { |
| // set default parameters |
| fFeatures |= CDATA; |
| fFeatures |= COMMENTS; |
| fFeatures |= ELEM_CONTENT_WHITESPACE; |
| fFeatures |= ENTITIES; |
| fFeatures |= NAMESPACES; |
| fFeatures |= NAMESPACEDECLS; |
| fFeatures |= SPLITCDATA; |
| fFeatures |= WELLFORMED; |
| fFeatures |= DISCARDDEFAULT; |
| fFeatures |= XMLDECL; |
| |
| // New OutputFormat properties |
| fDOMConfigProperties = new Properties(); |
| |
| // Initialize properties to be passed on the underlying serializer |
| initializeSerializerProps(); |
| |
| // Create the underlying serializer. |
| Properties configProps = OutputPropertiesFactory.getDefaultMethodProperties("xml"); |
| |
| // change xml version from 1.0 to 1.1 |
| //configProps.setProperty("version", "1.1"); |
| |
| // Get a serializer that seriailizes according the the properties, |
| // which in this case is to xml |
| fXMLSerializer = SerializerFactory.getSerializer(configProps); |
| |
| // Initialize Serializer |
| fXMLSerializer.setOutputFormat(fDOMConfigProperties); |
| } |
| |
| /** |
| * Initializes the underlying serializer's configuration depending on the |
| * default DOMConfiguration parameters. This method must be called before a |
| * node is to be serialized. |
| * |
| * @xsl.usage internal |
| */ |
| public void initializeSerializerProps () { |
| // canonical-form |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_DEFAULT_FALSE); |
| |
| // cdata-sections |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // "check-character-normalization" |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| |
| // comments |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // datatype-normalization |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DATATYPE_NORMALIZATION, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| |
| // element-content-whitespace |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // entities |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_TRUE); |
| // preserve entities |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // error-handler |
| // Should we set our default ErrorHandler |
| /* |
| * if (fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER) != null) { |
| * fDOMErrorHandler = |
| * (DOMErrorHandler)fDOMConfig.getParameter(Constants.DOM_ERROR_HANDLER); } |
| */ |
| |
| // infoset |
| if ((fFeatures & INFOSET) != 0) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACE_DECLARATIONS, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_FALSE); |
| // preserve entities |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_DEFAULT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CDATA_SECTIONS, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE_IF_SCHEMA, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DATATYPE_NORMALIZATION, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| } |
| |
| // namespaces |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // namespace-declarations |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACE_DECLARATIONS, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // normalize-characters |
| /* |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NORMALIZE_CHARACTERS, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| */ |
| |
| // split-cdata-sections |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // validate |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_DEFAULT_FALSE); |
| |
| // validate-if-schema |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE_IF_SCHEMA, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| |
| // well-formed |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // pretty-print |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XSL_OUTPUT_INDENT, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| fDOMConfigProperties.setProperty( |
| OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, Integer.toString(3)); |
| |
| // |
| |
| // discard-default-content |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, |
| DOMConstants.DOM3_DEFAULT_TRUE); |
| |
| // xml-declaration |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no"); |
| |
| } |
| |
| // ************************************************************************ |
| // DOMConfiguraiton implementation |
| // ************************************************************************ |
| |
| /** |
| * Checks if setting a parameter to a specific value is supported. |
| * |
| * @see org.w3c.dom.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object) |
| * @since DOM Level 3 |
| * @param name A String containing the DOMConfiguration parameter name. |
| * @param value An Object specifying the value of the corresponding parameter. |
| */ |
| public boolean canSetParameter(String name, Object value) { |
| if (value instanceof Boolean){ |
| if ( name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS) |
| || name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS) |
| || name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES) |
| || name.equalsIgnoreCase(DOMConstants.DOM_INFOSET) |
| || name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE) |
| || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES) |
| || name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS) |
| || name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA) |
| || name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED) |
| || name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT) |
| || name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT) |
| || name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)){ |
| // both values supported |
| return true; |
| } |
| else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) |
| || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE) |
| // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS) |
| ) { |
| // true is not supported |
| return !((Boolean)value).booleanValue(); |
| } |
| else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { |
| // false is not supported |
| return ((Boolean)value).booleanValue(); |
| } |
| } |
| else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) && |
| value == null || value instanceof DOMErrorHandler){ |
| return true; |
| } |
| return false; |
| } |
| /** |
| * This method returns the value of a parameter if known. |
| * |
| * @see org.w3c.dom.DOMConfiguration#getParameter(java.lang.String) |
| * |
| * @param name A String containing the DOMConfiguration parameter name |
| * whose value is to be returned. |
| * @return Object The value of the parameter if known. |
| */ |
| public Object getParameter(String name) throws DOMException { |
| if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) { |
| return ((fFeatures & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) { |
| return ((fFeatures & CDATA) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) { |
| return ((fFeatures & ENTITIES) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) { |
| return ((fFeatures & NAMESPACES) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) { |
| return ((fFeatures & NAMESPACEDECLS) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) { |
| return ((fFeatures & SPLITCDATA) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) { |
| return ((fFeatures & WELLFORMED) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) { |
| return ((fFeatures & DISCARDDEFAULT) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) { |
| return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) { |
| return ((fFeatures & XMLDECL) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) { |
| return ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) { |
| return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { |
| return Boolean.TRUE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) |
| || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) |
| // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) { |
| return Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)){ |
| if ((fFeatures & ENTITIES) == 0 && |
| (fFeatures & CDATA) == 0 && |
| (fFeatures & ELEM_CONTENT_WHITESPACE) != 0 && |
| (fFeatures & NAMESPACES) != 0 && |
| (fFeatures & NAMESPACEDECLS) != 0 && |
| (fFeatures & WELLFORMED) != 0 && |
| (fFeatures & COMMENTS) != 0) { |
| return Boolean.TRUE; |
| } |
| return Boolean.FALSE; |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) { |
| return fDOMErrorHandler; |
| } else if ( |
| name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) { |
| return null; |
| } else { |
| // Here we have to add the Xalan specific DOM Message Formatter |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_FOUND, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
| } |
| } |
| |
| /** |
| * This method returns a of the parameters supported by this DOMConfiguration object |
| * and for which at least one value can be set by the application |
| * |
| * @see org.w3c.dom.DOMConfiguration#getParameterNames() |
| * |
| * @return DOMStringList A list of DOMConfiguration parameters recognized |
| * by the serializer |
| */ |
| public DOMStringList getParameterNames() { |
| return new DOMStringListImpl(fRecognizedParameters); |
| } |
| |
| /** |
| * This method sets the value of the named parameter. |
| * |
| * @see org.w3c.dom.DOMConfiguration#setParameter(java.lang.String, java.lang.Object) |
| * |
| * @param name A String containing the DOMConfiguration parameter name. |
| * @param value An Object contaiing the parameters value to set. |
| */ |
| public void setParameter(String name, Object value) throws DOMException { |
| // If the value is a boolean |
| if (value instanceof Boolean) { |
| boolean state = ((Boolean) value).booleanValue(); |
| |
| if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS)) { |
| fFeatures = state ? fFeatures | COMMENTS : fFeatures |
| & ~COMMENTS; |
| // comments |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS)) { |
| fFeatures = state ? fFeatures | CDATA : fFeatures |
| & ~CDATA; |
| // cdata-sections |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES)) { |
| fFeatures = state ? fFeatures | ENTITIES : fFeatures |
| & ~ENTITIES; |
| // entities |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_TRUE); |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XERCES_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE); |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XERCES_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES)) { |
| fFeatures = state ? fFeatures | NAMESPACES : fFeatures |
| & ~NAMESPACES; |
| // namespaces |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name |
| .equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS)) { |
| fFeatures = state ? fFeatures | NAMESPACEDECLS |
| : fFeatures & ~NAMESPACEDECLS; |
| // namespace-declarations |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA)) { |
| fFeatures = state ? fFeatures | SPLITCDATA : fFeatures |
| & ~SPLITCDATA; |
| // split-cdata-sections |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_SPLIT_CDATA, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED)) { |
| fFeatures = state ? fFeatures | WELLFORMED : fFeatures |
| & ~WELLFORMED; |
| // well-formed |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name |
| .equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT)) { |
| fFeatures = state ? fFeatures | DISCARDDEFAULT |
| : fFeatures & ~DISCARDDEFAULT; |
| // discard-default-content |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) { |
| fFeatures = state ? fFeatures | PRETTY_PRINT : fFeatures |
| & ~PRETTY_PRINT; |
| // format-pretty-print |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } |
| else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) { |
| fFeatures = state ? fFeatures | XMLDECL : fFeatures |
| & ~XMLDECL; |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no"); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "yes"); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) { |
| fFeatures = state ? fFeatures | ELEM_CONTENT_WHITESPACE : fFeatures |
| & ~ELEM_CONTENT_WHITESPACE; |
| // element-content-whitespace |
| if (state) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { |
| // false is not supported |
| if (!state) { |
| // Here we have to add the Xalan specific DOM Message Formatter |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_SUPPORTED, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); |
| } else { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA) |
| || name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE) |
| || name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) |
| // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS) |
| ) { |
| // true is not supported |
| if (state) { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_SUPPORTED, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); |
| } else { |
| if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM)) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CANONICAL_FORM, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE)) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA)) { |
| fDOMConfigProperties.setProperty(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION |
| + DOMConstants.DOM_CHECK_CHAR_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION)) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } /* else if (name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS)) { |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NORMALIZE_CHARACTERS, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } */ |
| } |
| } else if (name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)) { |
| // infoset |
| if (state) { |
| fFeatures &= ~ENTITIES; |
| fFeatures &= ~CDATA; |
| fFeatures &= ~SCHEMAVALIDATE; |
| fFeatures &= ~DTNORMALIZE; |
| fFeatures |= NAMESPACES; |
| fFeatures |= NAMESPACEDECLS; |
| fFeatures |= WELLFORMED; |
| fFeatures |= ELEM_CONTENT_WHITESPACE; |
| fFeatures |= COMMENTS; |
| |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACES, DOMConstants.DOM3_EXPLICIT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_NAMESPACE_DECLARATIONS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_COMMENTS, DOMConstants.DOM3_EXPLICIT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE, DOMConstants.DOM3_EXPLICIT_TRUE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_WELLFORMED, DOMConstants.DOM3_EXPLICIT_TRUE); |
| |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS |
| + DOMConstants.DOM_ENTITIES, DOMConstants.DOM3_EXPLICIT_FALSE); |
| |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_CDATA_SECTIONS, DOMConstants.DOM3_EXPLICIT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_VALIDATE_IF_SCHEMA, DOMConstants.DOM3_EXPLICIT_FALSE); |
| fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS |
| + DOMConstants.DOM_DATATYPE_NORMALIZATION, DOMConstants.DOM3_EXPLICIT_FALSE); |
| } |
| } else { |
| // If this is a non-boolean parameter a type mismatch should be thrown. |
| if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) || |
| name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION) || |
| name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_TYPE_MISMATCH_ERR, |
| new Object[] { name }); |
| throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); |
| } |
| |
| // Parameter is not recognized |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_FOUND, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
| } |
| } // If the parameter value is not a boolean |
| else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER)) { |
| if (value == null || value instanceof DOMErrorHandler) { |
| fDOMErrorHandler = (DOMErrorHandler)value; |
| } else { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_TYPE_MISMATCH_ERR, |
| new Object[] { name }); |
| throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); |
| } |
| } else if ( |
| name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_LOCATION) |
| || name.equalsIgnoreCase(DOMConstants.DOM_SCHEMA_TYPE)) { |
| if (value != null) { |
| if (!(value instanceof String)) { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_TYPE_MISMATCH_ERR, |
| new Object[] { name }); |
| throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); |
| } |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_SUPPORTED, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); |
| } |
| } else { |
| // If this is a boolean parameter a type mismatch should be thrown. |
| if (name.equalsIgnoreCase(DOMConstants.DOM_COMMENTS) || |
| name.equalsIgnoreCase(DOMConstants.DOM_CDATA_SECTIONS) || |
| name.equalsIgnoreCase(DOMConstants.DOM_ENTITIES) || |
| name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACES) || |
| name.equalsIgnoreCase(DOMConstants.DOM_NAMESPACE_DECLARATIONS) || |
| name.equalsIgnoreCase(DOMConstants.DOM_SPLIT_CDATA) || |
| name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED) || |
| name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT) || |
| name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT) || |
| name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL) || |
| name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE) || |
| name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS) || |
| name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) || |
| name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE_IF_SCHEMA) || |
| name.equalsIgnoreCase(DOMConstants.DOM_VALIDATE) || |
| name.equalsIgnoreCase(DOMConstants.DOM_CHECK_CHAR_NORMALIZATION) || |
| name.equalsIgnoreCase(DOMConstants.DOM_DATATYPE_NORMALIZATION) || |
| name.equalsIgnoreCase(DOMConstants.DOM_INFOSET)) { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_TYPE_MISMATCH_ERR, |
| new Object[] { name }); |
| throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); |
| } |
| |
| // Parameter is not recognized |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_FEATURE_NOT_FOUND, |
| new Object[] { name }); |
| throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
| } |
| } |
| // ************************************************************************ |
| |
| |
| // ************************************************************************ |
| // DOMConfiguraiton implementation |
| // ************************************************************************ |
| |
| /** |
| * Returns the DOMConfiguration of the LSSerializer. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#getDomConfig() |
| * @since DOM Level 3 |
| * @return A DOMConfiguration object. |
| */ |
| public DOMConfiguration getDomConfig() { |
| return (DOMConfiguration)this; |
| } |
| |
| /** |
| * Returns the DOMConfiguration of the LSSerializer. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#getFilter() |
| * @since DOM Level 3 |
| * @return A LSSerializerFilter object. |
| */ |
| public LSSerializerFilter getFilter() { |
| return fSerializerFilter; |
| } |
| |
| /** |
| * Returns the End-Of-Line sequence of characters to be used in the XML |
| * being serialized. If none is set a default "\n" is returned. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#getNewLine() |
| * @since DOM Level 3 |
| * @return A String containing the end-of-line character sequence used in |
| * serialization. |
| */ |
| public String getNewLine() { |
| return fEndOfLine; |
| } |
| |
| /** |
| * Set a LSSerilizerFilter on the LSSerializer. When set, the filter is |
| * called before each node is serialized which depending on its implemention |
| * determines if the node is to be serialized or not. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#setFilter |
| * @since DOM Level 3 |
| * @param filter A LSSerializerFilter to be applied to the stream to serialize. |
| */ |
| public void setFilter(LSSerializerFilter filter) { |
| fSerializerFilter = filter; |
| } |
| |
| /** |
| * Sets the End-Of-Line sequence of characters to be used in the XML |
| * being serialized. Setting this attribute to null will reset its |
| * value to the default value i.e. "\n". |
| * |
| * @see org.w3c.dom.ls.LSSerializer#setNewLine |
| * @since DOM Level 3 |
| * @param newLine a String that is the end-of-line character sequence to be used in |
| * serialization. |
| */ |
| public void setNewLine(String newLine) { |
| fEndOfLine = (newLine != null) ? newLine : DEFAULT_END_OF_LINE; |
| } |
| |
| /** |
| * Serializes the specified node to the specified LSOutput and returns true if the Node |
| * was successfully serialized. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#write(org.w3c.dom.Node, org.w3c.dom.ls.LSOutput) |
| * @since DOM Level 3 |
| * @param nodeArg The Node to serialize. |
| * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the |
| * LSSerializer was unable to serialize the node. |
| * |
| */ |
| public boolean write(Node nodeArg, LSOutput destination) throws LSException { |
| // If the destination is null |
| if (destination == null) { |
| String msg = Utils.messages |
| .createMessage( |
| MsgKey.ER_NO_OUTPUT_SPECIFIED, |
| null); |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, msg, |
| MsgKey.ER_NO_OUTPUT_SPECIFIED)); |
| } |
| throw new LSException(LSException.SERIALIZE_ERR, msg); |
| } |
| |
| // If nodeArg is null, return false. Should we throw and LSException instead? |
| if (nodeArg == null ) { |
| return false; |
| } |
| |
| // Obtain a reference to the serializer to use |
| // Serializer serializer = getXMLSerializer(xmlVersion); |
| Serializer serializer = fXMLSerializer; |
| serializer.reset(); |
| |
| // If the node has not been seen |
| if ( nodeArg != fVisitedNode) { |
| // Determine the XML Document version of the Node |
| String xmlVersion = getXMLVersion(nodeArg); |
| |
| // Determine the encoding: 1.LSOutput.encoding, 2.Document.inputEncoding, 3.Document.xmlEncoding. |
| fEncoding = destination.getEncoding(); |
| if (fEncoding == null ) { |
| fEncoding = getInputEncoding(nodeArg); |
| fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg); |
| } |
| |
| // If the encoding is not recognized throw an exception. |
| // Note: The serializer defaults to UTF-8 when created |
| if (!Encodings.isRecognizedEncoding(fEncoding)) { |
| String msg = Utils.messages |
| .createMessage( |
| MsgKey.ER_UNSUPPORTED_ENCODING, |
| null); |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, msg, |
| MsgKey.ER_UNSUPPORTED_ENCODING)); |
| } |
| throw new LSException(LSException.SERIALIZE_ERR, msg); |
| } |
| |
| serializer.getOutputFormat().setProperty("version", xmlVersion); |
| |
| // Set the output encoding and xml version properties |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion); |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding); |
| |
| // If the node to be serialized is not a Document, Element, or Entity |
| // node |
| // then the XML declaration, or text declaration, should be never be |
| // serialized. |
| if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE |
| || nodeArg.getNodeType() != Node.ELEMENT_NODE |
| || nodeArg.getNodeType() != Node.ENTITY_NODE) |
| && ((fFeatures & XMLDECL) != 0)) { |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| } |
| |
| fVisitedNode = nodeArg; |
| } |
| |
| // Update the serializer properties |
| fXMLSerializer.setOutputFormat(fDOMConfigProperties); |
| |
| // |
| try { |
| |
| // The LSSerializer will use the LSOutput object to determine |
| // where to serialize the output to in the following order the |
| // first one that is not null and not an empty string will be |
| // used: 1.LSOutput.characterStream, 2.LSOutput.byteStream, |
| // 3. LSOutput.systemId |
| // 1.LSOutput.characterStream |
| Writer writer = destination.getCharacterStream(); |
| if (writer == null ) { |
| |
| // 2.LSOutput.byteStream |
| OutputStream outputStream = destination.getByteStream(); |
| if ( outputStream == null) { |
| |
| // 3. LSOutput.systemId |
| String uri = destination.getSystemId(); |
| if (uri == null) { |
| String msg = Utils.messages |
| .createMessage( |
| MsgKey.ER_NO_OUTPUT_SPECIFIED, |
| null); |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, msg, |
| MsgKey.ER_NO_OUTPUT_SPECIFIED)); |
| } |
| throw new LSException(LSException.SERIALIZE_ERR, msg); |
| |
| } else { |
| // Expand the System Id and obtain an absolute URI for it. |
| String absoluteURI = SystemIDResolver.getAbsoluteURI(uri); |
| |
| URL url = new URL(absoluteURI); |
| OutputStream urlOutStream = null; |
| String protocol = url.getProtocol(); |
| String host = url.getHost(); |
| |
| // For file protocols, there is no need to use a URL to get its |
| // corresponding OutputStream |
| |
| // Scheme names consist of a sequence of characters. The lower case |
| // letters "a"--"z", digits, and the characters plus ("+"), period |
| // ("."), and hyphen ("-") are allowed. For resiliency, programs |
| // interpreting URLs should treat upper case letters as equivalent to |
| // lower case in scheme names (e.g., allow "HTTP" as well as "http"). |
| if (protocol.equalsIgnoreCase("file") |
| && (host == null || host.length() == 0 || host.equals("localhost"))) { |
| // do we also need to check for host.equals(hostname) |
| urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath())); |
| |
| } else { |
| // This should support URL's whose schemes are mentioned in |
| // RFC1738 other than file |
| |
| URLConnection urlCon = url.openConnection(); |
| urlCon.setDoInput(false); |
| urlCon.setDoOutput(true); |
| urlCon.setUseCaches(false); |
| urlCon.setAllowUserInteraction(false); |
| |
| // When writing to a HTTP URI, a HTTP PUT is performed. |
| if (urlCon instanceof HttpURLConnection) { |
| HttpURLConnection httpCon = (HttpURLConnection) urlCon; |
| httpCon.setRequestMethod("PUT"); |
| } |
| urlOutStream = urlCon.getOutputStream(); |
| } |
| // set the OutputStream to that obtained from the systemId |
| serializer.setOutputStream(urlOutStream); |
| } |
| } else { |
| // 2.LSOutput.byteStream |
| serializer.setOutputStream(outputStream); |
| } |
| } else { |
| // 1.LSOutput.characterStream |
| serializer.setWriter(writer); |
| } |
| |
| // The associated media type by default is set to text/xml on |
| // org.apache.xml.serializer.SerializerBase. |
| |
| // Get a reference to the serializer then lets you serilize a DOM |
| // Use this hack till Xalan support JAXP1.3 |
| if (fDOMSerializer == null) { |
| fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer(); |
| } |
| |
| // Set the error handler on the DOM3Serializer interface implementation |
| if (fDOMErrorHandler != null) { |
| fDOMSerializer.setErrorHandler(fDOMErrorHandler); |
| } |
| |
| // Set the filter on the DOM3Serializer interface implementation |
| if (fSerializerFilter != null) { |
| fDOMSerializer.setNodeFilter(fSerializerFilter); |
| } |
| |
| // Set the NewLine character to be used |
| fDOMSerializer.setNewLine(fEndOfLine.toCharArray()); |
| |
| // Serializer your DOM, where node is an org.w3c.dom.Node |
| // Assuming that Xalan's serializer can serialize any type of DOM node |
| fDOMSerializer.serializeDOM3(nodeArg); |
| |
| } catch( UnsupportedEncodingException ue) { |
| |
| String msg = Utils.messages |
| .createMessage( |
| MsgKey.ER_UNSUPPORTED_ENCODING, |
| null); |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, msg, |
| MsgKey.ER_UNSUPPORTED_ENCODING, ue)); |
| } |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, ue).fillInStackTrace(); |
| } catch (LSException lse) { |
| // Rethrow LSException. |
| throw lse; |
| } catch (RuntimeException e) { |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } catch (Exception e) { |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, e.getMessage(), |
| null, e)); |
| } |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } |
| return true; |
| } |
| |
| /** |
| * Serializes the specified node and returns a String with the serialized |
| * data to the caller. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#writeToString(org.w3c.dom.Node) |
| * @since DOM Level 3 |
| * @param nodeArg The Node to serialize. |
| * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the |
| * LSSerializer was unable to serialize the node. |
| * |
| */ |
| public String writeToString(Node nodeArg) throws DOMException, LSException { |
| // return null is nodeArg is null. Should an Exception be thrown instead? |
| if (nodeArg == null) { |
| return null; |
| } |
| |
| // Should we reset the serializer configuration before each write operation? |
| // Obtain a reference to the serializer to use |
| Serializer serializer = fXMLSerializer; |
| serializer.reset(); |
| |
| if (nodeArg != fVisitedNode){ |
| // Determine the XML Document version of the Node |
| String xmlVersion = getXMLVersion(nodeArg); |
| |
| serializer.getOutputFormat().setProperty("version", xmlVersion); |
| |
| // Set the output encoding and xml version properties |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion); |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, "UTF-16"); |
| |
| // If the node to be serialized is not a Document, Element, or Entity |
| // node |
| // then the XML declaration, or text declaration, should be never be |
| // serialized. |
| if ((nodeArg.getNodeType() != Node.DOCUMENT_NODE |
| || nodeArg.getNodeType() != Node.ELEMENT_NODE |
| || nodeArg.getNodeType() != Node.ENTITY_NODE) |
| && ((fFeatures & XMLDECL) != 0)) { |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| } |
| |
| fVisitedNode = nodeArg; |
| } |
| // Update the serializer properties |
| fXMLSerializer.setOutputFormat(fDOMConfigProperties); |
| |
| // StringWriter to Output to |
| StringWriter output = new StringWriter(); |
| |
| // |
| try { |
| |
| // Set the Serializer's Writer to a StringWriter |
| serializer.setWriter(output); |
| |
| // Get a reference to the serializer then lets you serilize a DOM |
| // Use this hack till Xalan support JAXP1.3 |
| if (fDOMSerializer == null) { |
| fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer(); |
| } |
| |
| // Set the error handler on the DOM3Serializer interface implementation |
| if (fDOMErrorHandler != null) { |
| fDOMSerializer.setErrorHandler(fDOMErrorHandler); |
| } |
| |
| // Set the filter on the DOM3Serializer interface implementation |
| if (fSerializerFilter != null) { |
| fDOMSerializer.setNodeFilter(fSerializerFilter); |
| } |
| |
| // Set the NewLine character to be used |
| fDOMSerializer.setNewLine(fEndOfLine.toCharArray()); |
| |
| // Serializer your DOM, where node is an org.w3c.dom.Node |
| fDOMSerializer.serializeDOM3(nodeArg); |
| } catch (LSException lse) { |
| // Rethrow LSException. |
| throw lse; |
| } catch (RuntimeException e) { |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } catch (Exception e) { |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, e.getMessage(), |
| null, e)); |
| } |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } |
| |
| // return the serialized string |
| return output.toString(); |
| } |
| |
| /** |
| * Serializes the specified node to the specified URI and returns true if the Node |
| * was successfully serialized. |
| * |
| * @see org.w3c.dom.ls.LSSerializer#writeToURI(org.w3c.dom.Node, String) |
| * @since DOM Level 3 |
| * @param nodeArg The Node to serialize. |
| * @throws org.w3c.dom.ls.LSException SERIALIZE_ERR: Raised if the |
| * LSSerializer was unable to serialize the node. |
| * |
| */ |
| public boolean writeToURI(Node nodeArg, String uri) throws LSException { |
| // If nodeArg is null, return false. Should we throw and LSException instead? |
| if (nodeArg == null ) { |
| return false; |
| } |
| |
| // Obtain a reference to the serializer to use |
| Serializer serializer = fXMLSerializer; |
| serializer.reset(); |
| |
| if (nodeArg != fVisitedNode) { |
| // Determine the XML Document version of the Node |
| String xmlVersion = getXMLVersion(nodeArg); |
| |
| // Determine the encoding: 1.LSOutput.encoding, |
| // 2.Document.inputEncoding, 3.Document.xmlEncoding. |
| fEncoding = getInputEncoding(nodeArg); |
| if (fEncoding == null ) { |
| fEncoding = fEncoding != null ? fEncoding : getXMLEncoding(nodeArg) == null? "UTF-8": getXMLEncoding(nodeArg); |
| } |
| |
| serializer.getOutputFormat().setProperty("version", xmlVersion); |
| |
| // Set the output encoding and xml version properties |
| fDOMConfigProperties.setProperty(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION, xmlVersion); |
| fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_ENCODING, fEncoding); |
| |
| // If the node to be serialized is not a Document, Element, or Entity |
| // node |
| // then the XML declaration, or text declaration, should be never be |
| // serialized. |
| if ( (nodeArg.getNodeType() != Node.DOCUMENT_NODE |
| || nodeArg.getNodeType() != Node.ELEMENT_NODE |
| || nodeArg.getNodeType() != Node.ENTITY_NODE) |
| && ((fFeatures & XMLDECL) != 0)) { |
| fDOMConfigProperties.setProperty( |
| DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, |
| DOMConstants.DOM3_DEFAULT_FALSE); |
| } |
| |
| fVisitedNode = nodeArg; |
| } |
| |
| // Update the serializer properties |
| fXMLSerializer.setOutputFormat(fDOMConfigProperties); |
| |
| // |
| try { |
| // If the specified encoding is not supported an |
| // "unsupported-encoding" fatal error is raised. ?? |
| if (uri == null) { |
| String msg = Utils.messages.createMessage( |
| MsgKey.ER_NO_OUTPUT_SPECIFIED, null); |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, msg, |
| MsgKey.ER_NO_OUTPUT_SPECIFIED)); |
| } |
| throw new LSException(LSException.SERIALIZE_ERR, msg); |
| |
| } else { |
| // REVISIT: Can this be used to get an absolute expanded URI |
| String absoluteURI = SystemIDResolver.getAbsoluteURI(uri); |
| |
| URL url = new URL(absoluteURI); |
| OutputStream urlOutStream = null; |
| String protocol = url.getProtocol(); |
| String host = url.getHost(); |
| |
| // For file protocols, there is no need to use a URL to get its |
| // corresponding OutputStream |
| |
| // Scheme names consist of a sequence of characters. The lower |
| // case letters "a"--"z", digits, and the characters plus ("+"), |
| // period ("."), and hyphen ("-") are allowed. For resiliency, |
| // programs interpreting URLs should treat upper case letters as |
| // equivalent to lower case in scheme names |
| // (e.g., allow "HTTP" as well as "http"). |
| if (protocol.equalsIgnoreCase("file") |
| && (host == null || host.length() == 0 || host |
| .equals("localhost"))) { |
| // do we also need to check for host.equals(hostname) |
| urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath())); |
| |
| } else { |
| // This should support URL's whose schemes are mentioned in |
| // RFC1738 other than file |
| |
| URLConnection urlCon = url.openConnection(); |
| urlCon.setDoInput(false); |
| urlCon.setDoOutput(true); |
| urlCon.setUseCaches(false); |
| urlCon.setAllowUserInteraction(false); |
| |
| // When writing to a HTTP URI, a HTTP PUT is performed. |
| if (urlCon instanceof HttpURLConnection) { |
| HttpURLConnection httpCon = (HttpURLConnection) urlCon; |
| httpCon.setRequestMethod("PUT"); |
| } |
| urlOutStream = urlCon.getOutputStream(); |
| } |
| // set the OutputStream to that obtained from the systemId |
| serializer.setOutputStream(urlOutStream); |
| } |
| |
| // Get a reference to the serializer then lets you serilize a DOM |
| // Use this hack till Xalan support JAXP1.3 |
| if (fDOMSerializer == null) { |
| fDOMSerializer = (DOM3Serializer)serializer.asDOM3Serializer(); |
| } |
| |
| // Set the error handler on the DOM3Serializer interface implementation |
| if (fDOMErrorHandler != null) { |
| fDOMSerializer.setErrorHandler(fDOMErrorHandler); |
| } |
| |
| // Set the filter on the DOM3Serializer interface implementation |
| if (fSerializerFilter != null) { |
| fDOMSerializer.setNodeFilter(fSerializerFilter); |
| } |
| |
| // Set the NewLine character to be used |
| fDOMSerializer.setNewLine(fEndOfLine.toCharArray()); |
| |
| // Serializer your DOM, where node is an org.w3c.dom.Node |
| // Assuming that Xalan's serializer can serialize any type of DOM |
| // node |
| fDOMSerializer.serializeDOM3(nodeArg); |
| |
| } catch (LSException lse) { |
| // Rethrow LSException. |
| throw lse; |
| } catch (RuntimeException e) { |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } catch (Exception e) { |
| if (fDOMErrorHandler != null) { |
| fDOMErrorHandler.handleError(new DOMErrorImpl( |
| DOMError.SEVERITY_FATAL_ERROR, e.getMessage(), |
| null, e)); |
| } |
| throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); |
| } |
| |
| return true; |
| } |
| // ************************************************************************ |
| |
| |
| // ************************************************************************ |
| // Implementaion methods |
| // ************************************************************************ |
| |
| /** |
| * Determines the XML Version of the Document Node to serialize. If the Document Node |
| * is not a DOM Level 3 Node, then the default version returned is 1.0. |
| * |
| * @param nodeArg The Node to serialize |
| * @return A String containing the version pseudo-attribute of the XMLDecl. |
| * @throws Throwable if the DOM implementation does not implement Document.getXmlVersion() |
| */ |
| //protected String getXMLVersion(Node nodeArg) throws Throwable { |
| protected String getXMLVersion(Node nodeArg) { |
| Document doc = null; |
| |
| // Determine the XML Version of the document |
| if (nodeArg != null) { |
| if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) { |
| // The Document node is the Node argument |
| doc = (Document)nodeArg; |
| } else { |
| // The Document node is the Node argument's ownerDocument |
| doc = nodeArg.getOwnerDocument(); |
| } |
| |
| // Determine the DOM Version. |
| if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) { |
| return doc.getXmlVersion(); |
| } |
| } |
| // The version will be treated as "1.0" which may result in |
| // an ill-formed document being serialized. |
| // If nodeArg does not have an ownerDocument, treat this as XML 1.0 |
| return "1.0"; |
| } |
| |
| /** |
| * Determines the XML Encoding of the Document Node to serialize. If the Document Node |
| * is not a DOM Level 3 Node, then the default encoding "UTF-8" is returned. |
| * |
| * @param nodeArg The Node to serialize |
| * @return A String containing the encoding pseudo-attribute of the XMLDecl. |
| * @throws Throwable if the DOM implementation does not implement Document.getXmlEncoding() |
| */ |
| protected String getXMLEncoding(Node nodeArg) { |
| Document doc = null; |
| |
| // Determine the XML Encoding of the document |
| if (nodeArg != null) { |
| if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) { |
| // The Document node is the Node argument |
| doc = (Document)nodeArg; |
| } else { |
| // The Document node is the Node argument's ownerDocument |
| doc = nodeArg.getOwnerDocument(); |
| } |
| |
| // Determine the XML Version. |
| if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) { |
| return doc.getXmlEncoding(); |
| } |
| } |
| // The default encoding is UTF-8 except for the writeToString method |
| return "UTF-8"; |
| } |
| |
| /** |
| * Determines the Input Encoding of the Document Node to serialize. If the Document Node |
| * is not a DOM Level 3 Node, then null is returned. |
| * |
| * @param nodeArg The Node to serialize |
| * @return A String containing the input encoding. |
| */ |
| protected String getInputEncoding(Node nodeArg) { |
| Document doc = null; |
| |
| // Determine the Input Encoding of the document |
| if (nodeArg != null) { |
| if (nodeArg.getNodeType() == Node.DOCUMENT_NODE) { |
| // The Document node is the Node argument |
| doc = (Document)nodeArg; |
| } else { |
| // The Document node is the Node argument's ownerDocument |
| doc = nodeArg.getOwnerDocument(); |
| } |
| |
| // Determine the DOM Version. |
| if (doc != null && doc.getImplementation().hasFeature("Core","3.0")) { |
| return doc.getInputEncoding(); |
| } |
| } |
| // The default encoding returned is null |
| return null; |
| } |
| |
| /** |
| * This method returns the LSSerializer's error handler. |
| * |
| * @return Returns the fDOMErrorHandler. |
| */ |
| public DOMErrorHandler getErrorHandler() { |
| return fDOMErrorHandler; |
| } |
| |
| /** |
| * Replaces all escape sequences in the given path with their literal characters. |
| */ |
| private static String getPathWithoutEscapes(String origPath) { |
| if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) { |
| // Locate the escape characters |
| StringTokenizer tokenizer = new StringTokenizer(origPath, "%"); |
| StringBuffer result = new StringBuffer(origPath.length()); |
| int size = tokenizer.countTokens(); |
| result.append(tokenizer.nextToken()); |
| for(int i = 1; i < size; ++i) { |
| String token = tokenizer.nextToken(); |
| if (token.length() >= 2 && isHexDigit(token.charAt(0)) && |
| isHexDigit(token.charAt(1))) { |
| // Decode the 2 digit hexadecimal number following % in '%nn' |
| result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue()); |
| token = token.substring(2); |
| } |
| result.append(token); |
| } |
| return result.toString(); |
| } |
| return origPath; |
| } |
| |
| /** |
| * Returns true if the given character is a valid hex character. |
| */ |
| private static boolean isHexDigit(char c) { |
| return (c >= '0' && c <= '9' || |
| c >= 'a' && c <= 'f' || |
| c >= 'A' && c <= 'F'); |
| } |
| |
| /** |
| * Creates an LSException. On J2SE 1.4 and above the cause for the exception will be set. |
| */ |
| private static LSException createLSException(short code, Throwable cause) { |
| LSException lse = new LSException(code, cause != null ? cause.getMessage() : null); |
| if (cause != null && ThrowableMethods.fgThrowableMethodsAvailable) { |
| try { |
| ThrowableMethods.fgThrowableInitCauseMethod.invoke(lse, new Object [] {cause}); |
| } |
| // Something went wrong. There's not much we can do about it. |
| catch (Exception e) {} |
| } |
| return lse; |
| } |
| |
| /** |
| * Holder of methods from java.lang.Throwable. |
| */ |
| static class ThrowableMethods { |
| |
| // Method: java.lang.Throwable.initCause(java.lang.Throwable) |
| private static java.lang.reflect.Method fgThrowableInitCauseMethod = null; |
| |
| // Flag indicating whether or not Throwable methods available. |
| private static boolean fgThrowableMethodsAvailable = false; |
| |
| private ThrowableMethods() {} |
| |
| // Attempt to get methods for java.lang.Throwable on class initialization. |
| static { |
| try { |
| fgThrowableInitCauseMethod = Throwable.class.getMethod("initCause", new Class [] {Throwable.class}); |
| fgThrowableMethodsAvailable = true; |
| } |
| // ClassNotFoundException, NoSuchMethodException or SecurityException |
| // Whatever the case, we cannot use java.lang.Throwable.initCause(java.lang.Throwable). |
| catch (Exception exc) { |
| fgThrowableInitCauseMethod = null; |
| fgThrowableMethodsAvailable = false; |
| } |
| } |
| } |
| } |