19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id:  $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.serializer.dom3;
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.File;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.Writer;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Enumeration;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Hashtable;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Properties;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.dom3.NamespaceSupport;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.OutputPropertiesFactory;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.SerializationHandler;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.MsgKey;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.Utils;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.XML11Char;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.XMLChar;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Attr;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.CDATASection;
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Comment;
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.DOMError;
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.DOMErrorHandler;
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Document;
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.DocumentType;
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Element;
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Entity;
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.EntityReference;
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.NamedNodeMap;
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node;
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.NodeList;
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.ProcessingInstruction;
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Text;
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.ls.LSSerializerFilter;
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.traversal.NodeFilter;
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Locator;
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException;
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ext.LexicalHandler;
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.helpers.LocatorImpl;
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Built on org.apache.xml.serializer.TreeWalker and adds functionality to
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * traverse and serialize a DOM Node (Level 2 or Level 3) as specified in
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the DOM Level 3 LS Recommedation by evaluating and applying DOMConfiguration
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * parameters and filters if any during serialization.
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonfinal class DOM3TreeWalker {
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * The SerializationHandler, it extends ContentHandler and when
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * this class is instantiated via the constructor provided, a
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * SerializationHandler object is passed to it.
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private SerializationHandler fSerializer = null;
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** We do not need DOM2Helper since DOM Level 3 LS applies to DOM Level 2 or newer */
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Locator object for this TreeWalker          */
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private LocatorImpl fLocator = new LocatorImpl();
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** ErrorHandler */
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private DOMErrorHandler fErrorHandler = null;
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** LSSerializerFilter */
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private LSSerializerFilter fFilter = null;
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** If the serializer is an instance of a LexicalHandler */
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private LexicalHandler fLexicalHandler = null;
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int fWhatToShowFilter;
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** New Line character to use in serialization */
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private String fNewLine = null;
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** DOMConfiguration Properties */
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private Properties fDOMConfigProperties = null;
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Keeps track if we are in an entity reference when entities=true */
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean fInEntityRef = false;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Stores the version of the XML document to be serialize */
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private String fXMLVersion = null;
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** XML Version, default 1.0 */
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean fIsXMLVersion11 = false;
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Is the Node a Level 3 DOM node */
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean fIsLevel3DOM = false;
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** DOM Configuration Parameters */
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int fFeatures = 0;
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Flag indicating whether following text to be processed is raw text          */
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean fNextIsRaw = false;
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final String XMLNS_PREFIX = "xmlns";
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final String XML_PREFIX = "xml";
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** stores namespaces in scope */
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected NamespaceSupport fNSBinder;
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** stores all namespace bindings on the current element */
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected NamespaceSupport fLocalNSBinder;
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** stores the current element depth */
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int fElementDepth = 0;
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // DOMConfiguration paramter settings
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter canonical-form, true [optional] - NOT SUPPORTED
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int CANONICAL = 0x1 << 0;
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter cdata-sections, true [required] (default)
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int CDATA = 0x1 << 1;
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter check-character-normalization, true [optional] - NOT SUPPORTED
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int CHARNORMALIZE = 0x1 << 2;
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter comments, true [required] (default)
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int COMMENTS = 0x1 << 3;
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int DTNORMALIZE = 0x1 << 4;
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter entities, true [required] (default)
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int ENTITIES = 0x1 << 6;
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int INFOSET = 0x1 << 7;
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter namespaces, true [required] (default)
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int NAMESPACES = 0x1 << 8;
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter namespace-declarations, true [required] (default)
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int NAMESPACEDECLS = 0x1 << 9;
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter normalize-characters, true [optional] - NOT SUPPORTED
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int NORMALIZECHARS = 0x1 << 10;
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter split-cdata-sections, true [required] (default)
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int SPLITCDATA = 0x1 << 11;
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter validate, true [optional] - NOT SUPPORTED
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int VALIDATE = 0x1 << 12;
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int SCHEMAVALIDATE = 0x1 << 13;
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter split-cdata-sections, true [required] (default)
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int WELLFORMED = 0x1 << 14;
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter discard-default-content, true [required] (default)
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Not sure how this will be used in level 2 Documents
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int DISCARDDEFAULT = 0x1 << 15;
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter format-pretty-print, true [optional]
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int PRETTY_PRINT = 0x1 << 16;
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter ignore-unknown-character-denormalizations, true [required] (default)
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // We currently do not support XML 1.1 character normalization
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Parameter discard-default-content, true [required] (default)
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final static int XMLDECL = 0x1 << 18;
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Constructor.
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   contentHandler serialHandler The implemention of the SerializationHandler interface
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DOM3TreeWalker(
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SerializationHandler serialHandler,
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DOMErrorHandler errHandler,
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        LSSerializerFilter filter,
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String newLine) {
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fSerializer = serialHandler;
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //fErrorHandler = errHandler == null ? new DOMErrorHandlerImpl() : errHandler; // Should we be using the default?
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fErrorHandler = errHandler;
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fFilter = filter;
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fLexicalHandler = null;
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fNewLine = newLine;
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fNSBinder = new NamespaceSupport();
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fLocalNSBinder = new NamespaceSupport();
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fDOMConfigProperties = fSerializer.getOutputFormat();
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        fSerializer.setDocumentLocator(fLocator);
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        initProperties(fDOMConfigProperties);
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try {
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Bug see Bugzilla  26741
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setSystemId(
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                System.getProperty("user.dir") + File.separator + "dummy.xsl");
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } catch (SecurityException se) { // user.dir not accessible from applet
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Perform a pre-order traversal non-recursive style.
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Note that TreeWalker assumes that the subtree is intended to represent
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * a complete (though not necessarily well-formed) document and, during a
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * traversal, startDocument and endDocument will always be issued to the
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * SAX listener.
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param pos Node in the tree where to start traversal
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws TransformerException
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void traverse(Node pos) throws org.xml.sax.SAXException {
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        this.fSerializer.startDocument();
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Determine if the Node is a DOM Level 3 Core Node.
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Document ownerDoc = pos.getOwnerDocument();
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (ownerDoc != null
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fIsLevel3DOM = true;
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (((Document) pos)
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                .getImplementation()
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                .hasFeature("Core", "3.0")) {
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fIsLevel3DOM = true;
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fSerializer instanceof LexicalHandler) {
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLexicalHandler = ((LexicalHandler) this.fSerializer);
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fFilter != null)
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fWhatToShowFilter = fFilter.getWhatToShow();
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Node top = pos;
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (null != pos) {
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startNode(pos);
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node nextNode = null;
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nextNode = pos.getFirstChild();
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (null == nextNode) {
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                endNode(pos);
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (top.equals(pos))
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    break;
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                nextNode = pos.getNextSibling();
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (null == nextNode) {
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    pos = pos.getParentNode();
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if ((null == pos) || (top.equals(pos))) {
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (null != pos)
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            endNode(pos);
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        nextNode = null;
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        break;
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pos = nextNode;
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        this.fSerializer.endDocument();
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Perform a pre-order traversal non-recursive style.
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Note that TreeWalker assumes that the subtree is intended to represent
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * a complete (though not necessarily well-formed) document and, during a
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * traversal, startDocument and endDocument will always be issued to the
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * SAX listener.
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param pos Node in the tree where to start traversal
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param top Node in the tree where to end traversal
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws TransformerException
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void traverse(Node pos, Node top) throws org.xml.sax.SAXException {
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        this.fSerializer.startDocument();
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Determine if the Node is a DOM Level 3 Core Node.
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (pos.getNodeType() != Node.DOCUMENT_NODE) {
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Document ownerDoc = pos.getOwnerDocument();
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (ownerDoc != null
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fIsLevel3DOM = true;
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (((Document) pos)
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                .getImplementation()
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                .hasFeature("Core", "3.0")) {
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fIsLevel3DOM = true;
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fSerializer instanceof LexicalHandler) {
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLexicalHandler = ((LexicalHandler) this.fSerializer);
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fFilter != null)
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fWhatToShowFilter = fFilter.getWhatToShow();
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (null != pos) {
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startNode(pos);
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node nextNode = null;
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            nextNode = pos.getFirstChild();
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (null == nextNode) {
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                endNode(pos);
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((null != top) && top.equals(pos))
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    break;
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                nextNode = pos.getNextSibling();
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (null == nextNode) {
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    pos = pos.getParentNode();
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if ((null == pos) || ((null != top) && top.equals(pos))) {
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        nextNode = null;
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        break;
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pos = nextNode;
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        this.fSerializer.endDocument();
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Optimized dispatch of characters.
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final void dispatachChars(Node node)
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException {
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fSerializer != null) {
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.fSerializer.characters(node);
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String data = ((Text) node).getData();
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.fSerializer.characters(data.toCharArray(), 0, data.length());
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Start processing given node
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Node to process
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void startNode(Node node) throws org.xml.sax.SAXException {
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (node instanceof Locator) {
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Locator loc = (Locator) node;
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setColumnNumber(loc.getColumnNumber());
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setLineNumber(loc.getLineNumber());
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setPublicId(loc.getPublicId());
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setSystemId(loc.getSystemId());
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setColumnNumber(0);
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fLocator.setLineNumber(0);
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        switch (node.getNodeType()) {
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.DOCUMENT_TYPE_NODE :
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeDocType((DocumentType) node, true);
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.COMMENT_NODE :
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeComment((Comment) node);
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.DOCUMENT_FRAGMENT_NODE :
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Children are traversed
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.DOCUMENT_NODE :
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.ELEMENT_NODE :
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeElement((Element) node, true);
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.PROCESSING_INSTRUCTION_NODE :
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializePI((ProcessingInstruction) node);
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.CDATA_SECTION_NODE :
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeCDATASection((CDATASection) node);
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.TEXT_NODE :
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeText((Text) node);
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.ENTITY_REFERENCE_NODE :
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeEntityReference((EntityReference) node, true);
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            default :
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * End processing of given node
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node Node we just finished processing
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void endNode(Node node) throws org.xml.sax.SAXException {
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        switch (node.getNodeType()) {
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.DOCUMENT_NODE :
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.DOCUMENT_TYPE_NODE :
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeDocType((DocumentType) node, false);
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.ELEMENT_NODE :
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeElement((Element) node, false);
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.CDATA_SECTION_NODE :
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            case Node.ENTITY_REFERENCE_NODE :
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                serializeEntityReference((EntityReference) node, false);
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            default :
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Node serialization methods
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Applies a filter on the node to serialize
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The Node to serialize
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return True if the node is to be serialized else false if the node
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         is to be rejected or skipped.
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean applyFilter(Node node, int nodeType) {
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fFilter != null && (fWhatToShowFilter & nodeType) != 0) {
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            short code = fFilter.acceptNode(node);
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switch (code) {
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case NodeFilter.FILTER_REJECT :
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case NodeFilter.FILTER_SKIP :
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return false; // skip the node
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                default : // fall through..
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes a Document Type Node.
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The Docuemnt Type Node to serialize
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param bStart Invoked at the start or end of node.  Default true.
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeDocType(DocumentType node, boolean bStart)
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException {
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The DocType and internalSubset can not be modified in DOM and is
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // considered to be well-formed as the outcome of successful parsing.
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String docTypeName = node.getNodeName();
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String publicId = node.getPublicId();
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String systemId = node.getSystemId();
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String internalSubset = node.getInternalSubset();
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //DocumentType nodes are never passed to the filter
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (internalSubset != null && !"".equals(internalSubset)) {
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (bStart) {
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                try {
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // The Serializer does not provide a way to write out the
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // DOCTYPE internal subset via an event call, so we write it
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // out here.
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    Writer writer = fSerializer.getWriter();
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    StringBuffer dtd = new StringBuffer();
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append("<!DOCTYPE ");
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append(docTypeName);
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (null != publicId) {
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        dtd.append(" PUBLIC \"");
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        dtd.append(publicId);
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        dtd.append('\"');
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (null != systemId) {
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (null == publicId) {
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            dtd.append(" SYSTEM \"");
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        } else {
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            dtd.append(" \"");
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        dtd.append(systemId);
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        dtd.append('\"');
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append(" [ ");
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append(fNewLine);
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append(internalSubset);
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append("]>");
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    dtd.append(new String(fNewLine));
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(dtd.toString());
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.flush();
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } catch (IOException e) {
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    throw new SAXException(Utils.messages.createMessage(
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_WRITING_INTERNAL_SUBSET, null), e);
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } // else if !bStart do nothing
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (bStart) {
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (fLexicalHandler != null) {
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fLexicalHandler.startDTD(docTypeName, publicId, systemId);
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (fLexicalHandler != null) {
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fLexicalHandler.endDTD();
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes a Comment Node.
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The Comment Node to serialize
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeComment(Comment node) throws SAXException {
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // comments=true
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & COMMENTS) != 0) {
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String data = node.getData();
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // well-formed=true
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & WELLFORMED) != 0) {
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isCommentWellFormed(data);
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fLexicalHandler != null) {
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // apply the LSSerializer filter after the operations requested by the
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // DOMConfiguration parameters have been applied
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (!applyFilter(node, NodeFilter.SHOW_COMMENT)) {
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return;
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLexicalHandler.comment(data.toCharArray(), 0, data.length());
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes an Element Node.
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The Element Node to serialize
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param bStart Invoked at the start or end of node.
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeElement(Element node, boolean bStart)
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException {
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (bStart) {
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fElementDepth++;
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // We use the Xalan specific startElement and starPrefixMapping calls
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // (and addAttribute and namespaceAfterStartElement) as opposed to
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // SAX specific, for performance reasons as they reduce the overhead
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // of creating an AttList object upfront.
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // well-formed=true
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & WELLFORMED) != 0) {
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isElementWellFormed(node);
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // REVISIT: We apply the LSSerializer filter for elements before
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // namesapce fixup
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // namespaces=true, record and fixup namspaced element
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & NAMESPACES) != 0) {
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	fNSBinder.pushContext();
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	fLocalNSBinder.reset();
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                recordLocalNSDecl(node);
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fixupElementNS(node);
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Namespace normalization
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fSerializer.startElement(
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            		node.getNamespaceURI(),
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getLocalName(),
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getNodeName());
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            serializeAttList(node);
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        	fElementDepth--;
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // apply the LSSerializer filter
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.fSerializer.endElement(
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	node.getNamespaceURI(),
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                node.getLocalName(),
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                node.getNodeName());
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // since endPrefixMapping was not used by SerializationHandler it was removed
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // for performance reasons.
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & NAMESPACES) != 0 ) {
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fNSBinder.popContext();
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes the Attr Nodes of an Element.
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The OwnerElement whose Attr Nodes are to be serialized.
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeAttList(Element node) throws SAXException {
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        NamedNodeMap atts = node.getAttributes();
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int nAttrs = atts.getLength();
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < nAttrs; i++) {
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node attr = atts.item(i);
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String localName = attr.getLocalName();
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrName = attr.getNodeName();
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrPrefix = attr.getPrefix() == null ? "" : attr.getPrefix();
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrValue = attr.getNodeValue();
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Determine the Attr's type.
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String type = null;
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fIsLevel3DOM) {
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                type = ((Attr) attr).getSchemaTypeInfo().getTypeName();
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            type = type == null ? "CDATA" : type;
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrNS = attr.getNamespaceURI();
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (attrNS !=null && attrNS.length() == 0) {
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	attrNS=null;
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // we must remove prefix for this attribute
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	attrName=attr.getLocalName();
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean isSpecified = ((Attr) attr).getSpecified();
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean addAttr = true;
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean applyFilter = false;
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean xmlnsAttr =
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                attrName.equals("xmlns") || attrName.startsWith("xmlns:");
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // well-formed=true
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & WELLFORMED) != 0) {
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isAttributeWellFormed(attr);
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //-----------------------------------------------------------------
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // start Attribute namespace fixup
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //-----------------------------------------------------------------
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // namespaces=true, normalize all non-namespace attributes
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Step 3. Attribute
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & NAMESPACES) != 0 && !xmlnsAttr) {
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        		// If the Attr has a namespace URI
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        		if (attrNS != null) {
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			attrPrefix = attrPrefix == null ? "" : attrPrefix;
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			String declAttrPrefix = fNSBinder.getPrefix(attrNS);
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			String declAttrNS = fNSBinder.getURI(attrPrefix);
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// attribute has no prefix (default namespace decl does not apply to
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// attributes)
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// OR
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// attribute prefix is not declared
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// OR
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// conflict: attribute has a prefix that conflicts with a binding
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			if ("".equals(attrPrefix) || "".equals(declAttrPrefix)
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					|| !attrPrefix.equals(declAttrPrefix)) {
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				// namespaceURI matches an in scope declaration of one or
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				// more prefixes
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				if (declAttrPrefix != null && !"".equals(declAttrPrefix)) {
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					// pick the prefix that was found and change attribute's
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					// prefix and nodeName.
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					attrPrefix = declAttrPrefix;
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					if (declAttrPrefix.length() > 0 ) {
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						attrName = declAttrPrefix + ":" + localName;
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					} else {
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						attrName = localName;
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					}
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				} else {
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					// The current prefix is not null and it has no in scope
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					// declaration
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					if (attrPrefix != null && !"".equals(attrPrefix)
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							&& declAttrNS == null) {
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// declare this prefix
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						if ((fFeatures & NAMESPACEDECLS) != 0) {
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									attrNS);
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							fNSBinder.declarePrefix(attrPrefix, attrNS);
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						}
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					} else {
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// find a prefix following the pattern "NS" +index
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// (starting at 1)
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// make sure this prefix is not declared in the current
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// scope.
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						int counter = 1;
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						attrPrefix = "NS" + counter++;
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						while (fLocalNSBinder.getURI(attrPrefix) != null) {
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							attrPrefix = "NS" + counter++;
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						}
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// change attribute's prefix and Name
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						attrName = attrPrefix + ":" + localName;
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// create a local namespace declaration attribute
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						// Add the xmlns declaration attribute
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						if ((fFeatures & NAMESPACEDECLS) != 0) {
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							fSerializer.addAttribute(XMLNS_URI, attrPrefix,
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									attrNS);
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            						fNSBinder.declarePrefix(attrPrefix, attrNS);
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            						fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						}
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					}
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				}
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			}
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        		} else { // if the Attr has no namespace URI
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			// Attr has no localName
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			if (localName == null) {
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				// DOM Level 1 node!
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				String msg = Utils.messages.createMessage(
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        						new Object[] { attrName });
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				if (fErrorHandler != null) {
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        					fErrorHandler
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        							.handleError(new DOMErrorImpl(
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									DOMError.SEVERITY_ERROR, msg,
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									MsgKey.ER_NULL_LOCAL_ELEMENT_NAME, null,
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        									null, null));
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				}
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			} else { // uri=null and no colon
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				// attr has no namespace URI and no prefix
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        				// no action is required, since attrs don't use default
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        			}
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        		}
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // discard-default-content=true
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Default attr's are not passed to the filter and this contraint
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // is applied only when discard-default-content=true
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // What about default xmlns attributes???? check for xmlnsAttr
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((((fFeatures & DISCARDDEFAULT) != 0) && isSpecified)
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                || ((fFeatures & DISCARDDEFAULT) == 0)) {
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                applyFilter = true;
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	addAttr = false;
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (applyFilter) {
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // apply the filter for Attributes that are not default attributes
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // or namespace decl attributes
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (fFilter != null
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && (fFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        != 0) {
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (!xmlnsAttr) {
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        short code = fFilter.acceptNode(attr);
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        switch (code) {
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            case NodeFilter.FILTER_REJECT :
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            case NodeFilter.FILTER_SKIP :
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                addAttr = false;
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                break;
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            default : //fall through..
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if the node is a namespace node
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (addAttr && xmlnsAttr) {
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If namespace-declarations=true, add the node , else don't add it
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((fFeatures & NAMESPACEDECLS) != 0) {
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               		// The namespace may have been fixed up, in that case don't add it.
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                	if (localName != null && !"".equals(localName)) {
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                		fSerializer.addAttribute(attrNS, localName, attrName, type, attrValue);
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                	}
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else if (
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                addAttr && !xmlnsAttr) { // if the node is not a namespace node
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If namespace-declarations=true, add the node with the Attr nodes namespaceURI
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // else add the node setting it's namespace to null or else the serializer will later
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // attempt to add a xmlns attr for the prefixed attribute
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (((fFeatures & NAMESPACEDECLS) != 0) && (attrNS != null)) {
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fSerializer.addAttribute(
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        attrNS,
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        localName,
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        attrName,
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        type,
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        attrValue);
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } else {
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fSerializer.addAttribute(
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        "",
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        localName,
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        attrName,
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        type,
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        attrValue);
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (xmlnsAttr && ((fFeatures & NAMESPACEDECLS) != 0)) {
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                int index;
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Use "" instead of null, as Xerces likes "" for the
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // name of the default namespace.  Fix attributed
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // to "Steven Murray" <smurray@ebt.com>.
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String prefix =
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    (index = attrName.indexOf(":")) < 0
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        ? ""
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        : attrName.substring(index + 1);
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (!"".equals(prefix)) {
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fSerializer.namespaceAfterStartElement(prefix, attrValue);
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes an ProcessingInstruction Node.
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The ProcessingInstruction Node to serialize
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializePI(ProcessingInstruction node)
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException {
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ProcessingInstruction pi = node;
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String name = pi.getNodeName();
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // well-formed=true
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & WELLFORMED) != 0) {
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isPIWellFormed(node);
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // apply the LSSerializer filter
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!applyFilter(node, NodeFilter.SHOW_PROCESSING_INSTRUCTION)) {
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // String data = pi.getData();
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (name.equals("xslt-next-is-raw")) {
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fNextIsRaw = true;
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.fSerializer.processingInstruction(name, pi.getData());
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes an CDATASection Node.
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The CDATASection Node to serialize
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeCDATASection(CDATASection node)
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException {
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // well-formed=true
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & WELLFORMED) != 0) {
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isCDATASectionWellFormed(node);
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // cdata-sections = true
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & CDATA) != 0) {
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // split-cdata-sections = true
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Assumption: This parameter has an effect only when
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// cdata-sections=true
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // ToStream, by default splits cdata-sections. Hence the check
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			// below.
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String nodeValue = node.getNodeValue();
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int endIndex = nodeValue.indexOf("]]>");
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & SPLITCDATA) != 0) {
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (endIndex >= 0) {
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // The first node split will contain the ]] markers
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String relatedData = nodeValue.substring(0, endIndex + 2);
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null);
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_WARNING,
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_CDATA_SECTIONS_SPLIT,
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                relatedData,
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (endIndex >= 0) {
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // The first node split will contain the ]] markers
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String relatedData = nodeValue.substring(0, endIndex + 2);
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_CDATA_SECTIONS_SPLIT,
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null);
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_ERROR,
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_CDATA_SECTIONS_SPLIT));
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Report an error and return.  What error???
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return;
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // apply the LSSerializer filter
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!applyFilter(node, NodeFilter.SHOW_CDATA_SECTION)) {
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // splits the cdata-section
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fLexicalHandler != null) {
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLexicalHandler.startCDATA();
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            dispatachChars(node);
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fLexicalHandler != null) {
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLexicalHandler.endCDATA();
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            dispatachChars(node);
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes an Text Node.
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The Text Node to serialize
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeText(Text node) throws SAXException {
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fNextIsRaw) {
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fNextIsRaw = false;
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fSerializer.processingInstruction(
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING,
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                "");
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            dispatachChars(node);
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fSerializer.processingInstruction(
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING,
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                "");
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // keep track of dispatch or not to avoid duplicaiton of filter code
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean bDispatch = false;
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // well-formed=true
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & WELLFORMED) != 0) {
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isTextWellFormed(node);
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if the node is whitespace
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Determine the Attr's type.
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            boolean isElementContentWhitespace = false;
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fIsLevel3DOM) {
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isElementContentWhitespace =
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       node.isElementContentWhitespace();
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (isElementContentWhitespace) {
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // element-content-whitespace=true
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) {
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    bDispatch = true;
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                bDispatch = true;
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // apply the LSSerializer filter
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!applyFilter(node, NodeFilter.SHOW_TEXT)) {
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (bDispatch) {
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                dispatachChars(node);
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Serializes an EntityReference Node.
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param node The EntityReference Node to serialize
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param bStart Inicates if called from start or endNode
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void serializeEntityReference(
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        EntityReference node,
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean bStart)
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException {
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (bStart) {
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            EntityReference eref = node;
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // entities=true
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((fFeatures & ENTITIES) != 0) {
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // perform well-formedness and other checking only if
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // entities = true
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // well-formed=true
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((fFeatures & WELLFORMED) != 0) {
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    isEntityReferneceWellFormed(node);
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // check "unbound-prefix-in-entity-reference" [fatal]
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Raised if the configuration parameter "namespaces" is set to true
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((fFeatures & NAMESPACES) != 0) {
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    checkUnboundPrefixInEntRef(node);
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // The filter should not apply in this case, since the
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // EntityReference is not being expanded.
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // should we pass entity reference nodes to the filter???
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fLexicalHandler != null) {
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // startEntity outputs only Text but not Element, Attr, Comment
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // and PI child nodes.  It does so by setting the m_inEntityRef
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // in ToStream and using this to decide if a node is to be
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // serialized or not.
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLexicalHandler.startEntity(eref.getNodeName());
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            EntityReference eref = node;
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // entities=true or false,
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fLexicalHandler != null) {
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLexicalHandler.endEntity(eref.getNodeName());
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Methods to check well-formedness
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Taken from org.apache.xerces.dom.CoreDocumentImpl
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Check the string against XML's definition of acceptable names for
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * elements and attributes and so on using the XMLCharacterProperties
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * utility class
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isXMLName(String s, boolean xml11Version) {
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (s == null) {
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!xml11Version)
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return XMLChar.isValidName(s);
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return XML11Char.isXML11ValidName(s);
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Taken from org.apache.xerces.dom.CoreDocumentImpl
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if the given qualified name is legal with respect
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to the version of XML to which this document must conform.
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param prefix prefix of qualified name
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param local local part of qualified name
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isValidQName(
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String prefix,
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String local,
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean xml11Version) {
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // check that both prefix and local part match NCName
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (local == null)
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean validNCName = false;
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!xml11Version) {
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            validNCName =
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                (prefix == null || XMLChar.isValidNCName(prefix))
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && XMLChar.isValidNCName(local);
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            validNCName =
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                (prefix == null || XML11Char.isXML11ValidNCName(prefix))
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && XML11Char.isXML11ValidNCName(local);
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return validNCName;
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if a XML character is well-formed
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param characters A String of characters to be checked for Well-Formedness
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param refInvalidChar A reference to the character to be returned that was determined invalid.
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean isWFXMLChar(String chardata, Character refInvalidChar) {
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (chardata == null || (chardata.length() == 0)) {
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return true;
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        char[] dataarray = chardata.toCharArray();
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int datalength = dataarray.length;
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // version of the document is XML 1.1
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fIsXMLVersion11) {
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //we need to check all characters as per production rules of XML11
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XML11Char.isXML11Invalid(dataarray[i++])) {
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    char ch = dataarray[i - 1];
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char ch2 = dataarray[i++];
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(ch2)
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(ch, ch2))) {
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Reference to invalid character which is returned
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    refInvalidChar = new Character(ch);
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return false;
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // version of the document is XML 1.0
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // we need to check all characters as per production rules of XML 1.0
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XMLChar.isInvalid(dataarray[i++])) {
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    char ch = dataarray[i - 1];
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char ch2 = dataarray[i++];
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(ch2)
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(ch, ch2))) {
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Reference to invalid character which is returned
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    refInvalidChar = new Character(ch);
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return false;
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // end-else fDocument.isXMLVersion()
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    } // isXMLCharWF
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if a XML character is well-formed.  If there is a problem with
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the character a non-null Character is returned else null is returned.
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param characters A String of characters to be checked for Well-Formedness
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return Character A reference to the character to be returned that was determined invalid.
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected Character isWFXMLChar(String chardata) {
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	Character refInvalidChar;
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (chardata == null || (chardata.length() == 0)) {
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return null;
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        char[] dataarray = chardata.toCharArray();
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int datalength = dataarray.length;
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // version of the document is XML 1.1
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fIsXMLVersion11) {
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //we need to check all characters as per production rules of XML11
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XML11Char.isXML11Invalid(dataarray[i++])) {
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    char ch = dataarray[i - 1];
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char ch2 = dataarray[i++];
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(ch2)
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(ch, ch2))) {
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Reference to invalid character which is returned
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    refInvalidChar = new Character(ch);
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return refInvalidChar;
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // version of the document is XML 1.0
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // we need to check all characters as per production rules of XML 1.0
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XMLChar.isInvalid(dataarray[i++])) {
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    char ch = dataarray[i - 1];
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(ch) && i < datalength) {
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char ch2 = dataarray[i++];
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(ch2)
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(ch, ch2))) {
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Reference to invalid character which is returned
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    refInvalidChar = new Character(ch);
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    return refInvalidChar;
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // end-else fDocument.isXMLVersion()
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return null;
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    } // isXMLCharWF
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if a comment node is well-formed
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return a boolean indiacating if the comment is well-formed or not.
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isCommentWellFormed(String data) {
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (data == null || (data.length() == 0)) {
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        char[] dataarray = data.toCharArray();
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int datalength = dataarray.length;
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // version of the document is XML 1.1
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fIsXMLVersion11) {
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // we need to check all chracters as per production rules of XML11
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                char c = dataarray[i++];
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XML11Char.isXML11Invalid(c)) {
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char c2 = dataarray[i++];
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(c2)
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(c, c2))) {
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new Object[] { new Character(c)});
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_FATAL_ERROR,
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_WF_INVALID_CHARACTER,
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_WF_DASH_IN_COMMENT,
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null);
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_FATAL_ERROR,
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_WF_INVALID_CHARACTER,
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // version of the document is XML 1.0
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else {
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // we need to check all chracters as per production rules of XML 1.0
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int i = 0;
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (i < datalength) {
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                char c = dataarray[i++];
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XMLChar.isInvalid(c)) {
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // check if this is a supplemental character
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (XMLChar.isHighSurrogate(c) && i < datalength) {
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        char c2 = dataarray[i++];
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (XMLChar.isLowSurrogate(c2)
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            && XMLChar.isSupplemental(
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                XMLChar.supplemental(c, c2))) {
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            continue;
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new Object[] { new Character(c)});
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_FATAL_ERROR,
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_WF_INVALID_CHARACTER,
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } else if (c == '-' && i < datalength && dataarray[i] == '-') {
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_WF_DASH_IN_COMMENT,
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null);
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_FATAL_ERROR,
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_WF_INVALID_CHARACTER,
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return;
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if an element node is well-formed, by checking its Name for well-formedness.
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return a boolean indiacating if the comment is well-formed or not.
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isElementWellFormed(Node node) {
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean isNameWF = false;
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & NAMESPACES) != 0) {
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isNameWF =
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isValidQName(
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getPrefix(),
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getLocalName(),
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fIsXMLVersion11);
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isNameWF) {
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { "Element", node.getNodeName()});
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if an attr node is well-formed, by checking it's Name and value
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * for well-formedness.
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return a boolean indiacating if the comment is well-formed or not.
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isAttributeWellFormed(Node node) {
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean isNameWF = false;
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((fFeatures & NAMESPACES) != 0) {
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isNameWF =
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                isValidQName(
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getPrefix(),
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getLocalName(),
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fIsXMLVersion11);
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isNameWF) {
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { "Attr", node.getNodeName()});
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Check the Attr's node value
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // WFC: No < in Attribute Values
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String value = node.getNodeValue();
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (value.indexOf('<') >= 0) {
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_LT_IN_ATTVAL,
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] {
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        ((Attr) node).getOwnerElement().getNodeName(),
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        node.getNodeName()});
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_LT_IN_ATTVAL,
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we need to loop through the children of attr nodes and check their values for
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // well-formedness
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        NodeList children = node.getChildNodes();
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < children.getLength(); i++) {
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node child = children.item(i);
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // An attribute node with no text or entity ref child for example
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns");
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // followes by
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // element.setAttributeNodeNS(attribute);
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // can potentially lead to this situation.  If the attribute
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // was a prefix Namespace attribute declaration then then DOM Core
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // should have some exception defined for this.
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (child == null) {
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // we should probably report an error
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                continue;
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switch (child.getNodeType()) {
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case Node.TEXT_NODE :
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    isTextWellFormed((Text) child);
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    break;
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case Node.ENTITY_REFERENCE_NODE :
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    isEntityReferneceWellFormed((EntityReference) child);
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    break;
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                default :
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // TODO:
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // WFC: Check if the attribute prefix is bound to
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // http://www.w3.org/2000/xmlns/
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // WFC: Unique Att Spec
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Perhaps pass a seen boolean value to this method.  serializeAttList will determine
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // if the attr was seen before.
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if a PI node is well-formed, by checking it's Name and data
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * for well-formedness.
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isPIWellFormed(ProcessingInstruction node) {
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Is the PI Target a valid XML name
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { "ProcessingInstruction", node.getTarget()});
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Does the PI Data carry valid XML characters
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // REVISIT: Should we check if the PI DATA contains a ?> ???
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Character invalidChar = isWFXMLChar(node.getData());
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (invalidChar != null) {
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER,
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if an CDATASection node is well-formed, by checking it's data
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * for well-formedness.  Note that the presence of a CDATA termination mark
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * in the contents of a CDATASection is handled by the parameter
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * spli-cdata-sections
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isCDATASectionWellFormed(CDATASection node) {
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Does the data valid XML character data
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Character invalidChar = isWFXMLChar(node.getData());
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //if (!isWFXMLChar(node.getData(), invalidChar)) {
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (invalidChar != null) {
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER,
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if an Text node is well-formed, by checking if it contains invalid
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * XML characters.
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isTextWellFormed(Text node) {
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Does the data valid XML character data
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	Character invalidChar = isWFXMLChar(node.getData());
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	if (invalidChar != null) {
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER,
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Checks if an EntityRefernece node is well-formed, by checking it's node name.  Then depending
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * on whether it is referenced in Element content or in an Attr Node, checks if the EntityReference
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * references an unparsed entity or a external entity and if so throws raises the
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * appropriate well-formedness error.
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param data The contents of the comment node
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @parent The parent of the EntityReference Node
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void isEntityReferneceWellFormed(EntityReference node) {
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Is the EntityReference name a valid XML name
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String msg =
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Utils.messages.createMessage(
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[] { "EntityReference", node.getNodeName()});
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (fErrorHandler != null) {
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fErrorHandler.handleError(
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new DOMErrorImpl(
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        DOMError.SEVERITY_FATAL_ERROR,
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        msg,
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null,
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null));
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // determine the parent node
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Node parent = node.getParentNode();
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Traverse the declared entities and check if the nodeName and namespaceURI
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // of the EntityReference matches an Entity.  If so, check the if the notationName
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // is not null, if so, report an error.
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DocumentType docType = node.getOwnerDocument().getDoctype();
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (docType != null) {
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            NamedNodeMap entities = docType.getEntities();
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            for (int i = 0; i < entities.getLength(); i++) {
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Entity ent = (Entity) entities.item(i);
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String nodeName =
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getNodeName() == null ? "" : node.getNodeName();
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String nodeNamespaceURI =
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.getNamespaceURI() == null
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        ? ""
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        : node.getNamespaceURI();
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String entName =
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    ent.getNodeName() == null ? "" : ent.getNodeName();
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String entNamespaceURI =
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    ent.getNamespaceURI() == null ? "" : ent.getNamespaceURI();
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If referenced in Element content
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // WFC: Parsed Entity
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (parent.getNodeType() == Node.ELEMENT_NODE) {
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (entNamespaceURI.equals(nodeNamespaceURI)
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        && entName.equals(nodeName)) {
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (ent.getNotationName() != null) {
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            String msg =
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                Utils.messages.createMessage(
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    new Object[] { node.getNodeName()});
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (fErrorHandler != null) {
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                fErrorHandler.handleError(
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    new DOMErrorImpl(
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        DOMError.SEVERITY_FATAL_ERROR,
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        msg,
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null,
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null,
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null));
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            }
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } // end if WFC: Parsed Entity
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If referenced in an Attr value
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // WFC: No External Entity References
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (entNamespaceURI.equals(nodeNamespaceURI)
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        && entName.equals(nodeName)) {
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (ent.getPublicId() != null
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            || ent.getSystemId() != null
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            || ent.getNotationName() != null) {
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            String msg =
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                Utils.messages.createMessage(
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    new Object[] { node.getNodeName()});
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (fErrorHandler != null) {
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                fErrorHandler.handleError(
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    new DOMErrorImpl(
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        DOMError.SEVERITY_FATAL_ERROR,
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        msg,
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null,
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null,
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                        null));
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            }
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } //end if WFC: No External Entity References
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    } // isEntityReferneceWellFormed
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * If the configuration parameter "namespaces" is set to true, this methods
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * checks if an entity whose replacement text contains unbound namespace
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * prefixes is referenced in a location where there are no bindings for
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the namespace prefixes and if so raises a LSException with the error-type
17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * "unbound-prefix-in-entity-reference"
17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param Node, The EntityReference nodes whose children are to be checked
17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void checkUnboundPrefixInEntRef(Node node) {
17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Node child, next;
17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (child = node.getFirstChild(); child != null; child = next) {
17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            next = child.getNextSibling();
17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (child.getNodeType() == Node.ELEMENT_NODE) {
17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                //If a NamespaceURI is not declared for the current
17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                //node's prefix, raise a fatal error.
17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String prefix = child.getPrefix();
17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (prefix != null
17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                		&& fNSBinder.getURI(prefix) == null) {
17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new Object[] {
17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                node.getNodeName(),
17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                child.getNodeName(),
17679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                prefix });
17689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
17709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
17719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
17729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_FATAL_ERROR,
17739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
17749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
17759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
17769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
17779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
17789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
17799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
17809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                NamedNodeMap attrs = child.getAttributes();
17829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                for (int i = 0; i < attrs.getLength(); i++) {
17849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String attrPrefix = attrs.item(i).getPrefix();
17859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (attrPrefix != null
17869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    		&& fNSBinder.getURI(attrPrefix) == null) {
17879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        String msg =
17889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            Utils.messages.createMessage(
17899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
17909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                new Object[] {
17919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    node.getNodeName(),
17929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    child.getNodeName(),
17939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    attrs.item(i)});
17949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (fErrorHandler != null) {
17969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fErrorHandler.handleError(
17979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                new DOMErrorImpl(
17989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    DOMError.SEVERITY_FATAL_ERROR,
17999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    msg,
18009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
18019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    null,
18029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    null,
18039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    null));
18049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
18059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
18069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
18079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (child.hasChildNodes()) {
18109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                checkUnboundPrefixInEntRef(child);
18119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
18139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
18169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Namespace normalization
18179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // ***********************************************************************
18189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
18199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Records local namespace declarations, to be used for normalization later
18209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
18219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param Node, The element node, whose namespace declarations are to be recorded
18229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
18239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void recordLocalNSDecl(Node node) {
18249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        NamedNodeMap atts = ((Element) node).getAttributes();
18259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int length = atts.getLength();
18269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < length; i++) {
18289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node attr = atts.item(i);
18299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String localName = attr.getLocalName();
18319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrPrefix = attr.getPrefix();
18329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrValue = attr.getNodeValue();
18339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String attrNS = attr.getNamespaceURI();
18349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            localName =
18369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                localName == null
18379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    || XMLNS_PREFIX.equals(localName) ? "" : localName;
18389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            attrPrefix = attrPrefix == null ? "" : attrPrefix;
18399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            attrValue = attrValue == null ? "" : attrValue;
18409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            attrNS = attrNS == null ? "" : attrNS;
18419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // check if attribute is a namespace decl
18439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (XMLNS_URI.equals(attrNS)) {
18449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // No prefix may be bound to http://www.w3.org/2000/xmlns/.
18469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (XMLNS_URI.equals(attrValue)) {
18479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String msg =
18489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Utils.messages.createMessage(
18499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
18509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new Object[] { attrPrefix, XMLNS_URI });
18519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (fErrorHandler != null) {
18539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fErrorHandler.handleError(
18549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            new DOMErrorImpl(
18559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DOMError.SEVERITY_ERROR,
18569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                msg,
18579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
18589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
18599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null,
18609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                null));
18619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
18629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } else {
18639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // store the namespace-declaration
18649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                	if (XMLNS_PREFIX.equals(attrPrefix) ) {
18659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // record valid decl
18669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (attrValue.length() != 0) {
18679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fNSBinder.declarePrefix(localName, attrValue);
18689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        } else {
18699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            // Error; xmlns:prefix=""
18709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
18719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else { // xmlns
18729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // empty prefix is always bound ("" or some string)
18739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fNSBinder.declarePrefix("", attrValue);
18749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
18759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
18769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
18799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
18829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Fixes an element's namespace
18839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
18849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param Node, The element node, whose namespace is to be fixed
18859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
18869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void fixupElementNS(Node node) throws SAXException {
18879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String namespaceURI = ((Element) node).getNamespaceURI();
18889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String prefix = ((Element) node).getPrefix();
18899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String localName = ((Element) node).getLocalName();
18909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (namespaceURI != null) {
18929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //if ( Element's prefix/namespace pair (or default namespace,
18939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if no prefix) are within the scope of a binding )
18949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            prefix = prefix == null ? "" : prefix;
18959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String inScopeNamespaceURI = fNSBinder.getURI(prefix);
18969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((inScopeNamespaceURI != null
18989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && inScopeNamespaceURI.equals(namespaceURI))) {
18999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // do nothing, declaration in scope is inherited
19009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
19029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Create a local namespace declaration attr for this namespace,
19039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // with Element's current prefix (or a default namespace, if
19049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // no prefix). If there's a conflicting local declaration
19059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // already present, change its value to use this namespace.
19069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Add the xmlns declaration attribute
19089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	//fNSBinder.pushNamespace(prefix, namespaceURI, fElementDepth);
19099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((fFeatures & NAMESPACEDECLS) != 0) {
19109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if ("".equals(prefix) || "".equals(namespaceURI)) {
19119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceURI);
19129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else {
19139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    	((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX + ":" + prefix, namespaceURI);
19149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
19159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
19169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fLocalNSBinder.declarePrefix(prefix, namespaceURI);
19179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                fNSBinder.declarePrefix(prefix, namespaceURI);
19189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
19209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
19219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Element has no namespace
19229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // DOM Level 1
19239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (localName == null || "".equals(localName)) {
19249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                //  DOM Level 1 node!
19259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String msg =
19269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    Utils.messages.createMessage(
19279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
19289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        new Object[] { node.getNodeName()});
19299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (fErrorHandler != null) {
19319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fErrorHandler.handleError(
19329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        new DOMErrorImpl(
19339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            DOMError.SEVERITY_ERROR,
19349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            msg,
19359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
19369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null,
19379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null,
19389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            null));
19399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
19409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } else {
19419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	namespaceURI = fNSBinder.getURI("");
19429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	if (namespaceURI !=null && namespaceURI.length() > 0) {
19439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	    ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, "");
19449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            		fLocalNSBinder.declarePrefix("", "");
19459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    fNSBinder.declarePrefix("", "");
19469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            	}
19479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
19489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
19519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This table is a quick lookup of a property key (String) to the integer that
19529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * is the bit to flip in the fFeatures field, so the integers should have
19539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * values 1,2,4,8,16...
19549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
19559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
19569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final Hashtable s_propKeys = new Hashtable();
19579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static {
19589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Initialize the mappings of property keys to bit values (Integer objects)
19609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // or mappings to a String object "", which indicates we are interested
19619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // in the property, but it does not have a simple bit value to flip
19629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // cdata-sections
19649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i = CDATA;
19659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Integer val = new Integer(i);
19669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
19679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_CDATA_SECTIONS,
19689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
19699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // comments
19719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i1 = COMMENTS;
19729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i1);
19739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
19749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_COMMENTS,
19759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
19769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // element-content-whitespace
19789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i2 = ELEM_CONTENT_WHITESPACE;
19799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i2);
19809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
19819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS
19829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
19839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
19849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i3 = ENTITIES;
19859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // entities
19879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i3);
19889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
19899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_ENTITIES,
19909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
19919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // namespaces
19939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i4 = NAMESPACES;
19949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i4);
19959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
19969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_NAMESPACES,
19979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
19989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // namespace-declarations
20009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i5 = NAMESPACEDECLS;
20019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i5);
20029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS
20049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
20059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
20069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // split-cdata-sections
20089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i6 = SPLITCDATA;
20099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i6);
20109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_SPLIT_CDATA,
20129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
20139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // discard-default-content
20159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i7 = WELLFORMED;
20169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i7);
20179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_WELLFORMED,
20199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
20209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // discard-default-content
20229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i8 = DISCARDDEFAULT;
20239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = new Integer(i8);
20249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS
20269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
20279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val);
20289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // We are interested in these properties, but they don't have a simple
20309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // bit value to deal with.
20319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_DOM3_PROPERTIES_NS
20339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                + DOMConstants.DOM_FORMAT_PRETTY_PRINT,
20349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "");
20359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "");
20369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(
20379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION,
20389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "");
20399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(DOMConstants.S_XSL_OUTPUT_ENCODING, "");
20409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        s_propKeys.put(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.DOM_ENTITIES, "");
20419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Initializes fFeatures based on the DOMConfiguration Parameters set.
20459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
20469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param properties DOMConfiguraiton properties that were set and which are
20479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to be used while serializing the DOM.
20489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void initProperties(Properties properties) {
20509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {
20529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final String key = (String) keys.nextElement();
20549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // caonical-form
20569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Other features will be enabled or disabled when this is set to true or false.
20579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // error-handler; set via the constructor
20599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // infoset
20619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Other features will be enabled or disabled when this is set to true
20629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // A quick lookup for the given set of properties (cdata-sections ...)
20649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final Object iobj = s_propKeys.get(key);
20659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (iobj != null) {
20669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (iobj instanceof Integer) {
20679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Dealing with a property that has a simple bit value that
20689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // we need to set
20699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // cdata-sections
20719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // comments
20729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // element-content-whitespace
20739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // entities
20749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // namespaces
20759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // namespace-declarations
20769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // split-cdata-sections
20779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // well-formed
20789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // discard-default-content
20799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    final int BITFLAG = ((Integer) iobj).intValue();
20809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if ((properties.getProperty(key).endsWith("yes"))) {
20819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fFeatures = fFeatures | BITFLAG;
20829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else {
20839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        fFeatures = fFeatures & ~BITFLAG;
20849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
20859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                } else {
20869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // We are interested in the property, but it is not
20879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // a simple bit that we need to set.
20889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if ((DOMConstants.S_DOM3_PROPERTIES_NS
20909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        + DOMConstants.DOM_FORMAT_PRETTY_PRINT)
20919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        .equals(key)) {
20929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // format-pretty-print; set internally on the serializers via xsl:output properties in LSSerializer
20939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if ((properties.getProperty(key).endsWith("yes"))) {
20949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setIndent(true);
20959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setIndentAmount(3);
20969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        } else {
20979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setIndent(false);
20989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
20999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else if (
21009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        (DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL).equals(
21019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            key)) {
21029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // omit-xml-declaration; set internally on the serializers via xsl:output properties in LSSerializer
21039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if ((properties.getProperty(key).endsWith("yes"))) {
21049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setOmitXMLDeclaration(true);
21059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        } else {
21069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setOmitXMLDeclaration(false);
21079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else if (
21099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        (
21109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            DOMConstants.S_XERCES_PROPERTIES_NS
21119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                + DOMConstants.S_XML_VERSION).equals(
21129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            key)) {
21139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Retreive the value of the XML Version attribute via the xml-version
21149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        String version = properties.getProperty(key);
21159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if ("1.1".equals(version)) {
21169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fIsXMLVersion11 = true;
21179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setVersion(version);
21189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        } else {
21199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setVersion("1.0");
21209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else if (
21229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        (DOMConstants.S_XSL_OUTPUT_ENCODING).equals(key)) {
21239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Retreive the value of the XML Encoding attribute
21249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        String encoding = properties.getProperty(key);
21259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (encoding != null) {
21269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setEncoding(encoding);
21279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else if ((DOMConstants.S_XERCES_PROPERTIES_NS
21299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            + DOMConstants.DOM_ENTITIES).equals(key)) {
21309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Preserve entity references in the document
21319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if ((properties.getProperty(key).endsWith("yes"))) {
21329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setDTDEntityExpansion(false);
21339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        else {
21359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            fSerializer.setDTDEntityExpansion(true);
21369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    } else {
21389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // We shouldn't get here, ever, now what?
21399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
21409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
21419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
21429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
21439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Set the newLine character to use
21449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fNewLine != null) {
21459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR, fNewLine);
21469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
21479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} //TreeWalker
2150