--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Thu Apr 12 08:38:26 2012 -0700
@@ -0,0 +1,1212 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+package com.sun.org.apache.xml.internal.serialize;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
+import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
+import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
+import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
+import com.sun.org.apache.xerces.internal.dom.DOMNormalizer;
+import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.DOMStringList;
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
+import com.sun.org.apache.xerces.internal.util.DOMUtil;
+import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.util.XML11Char;
+import com.sun.org.apache.xerces.internal.util.XMLChar;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+import org.w3c.dom.ls.LSSerializerFilter;
+
+
+/**
+ * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer by delegating serialization
+ * calls to <CODE>XMLSerializer</CODE>.
+ * LSSerializer provides an API for serializing (writing) a DOM document out in an
+ * XML document. The XML data is written to an output stream.
+ * During serialization of XML data, namespace fixup is done when possible as
+ * defined in DOM Level 3 Core, Appendix B.
+ *
+ * @author Elena Litani, IBM
+ * @author Gopal Sharma, Sun Microsystems
+ * @author Arun Yadav, Sun Microsystems
+ * @author Sunitha Reddy, Sun Microsystems
+ * @version $Id: DOMSerializerImpl.java,v 1.11 2010-11-01 04:40:36 joehw Exp $
+ */
+public class DOMSerializerImpl implements LSSerializer, DOMConfiguration {
+
+ // TODO: When DOM Level 3 goes to REC replace method calls using
+ // reflection for: getXmlEncoding, getInputEncoding and getXmlEncoding
+ // with regular static calls on the Document object.
+
+ // data
+ // serializer
+ private XMLSerializer serializer;
+
+ // XML 1.1 serializer
+ private XML11Serializer xml11Serializer;
+
+ //Recognized parameters
+ private DOMStringList fRecognizedParameters;
+
+ /** REVISIT: Currently we handle 3 different configurations, would be nice just have one configuration
+ * that has different recognized parameters depending if it is used in Core/LS.
+ */
+ protected short features = 0;
+
+ protected final static short NAMESPACES = 0x1<<0;
+ protected final static short WELLFORMED = 0x1<<1;
+ protected final static short ENTITIES = 0x1<<2;
+ protected final static short CDATA = 0x1<<3;
+ protected final static short SPLITCDATA = 0x1<<4;
+ protected final static short COMMENTS = 0x1<<5;
+ protected final static short DISCARDDEFAULT = 0x1<<6;
+ protected final static short INFOSET = 0x1<<7;
+ protected final static short XMLDECL = 0x1<<8;
+ protected final static short NSDECL = 0x1<<9;
+ protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1<<10;
+ protected final static short FORMAT_PRETTY_PRINT = 0x1<<11;
+
+ // well-formness checking
+ private DOMErrorHandler fErrorHandler = null;
+ private final DOMErrorImpl fError = new DOMErrorImpl();
+ private final DOMLocatorImpl fLocator = new DOMLocatorImpl();
+ private static final RuntimeException abort = new RuntimeException();
+
+ /**
+ * Constructs a new LSSerializer.
+ * The constructor turns on the namespace support in <code>XMLSerializer</code> and
+ * initializes the following fields: fNSBinder, fLocalNSBinder, fSymbolTable,
+ * fEmptySymbol, fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures.
+ */
+ public DOMSerializerImpl() {
+ // set default features
+ features |= NAMESPACES;
+ features |= ENTITIES;
+ features |= COMMENTS;
+ features |= CDATA;
+ features |= SPLITCDATA;
+ features |= WELLFORMED;
+ features |= NSDECL;
+ features |= DOM_ELEMENT_CONTENT_WHITESPACE;
+ features |= DISCARDDEFAULT;
+ features |= XMLDECL;
+
+ serializer = new XMLSerializer();
+ initSerializer(serializer);
+ }
+
+
+
+ //
+ // LSSerializer methods
+ //
+
+ public DOMConfiguration getDomConfig(){
+ return this;
+ }
+
+ /** DOM L3-EXPERIMENTAL:
+ * Setter for boolean and object parameters
+ */
+ public void setParameter(String name, Object value) throws DOMException {
+ if (value instanceof Boolean) {
+ boolean state = ((Boolean) value).booleanValue();
+ if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){
+ if (state){
+ features &= ~ENTITIES;
+ features &= ~CDATA;
+ features |= NAMESPACES;
+ features |= NSDECL;
+ features |= WELLFORMED;
+ features |= COMMENTS;
+ }
+ // false does not have any effect
+ } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
+ features =
+ (short) (state ? features | XMLDECL : features & ~XMLDECL);
+ } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
+ features =
+ (short) (state
+ ? features | NAMESPACES
+ : features & ~NAMESPACES);
+ serializer.fNamespaces = state;
+ } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
+ features =
+ (short) (state
+ ? features | SPLITCDATA
+ : features & ~SPLITCDATA);
+ } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
+ features =
+ (short) (state
+ ? features | DISCARDDEFAULT
+ : features & ~DISCARDDEFAULT);
+ } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
+ features =
+ (short) (state
+ ? features | WELLFORMED
+ : features & ~WELLFORMED);
+ } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)){
+ features =
+ (short) (state
+ ? features | ENTITIES
+ : features & ~ENTITIES);
+ }
+ else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)){
+ features =
+ (short) (state
+ ? features | CDATA
+ : features & ~CDATA);
+ }
+ else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)){
+ features =
+ (short) (state
+ ? features | COMMENTS
+ : features & ~COMMENTS);
+ }
+ else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)){
+ features =
+ (short) (state
+ ? features | FORMAT_PRETTY_PRINT
+ : features & ~FORMAT_PRETTY_PRINT);
+ }
+ else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
+ || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
+ || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
+ // || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
+ // true is not supported
+ if (state) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_SUPPORTED",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+ }
+ }else if (
+ name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
+ //namespace-declaration has effect only if namespaces is true
+ features =
+ (short) (state
+ ? features | NSDECL
+ : features & ~NSDECL);
+ serializer.fNamespacePrefixes = state;
+ } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
+ || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+ // false is not supported
+ if (!state) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_SUPPORTED",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+ }
+ } else {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_FOUND",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+ }
+ } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
+ if (value == null || value instanceof DOMErrorHandler) {
+ fErrorHandler = (DOMErrorHandler)value;
+ } else {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "TYPE_MISMATCH_ERR",
+ new Object[] { name });
+ throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+ }
+ } else if (
+ name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
+ || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
+ || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)
+ || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
+ && value != null) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_SUPPORTED",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+ } else {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_FOUND",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+ }
+ }
+
+ /** DOM L3-EXPERIMENTAL:
+ * Check if parameter can be set
+ */
+ public boolean canSetParameter(String name, Object state) {
+
+ if (state == null) {
+ return true;
+ }
+
+ if (state instanceof Boolean) {
+ boolean value = ((Boolean) state).booleanValue();
+
+ if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)
+ || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)
+ || name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)
+ || name.equalsIgnoreCase(Constants.DOM_XMLDECL)
+ || name.equalsIgnoreCase(Constants.DOM_WELLFORMED)
+ || name.equalsIgnoreCase(Constants.DOM_INFOSET)
+ || name.equalsIgnoreCase(Constants.DOM_ENTITIES)
+ || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)
+ || name.equalsIgnoreCase(Constants.DOM_COMMENTS)
+ || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)
+ || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
+ // both values supported
+ return true;
+ } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
+ || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
+ || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
+ // || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
+ // true is not supported
+ return !value;
+ } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
+ || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+ // false is not supported
+ return value;
+ }
+ } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER) &&
+ state == null || state instanceof DOMErrorHandler) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * DOM Level 3 Core CR - Experimental.
+ *
+ * The list of the parameters supported by this
+ * <code>DOMConfiguration</code> object and for which at least one value
+ * can be set by the application. Note that this list can also contain
+ * parameter names defined outside this specification.
+ */
+ public DOMStringList getParameterNames() {
+
+ if (fRecognizedParameters == null){
+ Vector parameters = new Vector();
+
+ //Add DOM recognized parameters
+ //REVISIT: Would have been nice to have a list of
+ //recognized parameters.
+ parameters.add(Constants.DOM_NAMESPACES);
+ parameters.add(Constants.DOM_SPLIT_CDATA);
+ parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT);
+ parameters.add(Constants.DOM_XMLDECL);
+ parameters.add(Constants.DOM_CANONICAL_FORM);
+ parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
+ parameters.add(Constants.DOM_VALIDATE);
+ parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
+ parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
+ parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT);
+ //parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
+ parameters.add(Constants.DOM_WELLFORMED);
+ parameters.add(Constants.DOM_INFOSET);
+ parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
+ parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
+ parameters.add(Constants.DOM_ENTITIES);
+ parameters.add(Constants.DOM_CDATA_SECTIONS);
+ parameters.add(Constants.DOM_COMMENTS);
+ parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
+ parameters.add(Constants.DOM_ERROR_HANDLER);
+ //parameters.add(Constants.DOM_SCHEMA_LOCATION);
+ //parameters.add(Constants.DOM_SCHEMA_TYPE);
+
+ //Add recognized xerces features and properties
+
+ fRecognizedParameters = new DOMStringListImpl(parameters);
+
+ }
+
+ return fRecognizedParameters;
+ }
+
+ /** DOM L3-EXPERIMENTAL:
+ * Getter for boolean and object parameters
+ */
+ public Object getParameter(String name) throws DOMException {
+
+ if(name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)){
+ return null;
+ } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
+ return ((features & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
+ return (features & NAMESPACES) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
+ return (features & XMLDECL) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
+ return (features & CDATA) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
+ return (features & ENTITIES) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
+ return (features & SPLITCDATA) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
+ return (features & WELLFORMED) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
+ return (features & NSDECL) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
+ return (features & FORMAT_PRETTY_PRINT) != 0 ? Boolean.TRUE : Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) ||
+ name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+ return Boolean.TRUE;
+ }else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)){
+ return ((features & DISCARDDEFAULT)!=0)?Boolean.TRUE:Boolean.FALSE;
+ }else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){
+ if ((features & ENTITIES) == 0 &&
+ (features & CDATA) == 0 &&
+ (features & NAMESPACES) != 0 &&
+ (features & NSDECL) != 0 &&
+ (features & WELLFORMED) != 0 &&
+ (features & COMMENTS) != 0) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
+ || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
+ || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
+ || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
+ return Boolean.FALSE;
+ } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
+ return fErrorHandler;
+ } else if (
+ name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
+ || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
+ || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_SUPPORTED",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+ } else {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "FEATURE_NOT_FOUND",
+ new Object[] { name });
+ throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+ }
+ }
+
+
+ /**
+ * DOM L3 EXPERIMENTAL:
+ * Serialize the specified node as described above in the description of
+ * <code>LSSerializer</code>. The result of serializing the node is
+ * returned as a string. Writing a Document or Entity node produces a
+ * serialized form that is well formed XML. Writing other node types
+ * produces a fragment of text in a form that is not fully defined by
+ * this document, but that should be useful to a human for debugging or
+ * diagnostic purposes.
+ * @param wnode The node to be written.
+ * @return Returns the serialized data
+ * @exception DOMException
+ * DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a
+ * <code>DOMString</code>.
+ * @exception LSException
+ * SERIALIZE_ERR: Unable to serialize the node. DOM applications should
+ * attach a <code>DOMErrorHandler</code> using the parameter
+ * "<i>error-handler</i>" to get details on error.
+ */
+ public String writeToString(Node wnode) throws DOMException, LSException {
+ // determine which serializer to use:
+ Document doc = (wnode.getNodeType() == Node.DOCUMENT_NODE)?(Document)wnode:wnode.getOwnerDocument();
+ Method getVersion = null;
+ XMLSerializer ser = null;
+ String ver = null;
+ // this should run under JDK 1.1.8...
+ try {
+ getVersion = doc.getClass().getMethod("getXmlVersion", new Class[]{});
+ if(getVersion != null ) {
+ ver = (String)getVersion.invoke(doc, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // no way to test the version...
+ // ignore the exception
+ }
+ if(ver != null && ver.equals("1.1")) {
+ if(xml11Serializer == null) {
+ xml11Serializer = new XML11Serializer();
+ initSerializer(xml11Serializer);
+ }
+ // copy setting from "main" serializer to XML 1.1 serializer
+ copySettings(serializer, xml11Serializer);
+ ser = xml11Serializer;
+ } else {
+ ser = serializer;
+ }
+
+ StringWriter destination = new StringWriter();
+ try {
+ prepareForSerialization(ser, wnode);
+ ser._format.setEncoding("UTF-16");
+ ser.setOutputCharStream(destination);
+ if (wnode.getNodeType() == Node.DOCUMENT_NODE) {
+ ser.serialize((Document)wnode);
+ }
+ else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
+ ser.serialize((DocumentFragment)wnode);
+ }
+ else if (wnode.getNodeType() == Node.ELEMENT_NODE) {
+ ser.serialize((Element)wnode);
+ }
+ else if (wnode.getNodeType() == Node.TEXT_NODE ||
+ wnode.getNodeType() == Node.COMMENT_NODE ||
+ wnode.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
+ wnode.getNodeType() == Node.CDATA_SECTION_NODE ||
+ wnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
+ ser.serialize(wnode);
+ }
+ else {
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.SERIALIZER_DOMAIN,
+ "unable-to-serialize-node", null);
+ if (ser.fDOMErrorHandler != null) {
+ DOMErrorImpl error = new DOMErrorImpl();
+ error.fType = "unable-to-serialize-node";
+ error.fMessage = msg;
+ error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
+ ser.fDOMErrorHandler.handleError(error);
+ }
+ throw new LSException(LSException.SERIALIZE_ERR, msg);
+ }
+ } catch (LSException lse) {
+ // Rethrow LSException.
+ throw lse;
+ } catch (RuntimeException e) {
+ if (e == DOMNormalizer.abort){
+ // stopped at user request
+ return null;
+ }
+ throw (LSException) new LSException(LSException.SERIALIZE_ERR, e.toString()).initCause(e);
+ } catch (IOException ioe) {
+ // REVISIT: A generic IOException doesn't provide enough information
+ // to determine that the serialized document is too large to fit
+ // into a string. This could have thrown for some other reason. -- mrglavas
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "STRING_TOO_LONG",
+ new Object[] { ioe.getMessage()});
+ throw (DOMException) new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg).initCause(ioe);
+ }
+
+ return destination.toString();
+ }
+
+ /**
+ * DOM L3 EXPERIMENTAL:
+ * The end-of-line sequence of characters to be used in the XML being
+ * written out. The only permitted values are these:
+ * <dl>
+ * <dt><code>null</code></dt>
+ * <dd>
+ * Use a default end-of-line sequence. DOM implementations should choose
+ * the default to match the usual convention for text files in the
+ * environment being used. Implementations must choose a default
+ * sequence that matches one of those allowed by 2.11 "End-of-Line
+ * Handling". </dd>
+ * <dt>CR</dt>
+ * <dd>The carriage-return character (#xD).</dd>
+ * <dt>CR-LF</dt>
+ * <dd> The
+ * carriage-return and line-feed characters (#xD #xA). </dd>
+ * <dt>LF</dt>
+ * <dd> The line-feed
+ * character (#xA). </dd>
+ * </dl>
+ * <br>The default value for this attribute is <code>null</code>.
+ */
+ public void setNewLine(String newLine) {
+ serializer._format.setLineSeparator(newLine);
+ }
+
+
+ /**
+ * DOM L3 EXPERIMENTAL:
+ * The end-of-line sequence of characters to be used in the XML being
+ * written out. The only permitted values are these:
+ * <dl>
+ * <dt><code>null</code></dt>
+ * <dd>
+ * Use a default end-of-line sequence. DOM implementations should choose
+ * the default to match the usual convention for text files in the
+ * environment being used. Implementations must choose a default
+ * sequence that matches one of those allowed by 2.11 "End-of-Line
+ * Handling". </dd>
+ * <dt>CR</dt>
+ * <dd>The carriage-return character (#xD).</dd>
+ * <dt>CR-LF</dt>
+ * <dd> The
+ * carriage-return and line-feed characters (#xD #xA). </dd>
+ * <dt>LF</dt>
+ * <dd> The line-feed
+ * character (#xA). </dd>
+ * </dl>
+ * <br>The default value for this attribute is <code>null</code>.
+ */
+ public String getNewLine() {
+ return serializer._format.getLineSeparator();
+ }
+
+
+ /**
+ * When the application provides a filter, the serializer will call out
+ * to the filter before serializing each Node. Attribute nodes are never
+ * passed to the filter. The filter implementation can choose to remove
+ * the node from the stream or to terminate the serialization early.
+ */
+ public LSSerializerFilter getFilter(){
+ return serializer.fDOMFilter;
+ }
+ /**
+ * When the application provides a filter, the serializer will call out
+ * to the filter before serializing each Node. Attribute nodes are never
+ * passed to the filter. The filter implementation can choose to remove
+ * the node from the stream or to terminate the serialization early.
+ */
+ public void setFilter(LSSerializerFilter filter){
+ serializer.fDOMFilter = filter;
+ }
+
+ // this initializes a newly-created serializer
+ private void initSerializer(XMLSerializer ser) {
+ ser.fNSBinder = new NamespaceSupport();
+ ser.fLocalNSBinder = new NamespaceSupport();
+ ser.fSymbolTable = new SymbolTable();
+ }
+
+ // copies all settings that could have been modified
+ // by calls to LSSerializer methods from one serializer to another.
+ // IMPORTANT: if new methods are implemented or more settings of
+ // the serializer are made alterable, this must be
+ // reflected in this method!
+ private void copySettings(XMLSerializer src, XMLSerializer dest) {
+ dest.fDOMErrorHandler = fErrorHandler;
+ dest._format.setEncoding(src._format.getEncoding());
+ dest._format.setLineSeparator(src._format.getLineSeparator());
+ dest.fDOMFilter = src.fDOMFilter;
+ }//copysettings
+
+ /**
+ * Serialize the specified node as described above in the general
+ * description of the <code>LSSerializer</code> interface. The output
+ * is written to the supplied <code>LSOutput</code>.
+ * <br> When writing to a <code>LSOutput</code>, the encoding is found by
+ * looking at the encoding information that is reachable through the
+ * <code>LSOutput</code> and the item to be written (or its owner
+ * document) in this order:
+ * <ol>
+ * <li> <code>LSOutput.encoding</code>,
+ * </li>
+ * <li>
+ * <code>Document.actualEncoding</code>,
+ * </li>
+ * <li>
+ * <code>Document.xmlEncoding</code>.
+ * </li>
+ * </ol>
+ * <br> If no encoding is reachable through the above properties, a
+ * default encoding of "UTF-8" will be used.
+ * <br> If the specified encoding is not supported an
+ * "unsupported-encoding" error is raised.
+ * <br> If no output is specified in the <code>LSOutput</code>, a
+ * "no-output-specified" error is raised.
+ * @param node The node to serialize.
+ * @param destination The destination for the serialized DOM.
+ * @return Returns <code>true</code> if <code>node</code> was
+ * successfully serialized and <code>false</code> in case the node
+ * couldn't be serialized.
+ */
+ public boolean write(Node node, LSOutput destination) throws LSException{
+
+ if (node == null)
+ return false;
+
+ Method getVersion = null;
+ XMLSerializer ser = null;
+ String ver = null;
+ Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE)
+ ? (Document) node
+ : node.getOwnerDocument();
+ // this should run under JDK 1.1.8...
+ try {
+ getVersion = fDocument.getClass().getMethod("getXmlVersion", new Class[] {});
+ if (getVersion != null) {
+ ver = (String) getVersion.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ //no way to test the version...
+ //ignore the exception
+ }
+ //determine which serializer to use:
+ if (ver != null && ver.equals("1.1")) {
+ if (xml11Serializer == null) {
+ xml11Serializer = new XML11Serializer();
+ initSerializer(xml11Serializer);
+ }
+ //copy setting from "main" serializer to XML 1.1 serializer
+ copySettings(serializer, xml11Serializer);
+ ser = xml11Serializer;
+ } else {
+ ser = serializer;
+ }
+
+ String encoding = null;
+ if ((encoding = destination.getEncoding()) == null) {
+ try {
+ Method getEncoding =
+ fDocument.getClass().getMethod("getInputEncoding", new Class[] {});
+ if (getEncoding != null) {
+ encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ if (encoding == null) {
+ try {
+ Method getEncoding =
+ fDocument.getClass().getMethod("getXmlEncoding", new Class[] {});
+ if (getEncoding != null) {
+ encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ if (encoding == null) {
+ encoding = "UTF-8";
+ }
+ }
+ }
+ try {
+ prepareForSerialization(ser, node);
+ ser._format.setEncoding(encoding);
+ OutputStream outputStream = destination.getByteStream();
+ Writer writer = destination.getCharacterStream();
+ String uri = destination.getSystemId();
+ if (writer == null) {
+ if (outputStream == null) {
+ if (uri == null) {
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.SERIALIZER_DOMAIN,
+ "no-output-specified", null);
+ if (ser.fDOMErrorHandler != null) {
+ DOMErrorImpl error = new DOMErrorImpl();
+ error.fType = "no-output-specified";
+ error.fMessage = msg;
+ error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
+ ser.fDOMErrorHandler.handleError(error);
+ }
+ throw new LSException(LSException.SERIALIZE_ERR, msg);
+ }
+ else {
+ // URI was specified. Handle relative URIs.
+ String expanded = XMLEntityManager.expandSystemId(uri, null, true);
+ URL url = new URL(expanded != null ? expanded : uri);
+ OutputStream out = null;
+ String protocol = url.getProtocol();
+ String host = url.getHost();
+ // Use FileOutputStream if this URI is for a local file.
+ if (protocol.equals("file")
+ && (host == null || host.length() == 0 || host.equals("localhost"))) {
+ out = new FileOutputStream(getPathWithoutEscapes(url.getFile()));
+ }
+ // Try to write to some other kind of URI. Some protocols
+ // won't support this, though HTTP should work.
+ else {
+ URLConnection urlCon = url.openConnection();
+ urlCon.setDoInput(false);
+ urlCon.setDoOutput(true);
+ urlCon.setUseCaches(false); // Enable tunneling.
+ if (urlCon instanceof HttpURLConnection) {
+ // The DOM L3 LS CR says if we are writing to an HTTP URI
+ // it is to be done with an HTTP PUT.
+ HttpURLConnection httpCon = (HttpURLConnection) urlCon;
+ httpCon.setRequestMethod("PUT");
+ }
+ out = urlCon.getOutputStream();
+ }
+ ser.setOutputByteStream(out);
+ }
+ }
+ else {
+ // byte stream was specified
+ ser.setOutputByteStream(outputStream);
+ }
+ }
+ else {
+ // character stream is specified
+ ser.setOutputCharStream(writer);
+ }
+
+ if (node.getNodeType() == Node.DOCUMENT_NODE)
+ ser.serialize((Document) node);
+ else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
+ ser.serialize((DocumentFragment) node);
+ else if (node.getNodeType() == Node.ELEMENT_NODE)
+ ser.serialize((Element) node);
+ else if (node.getNodeType() == Node.TEXT_NODE ||
+ node.getNodeType() == Node.COMMENT_NODE ||
+ node.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
+ node.getNodeType() == Node.CDATA_SECTION_NODE ||
+ node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
+ ser.serialize(node);
+ }
+ else
+ return false;
+ } catch( UnsupportedEncodingException ue) {
+ if (ser.fDOMErrorHandler != null) {
+ DOMErrorImpl error = new DOMErrorImpl();
+ error.fException = ue;
+ error.fType = "unsupported-encoding";
+ error.fMessage = ue.getMessage();
+ error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
+ ser.fDOMErrorHandler.handleError(error);
+ }
+ throw new LSException(LSException.SERIALIZE_ERR,
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.SERIALIZER_DOMAIN,
+ "unsupported-encoding", null));
+ //return false;
+ } catch (LSException lse) {
+ // Rethrow LSException.
+ throw lse;
+ } catch (RuntimeException e) {
+ if (e == DOMNormalizer.abort){
+ // stopped at user request
+ return false;
+ }
+ throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+ } catch (Exception e) {
+ if (ser.fDOMErrorHandler != null) {
+ DOMErrorImpl error = new DOMErrorImpl();
+ error.fException = e;
+ error.fMessage = e.getMessage();
+ error.fSeverity = DOMError.SEVERITY_ERROR;
+ ser.fDOMErrorHandler.handleError(error);
+
+ }
+ e.printStackTrace();
+ throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+ }
+ return true;
+
+ } //write
+
+ /**
+ * Serialize the specified node as described above in the general
+ * description of the <code>LSSerializer</code> interface. The output
+ * is written to the supplied URI.
+ * <br> When writing to a URI, the encoding is found by looking at the
+ * encoding information that is reachable through the item to be written
+ * (or its owner document) in this order:
+ * <ol>
+ * <li>
+ * <code>Document.inputEncoding</code>,
+ * </li>
+ * <li>
+ * <code>Document.xmlEncoding</code>.
+ * </li>
+ * </ol>
+ * <br> If no encoding is reachable through the above properties, a
+ * default encoding of "UTF-8" will be used.
+ * <br> If the specified encoding is not supported an
+ * "unsupported-encoding" error is raised.
+ * @param node The node to serialize.
+ * @param URI The URI to write to.
+ * @return Returns <code>true</code> if <code>node</code> was
+ * successfully serialized and <code>false</code> in case the node
+ * couldn't be serialized.
+ */
+ public boolean writeToURI(Node node, String URI) throws LSException{
+ if (node == null){
+ return false;
+ }
+
+ Method getXmlVersion = null;
+ XMLSerializer ser = null;
+ String ver = null;
+ String encoding = null;
+
+ Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE)
+ ? (Document) node
+ : node.getOwnerDocument();
+ // this should run under JDK 1.1.8...
+ try {
+ getXmlVersion =
+ fDocument.getClass().getMethod("getXmlVersion", new Class[] {});
+ if (getXmlVersion != null) {
+ ver = (String) getXmlVersion.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // no way to test the version...
+ // ignore the exception
+ }
+ if (ver != null && ver.equals("1.1")) {
+ if (xml11Serializer == null) {
+ xml11Serializer = new XML11Serializer();
+ initSerializer(xml11Serializer);
+ }
+ // copy setting from "main" serializer to XML 1.1 serializer
+ copySettings(serializer, xml11Serializer);
+ ser = xml11Serializer;
+ } else {
+ ser = serializer;
+ }
+
+ try {
+ Method getEncoding =
+ fDocument.getClass().getMethod("getInputEncoding", new Class[] {});
+ if (getEncoding != null) {
+ encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ if (encoding == null) {
+ try {
+ Method getEncoding =
+ fDocument.getClass().getMethod("getXmlEncoding", new Class[] {});
+ if (getEncoding != null) {
+ encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ if (encoding == null) {
+ encoding = "UTF-8";
+ }
+ }
+
+ try {
+ prepareForSerialization(ser, node);
+ ser._format.setEncoding(encoding);
+
+ // URI was specified. Handle relative URIs.
+ String expanded = XMLEntityManager.expandSystemId(URI, null, true);
+ URL url = new URL(expanded != null ? expanded : URI);
+ OutputStream out = null;
+ String protocol = url.getProtocol();
+ String host = url.getHost();
+ // Use FileOutputStream if this URI is for a local file.
+ if (protocol.equals("file")
+ && (host == null || host.length() == 0 || host.equals("localhost"))) {
+ out = new FileOutputStream(getPathWithoutEscapes(url.getFile()));
+ }
+ // Try to write to some other kind of URI. Some protocols
+ // won't support this, though HTTP should work.
+ else {
+ URLConnection urlCon = url.openConnection();
+ urlCon.setDoInput(false);
+ urlCon.setDoOutput(true);
+ urlCon.setUseCaches(false); // Enable tunneling.
+ if (urlCon instanceof HttpURLConnection) {
+ // The DOM L3 LS CR says if we are writing to an HTTP URI
+ // it is to be done with an HTTP PUT.
+ HttpURLConnection httpCon = (HttpURLConnection) urlCon;
+ httpCon.setRequestMethod("PUT");
+ }
+ out = urlCon.getOutputStream();
+ }
+ ser.setOutputByteStream(out);
+
+ if (node.getNodeType() == Node.DOCUMENT_NODE)
+ ser.serialize((Document) node);
+ else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
+ ser.serialize((DocumentFragment) node);
+ else if (node.getNodeType() == Node.ELEMENT_NODE)
+ ser.serialize((Element) node);
+ else if (node.getNodeType() == Node.TEXT_NODE ||
+ node.getNodeType() == Node.COMMENT_NODE ||
+ node.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
+ node.getNodeType() == Node.CDATA_SECTION_NODE ||
+ node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
+ ser.serialize(node);
+ }
+ else
+ return false;
+ } catch (LSException lse) {
+ // Rethrow LSException.
+ throw lse;
+ } catch (RuntimeException e) {
+ if (e == DOMNormalizer.abort){
+ // stopped at user request
+ return false;
+ }
+ throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+ } catch (Exception e) {
+ if (ser.fDOMErrorHandler != null) {
+ DOMErrorImpl error = new DOMErrorImpl();
+ error.fException = e;
+ error.fMessage = e.getMessage();
+ error.fSeverity = DOMError.SEVERITY_ERROR;
+ ser.fDOMErrorHandler.handleError(error);
+ }
+ throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+ }
+ return true;
+ } //writeURI
+
+
+ //
+ // Private methods
+ //
+
+ private void prepareForSerialization(XMLSerializer ser, Node node) {
+ ser.reset();
+ ser.features = features;
+ ser.fDOMErrorHandler = fErrorHandler;
+ ser.fNamespaces = (features & NAMESPACES) != 0;
+ ser.fNamespacePrefixes = (features & NSDECL) != 0;
+ ser._format.setOmitComments((features & COMMENTS)==0);
+ ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0);
+ ser._format.setIndenting((features & FORMAT_PRETTY_PRINT) != 0);
+
+ if ((features & WELLFORMED) != 0) {
+ // REVISIT: this is inefficient implementation of well-formness. Instead, we should check
+ // well-formness as we serialize the tree
+ Node next, root;
+ root = node;
+ Method versionChanged;
+ boolean verifyNames = true;
+ Document document =(node.getNodeType() == Node.DOCUMENT_NODE)
+ ? (Document) node
+ : node.getOwnerDocument();
+ try {
+ versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class[] {});
+ if (versionChanged != null) {
+ verifyNames = ((Boolean)versionChanged.invoke(document, (Object[]) null)).booleanValue();
+ }
+ } catch (Exception e) {
+ //no way to test the version...
+ //ignore the exception
+ }
+ if (node.getFirstChild() != null) {
+ while (node != null) {
+ verify(node, verifyNames, false);
+ // Move down to first child
+ next = node.getFirstChild();
+ // No child nodes, so walk tree
+ while (next == null) {
+ // Move to sibling if possible.
+ next = node.getNextSibling();
+ if (next == null) {
+ node = node.getParentNode();
+ if (root == node){
+ next = null;
+ break;
+ }
+ next = node.getNextSibling();
+ }
+ }
+ node = next;
+ }
+ }
+ else {
+ verify(node, verifyNames, false);
+ }
+ }
+ }
+
+
+ private void verify (Node node, boolean verifyNames, boolean xml11Version){
+
+ int type = node.getNodeType();
+ fLocator.fRelatedNode = node;
+ boolean wellformed;
+ switch (type) {
+ case Node.DOCUMENT_NODE:{
+ break;
+ }
+ case Node.DOCUMENT_TYPE_NODE:{
+ break;
+ }
+ case Node.ELEMENT_NODE:{
+ if (verifyNames){
+ if((features & NAMESPACES) != 0){
+ wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), xml11Version) ;
+ }
+ else{
+ wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version);
+ }
+ if (!wellformed){
+ if (!wellformed){
+ if (fErrorHandler != null) {
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "wf-invalid-character-in-node-name",
+ new Object[]{"Element", node.getNodeName()});
+ DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
+ "wf-invalid-character-in-node-name");
+ }
+
+ }
+ }
+ }
+
+ NamedNodeMap attributes = (node.hasAttributes()) ? node.getAttributes() : null;
+ if (attributes != null) {
+ for (int i = 0; i < attributes.getLength(); ++i) {
+ Attr attr = (Attr) attributes.item(i);
+ fLocator.fRelatedNode = attr;
+ DOMNormalizer.isAttrValueWF( fErrorHandler, fError, fLocator,
+ attributes, attr, attr.getValue(), xml11Version);
+ if (verifyNames) {
+ wellformed = CoreDocumentImpl.isXMLName( attr.getNodeName(), xml11Version);
+ if (!wellformed) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "wf-invalid-character-in-node-name",
+ new Object[] { "Attr", node.getNodeName()});
+ DOMNormalizer.reportDOMError( fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
+ "wf-invalid-character-in-node-name");
+ }
+ }
+ }
+
+ }
+
+ break;
+ }
+
+ case Node.COMMENT_NODE: {
+ // only verify well-formness if comments included in the tree
+ if ((features & COMMENTS) != 0)
+ DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment)node).getData(), xml11Version);
+ break;
+ }
+ case Node.ENTITY_REFERENCE_NODE: {
+ // only if entity is preserved in the tree
+ if (verifyNames && (features & ENTITIES) != 0){
+ CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version);
+ }
+ break;
+
+ }
+ case Node.CDATA_SECTION_NODE: {
+ // verify content
+ DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
+ // the ]]> string will be checked during serialization
+ break;
+ }
+ case Node.TEXT_NODE:{
+ DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
+ break;
+ }
+ case Node.PROCESSING_INSTRUCTION_NODE:{
+ ProcessingInstruction pinode = (ProcessingInstruction)node ;
+ String target = pinode.getTarget();
+ if (verifyNames) {
+ if (xml11Version) {
+ wellformed = XML11Char.isXML11ValidName(target);
+ } else {
+ wellformed = XMLChar.isValidName(target);
+ }
+
+ if (!wellformed) {
+ String msg =
+ DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "wf-invalid-character-in-node-name",
+ new Object[] { "Element", node.getNodeName()});
+ DOMNormalizer.reportDOMError(
+ fErrorHandler,
+ fError,
+ fLocator,
+ msg,
+ DOMError.SEVERITY_FATAL_ERROR,
+ "wf-invalid-character-in-node-name");
+ }
+ }
+ DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version);
+ break;
+ }
+ }
+
+ }
+
+ private 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();
+ // Decode the 2 digit hexadecimal number following % in '%nn'
+ result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue());
+ result.append(token.substring(2));
+ }
+ return result.toString();
+ }
+ return origPath;
+ }
+
+}//DOMSerializerImpl