svn commit: r1225426 [10/19] - in /xalan/java/trunk/src: ./ org/apache/xalan/ org/apache/xalan/res/ org/apache/xalan/xsltc/compiler/util/ org/apache/xalan/xsltc/dom/ org/apache/xalan/xsltc/runtime/ org/apache/xml/dtm/ org/apache/xml/res/ org/apache/xml...
[email protected] Thu, 29 Dec 2011 04:13:09 -0000
| Newsgroups | gmane.text.xml.xalan.cvs |
|---|---|
| Message-ID | <[email protected]> |
Modified: xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java?rev=1225426&r1=1225425&r2=1225426&view=diff
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java Thu Dec 29 04:13:08 2011
@@ -1,2149 +1,2149 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * $Id: $
- */
-
-package org.apache.xml.serializer.dom3;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-
-import org.apache.xml.serializer.dom3.NamespaceSupport;
-import org.apache.xml.serializer.OutputPropertiesFactory;
-import org.apache.xml.serializer.SerializationHandler;
-import org.apache.xml.serializer.utils.MsgKey;
-import org.apache.xml.serializer.utils.Utils;
-import org.apache.xml.serializer.utils.XML11Char;
-import org.apache.xml.serializer.utils.XMLChar;
-import org.w3c.dom.Attr;
-import org.w3c.dom.CDATASection;
-import org.w3c.dom.Comment;
-import org.w3c.dom.DOMError;
-import org.w3c.dom.DOMErrorHandler;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.Entity;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.ProcessingInstruction;
-import org.w3c.dom.Text;
-import org.w3c.dom.ls.LSSerializerFilter;
-import org.w3c.dom.traversal.NodeFilter;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.LocatorImpl;
-
-/**
- * Built on org.apache.xml.serializer.TreeWalker and adds functionality to
- * traverse and serialize a DOM Node (Level 2 or Level 3) as specified in
- * the DOM Level 3 LS Recommedation by evaluating and applying DOMConfiguration
- * parameters and filters if any during serialization.
- *
- * @xsl.usage internal
- */
-final class DOM3TreeWalker {
-
- /**
- * The SerializationHandler, it extends ContentHandler and when
- * this class is instantiated via the constructor provided, a
- * SerializationHandler object is passed to it.
- */
- private SerializationHandler fSerializer = null;
-
- /** We do not need DOM2Helper since DOM Level 3 LS applies to DOM Level 2 or newer */
-
- /** Locator object for this TreeWalker */
- private LocatorImpl fLocator = new LocatorImpl();
-
- /** ErrorHandler */
- private DOMErrorHandler fErrorHandler = null;
-
- /** LSSerializerFilter */
- private LSSerializerFilter fFilter = null;
-
- /** If the serializer is an instance of a LexicalHandler */
- private LexicalHandler fLexicalHandler = null;
-
- private int fWhatToShowFilter;
-
- /** New Line character to use in serialization */
- private String fNewLine = null;
-
- /** DOMConfiguration Properties */
- private Properties fDOMConfigProperties = null;
-
- /** Keeps track if we are in an entity reference when entities=true */
- private boolean fInEntityRef = false;
-
- /** Stores the version of the XML document to be serialize */
- private String fXMLVersion = null;
-
- /** XML Version, default 1.0 */
- private boolean fIsXMLVersion11 = false;
-
- /** Is the Node a Level 3 DOM node */
- private boolean fIsLevel3DOM = false;
-
- /** DOM Configuration Parameters */
- private int fFeatures = 0;
-
- /** Flag indicating whether following text to be processed is raw text */
- boolean fNextIsRaw = false;
-
- //
- private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
-
- //
- private static final String XMLNS_PREFIX = "xmlns";
-
- //
- private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
-
- //
- private static final String XML_PREFIX = "xml";
-
- /** stores namespaces in scope */
- protected NamespaceSupport fNSBinder;
-
- /** stores all namespace bindings on the current element */
- protected NamespaceSupport fLocalNSBinder;
-
- /** stores the current element depth */
- private int fElementDepth = 0;
-
- // ***********************************************************************
- // DOMConfiguration paramter settings
- // ***********************************************************************
- // Parameter canonical-form, true [optional] - NOT SUPPORTED
- private final static int CANONICAL = 0x1 << 0;
-
- // Parameter cdata-sections, true [required] (default)
- private final static int CDATA = 0x1 << 1;
-
- // Parameter check-character-normalization, true [optional] - NOT SUPPORTED
- private final static int CHARNORMALIZE = 0x1 << 2;
-
- // Parameter comments, true [required] (default)
- private final static int COMMENTS = 0x1 << 3;
-
- // Parameter datatype-normalization, true [optional] - NOT SUPPORTED
- private final static int DTNORMALIZE = 0x1 << 4;
-
- // Parameter element-content-whitespace, true [required] (default) - value - false [optional] NOT SUPPORTED
- private final static int ELEM_CONTENT_WHITESPACE = 0x1 << 5;
-
- // Parameter entities, true [required] (default)
- private final static int ENTITIES = 0x1 << 6;
-
- // Parameter infoset, true [required] (default), false has no effect --> True has no effect for the serializer
- private final static int INFOSET = 0x1 << 7;
-
- // Parameter namespaces, true [required] (default)
- private final static int NAMESPACES = 0x1 << 8;
-
- // Parameter namespace-declarations, true [required] (default)
- private final static int NAMESPACEDECLS = 0x1 << 9;
-
- // Parameter normalize-characters, true [optional] - NOT SUPPORTED
- private final static int NORMALIZECHARS = 0x1 << 10;
-
- // Parameter split-cdata-sections, true [required] (default)
- private final static int SPLITCDATA = 0x1 << 11;
-
- // Parameter validate, true [optional] - NOT SUPPORTED
- private final static int VALIDATE = 0x1 << 12;
-
- // Parameter validate-if-schema, true [optional] - NOT SUPPORTED
- private final static int SCHEMAVALIDATE = 0x1 << 13;
-
- // Parameter split-cdata-sections, true [required] (default)
- private final static int WELLFORMED = 0x1 << 14;
-
- // Parameter discard-default-content, true [required] (default)
- // Not sure how this will be used in level 2 Documents
- private final static int DISCARDDEFAULT = 0x1 << 15;
-
- // Parameter format-pretty-print, true [optional]
- private final static int PRETTY_PRINT = 0x1 << 16;
-
- // Parameter ignore-unknown-character-denormalizations, true [required] (default)
- // We currently do not support XML 1.1 character normalization
- private final static int IGNORE_CHAR_DENORMALIZE = 0x1 << 17;
-
- // Parameter discard-default-content, true [required] (default)
- private final static int XMLDECL = 0x1 << 18;
-
- /**
- * Constructor.
- * @param contentHandler serialHandler The implemention of the SerializationHandler interface
- */
- DOM3TreeWalker(
- SerializationHandler serialHandler,
- DOMErrorHandler errHandler,
- LSSerializerFilter filter,
- String newLine) {
- fSerializer = serialHandler;
- //fErrorHandler = errHandler == null ? new DOMErrorHandlerImpl() : errHandler; // Should we be using the default?
- fErrorHandler = errHandler;
- fFilter = filter;
- fLexicalHandler = null;
- fNewLine = newLine;
-
- fNSBinder = new NamespaceSupport();
- fLocalNSBinder = new NamespaceSupport();
-
- fDOMConfigProperties = fSerializer.getOutputFormat();
- fSerializer.setDocumentLocator(fLocator);
- initProperties(fDOMConfigProperties);
-
- try {
- // Bug see Bugzilla 26741
- fLocator.setSystemId(
- System.getProperty("user.dir") + File.separator + "dummy.xsl");
- } catch (SecurityException se) { // user.dir not accessible from applet
-
- }
- }
-
- /**
- * Perform a pre-order traversal non-recursive style.
- *
- * Note that TreeWalker assumes that the subtree is intended to represent
- * a complete (though not necessarily well-formed) document and, during a
- * traversal, startDocument and endDocument will always be issued to the
- * SAX listener.
- *
- * @param pos Node in the tree where to start traversal
- *
- * @throws TransformerException
- */
- public void traverse(Node pos) throws org.xml.sax.SAXException {
- this.fSerializer.startDocument();
-
- // Determine if the Node is a DOM Level 3 Core Node.
- if (pos.getNodeType() != Node.DOCUMENT_NODE) {
- Document ownerDoc = pos.getOwnerDocument();
- if (ownerDoc != null
- && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
- fIsLevel3DOM = true;
- }
- } else {
- if (((Document) pos)
- .getImplementation()
- .hasFeature("Core", "3.0")) {
- fIsLevel3DOM = true;
- }
- }
-
- if (fSerializer instanceof LexicalHandler) {
- fLexicalHandler = ((LexicalHandler) this.fSerializer);
- }
-
- if (fFilter != null)
- fWhatToShowFilter = fFilter.getWhatToShow();
-
- Node top = pos;
-
- while (null != pos) {
- startNode(pos);
-
- Node nextNode = null;
-
- nextNode = pos.getFirstChild();
-
- while (null == nextNode) {
- endNode(pos);
-
- if (top.equals(pos))
- break;
-
- nextNode = pos.getNextSibling();
-
- if (null == nextNode) {
- pos = pos.getParentNode();
-
- if ((null == pos) || (top.equals(pos))) {
- if (null != pos)
- endNode(pos);
-
- nextNode = null;
-
- break;
- }
- }
- }
-
- pos = nextNode;
- }
- this.fSerializer.endDocument();
- }
-
- /**
- * Perform a pre-order traversal non-recursive style.
-
- * Note that TreeWalker assumes that the subtree is intended to represent
- * a complete (though not necessarily well-formed) document and, during a
- * traversal, startDocument and endDocument will always be issued to the
- * SAX listener.
- *
- * @param pos Node in the tree where to start traversal
- * @param top Node in the tree where to end traversal
- *
- * @throws TransformerException
- */
- public void traverse(Node pos, Node top) throws org.xml.sax.SAXException {
-
- this.fSerializer.startDocument();
-
- // Determine if the Node is a DOM Level 3 Core Node.
- if (pos.getNodeType() != Node.DOCUMENT_NODE) {
- Document ownerDoc = pos.getOwnerDocument();
- if (ownerDoc != null
- && ownerDoc.getImplementation().hasFeature("Core", "3.0")) {
- fIsLevel3DOM = true;
- }
- } else {
- if (((Document) pos)
- .getImplementation()
- .hasFeature("Core", "3.0")) {
- fIsLevel3DOM = true;
- }
- }
-
- if (fSerializer instanceof LexicalHandler) {
- fLexicalHandler = ((LexicalHandler) this.fSerializer);
- }
-
- if (fFilter != null)
- fWhatToShowFilter = fFilter.getWhatToShow();
-
- while (null != pos) {
- startNode(pos);
-
- Node nextNode = null;
-
- nextNode = pos.getFirstChild();
-
- while (null == nextNode) {
- endNode(pos);
-
- if ((null != top) && top.equals(pos))
- break;
-
- nextNode = pos.getNextSibling();
-
- if (null == nextNode) {
- pos = pos.getParentNode();
-
- if ((null == pos) || ((null != top) && top.equals(pos))) {
- nextNode = null;
-
- break;
- }
- }
- }
-
- pos = nextNode;
- }
- this.fSerializer.endDocument();
- }
-
- /**
- * Optimized dispatch of characters.
- */
- private final void dispatachChars(Node node)
- throws org.xml.sax.SAXException {
- if (fSerializer != null) {
- this.fSerializer.characters(node);
- } else {
- String data = ((Text) node).getData();
- this.fSerializer.characters(data.toCharArray(), 0, data.length());
- }
- }
-
- /**
- * Start processing given node
- *
- * @param node Node to process
- *
- * @throws org.xml.sax.SAXException
- */
- protected void startNode(Node node) throws org.xml.sax.SAXException {
- if (node instanceof Locator) {
- Locator loc = (Locator) node;
- fLocator.setColumnNumber(loc.getColumnNumber());
- fLocator.setLineNumber(loc.getLineNumber());
- fLocator.setPublicId(loc.getPublicId());
- fLocator.setSystemId(loc.getSystemId());
- } else {
- fLocator.setColumnNumber(0);
- fLocator.setLineNumber(0);
- }
-
- switch (node.getNodeType()) {
- case Node.DOCUMENT_TYPE_NODE :
- serializeDocType((DocumentType) node, true);
- break;
- case Node.COMMENT_NODE :
- serializeComment((Comment) node);
- break;
- case Node.DOCUMENT_FRAGMENT_NODE :
- // Children are traversed
- break;
- case Node.DOCUMENT_NODE :
- break;
- case Node.ELEMENT_NODE :
- serializeElement((Element) node, true);
- break;
- case Node.PROCESSING_INSTRUCTION_NODE :
- serializePI((ProcessingInstruction) node);
- break;
- case Node.CDATA_SECTION_NODE :
- serializeCDATASection((CDATASection) node);
- break;
- case Node.TEXT_NODE :
- serializeText((Text) node);
- break;
- case Node.ENTITY_REFERENCE_NODE :
- serializeEntityReference((EntityReference) node, true);
- break;
- default :
- }
- }
-
- /**
- * End processing of given node
- *
- *
- * @param node Node we just finished processing
- *
- * @throws org.xml.sax.SAXException
- */
- protected void endNode(Node node) throws org.xml.sax.SAXException {
-
- switch (node.getNodeType()) {
- case Node.DOCUMENT_NODE :
- break;
- case Node.DOCUMENT_TYPE_NODE :
- serializeDocType((DocumentType) node, false);
- break;
- case Node.ELEMENT_NODE :
- serializeElement((Element) node, false);
- break;
- case Node.CDATA_SECTION_NODE :
- break;
- case Node.ENTITY_REFERENCE_NODE :
- serializeEntityReference((EntityReference) node, false);
- break;
- default :
- }
- }
-
- // ***********************************************************************
- // Node serialization methods
- // ***********************************************************************
- /**
- * Applies a filter on the node to serialize
- *
- * @param node The Node to serialize
- * @return True if the node is to be serialized else false if the node
- * is to be rejected or skipped.
- */
- protected boolean applyFilter(Node node, int nodeType) {
- if (fFilter != null && (fWhatToShowFilter & nodeType) != 0) {
-
- short code = fFilter.acceptNode(node);
- switch (code) {
- case NodeFilter.FILTER_REJECT :
- case NodeFilter.FILTER_SKIP :
- return false; // skip the node
- default : // fall through..
- }
- }
- return true;
- }
-
- /**
- * Serializes a Document Type Node.
- *
- * @param node The Docuemnt Type Node to serialize
- * @param bStart Invoked at the start or end of node. Default true.
- */
- protected void serializeDocType(DocumentType node, boolean bStart)
- throws SAXException {
- // The DocType and internalSubset can not be modified in DOM and is
- // considered to be well-formed as the outcome of successful parsing.
- String docTypeName = node.getNodeName();
- String publicId = node.getPublicId();
- String systemId = node.getSystemId();
- String internalSubset = node.getInternalSubset();
-
- //DocumentType nodes are never passed to the filter
-
- if (internalSubset != null && !"".equals(internalSubset)) {
-
- if (bStart) {
- try {
- // The Serializer does not provide a way to write out the
- // DOCTYPE internal subset via an event call, so we write it
- // out here.
- Writer writer = fSerializer.getWriter();
- StringBuffer dtd = new StringBuffer();
-
- dtd.append("<!DOCTYPE ");
- dtd.append(docTypeName);
- if (null != publicId) {
- dtd.append(" PUBLIC \"");
- dtd.append(publicId);
- dtd.append('\"');
- }
-
- if (null != systemId) {
- if (null == publicId) {
- dtd.append(" SYSTEM \"");
- } else {
- dtd.append(" \"");
- }
- dtd.append(systemId);
- dtd.append('\"');
- }
-
- dtd.append(" [ ");
-
- dtd.append(fNewLine);
- dtd.append(internalSubset);
- dtd.append("]>");
- dtd.append(new String(fNewLine));
-
- writer.write(dtd.toString());
- writer.flush();
-
- } catch (IOException e) {
- throw new SAXException(Utils.messages.createMessage(
- MsgKey.ER_WRITING_INTERNAL_SUBSET, null), e);
- }
- } // else if !bStart do nothing
-
- } else {
-
- if (bStart) {
- if (fLexicalHandler != null) {
- fLexicalHandler.startDTD(docTypeName, publicId, systemId);
- }
- } else {
- if (fLexicalHandler != null) {
- fLexicalHandler.endDTD();
- }
- }
- }
- }
-
- /**
- * Serializes a Comment Node.
- *
- * @param node The Comment Node to serialize
- */
- protected void serializeComment(Comment node) throws SAXException {
- // comments=true
- if ((fFeatures & COMMENTS) != 0) {
- String data = node.getData();
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isCommentWellFormed(data);
- }
-
- if (fLexicalHandler != null) {
- // apply the LSSerializer filter after the operations requested by the
- // DOMConfiguration parameters have been applied
- if (!applyFilter(node, NodeFilter.SHOW_COMMENT)) {
- return;
- }
-
- fLexicalHandler.comment(data.toCharArray(), 0, data.length());
- }
- }
- }
-
- /**
- * Serializes an Element Node.
- *
- * @param node The Element Node to serialize
- * @param bStart Invoked at the start or end of node.
- */
- protected void serializeElement(Element node, boolean bStart)
- throws SAXException {
- if (bStart) {
- fElementDepth++;
-
- // We use the Xalan specific startElement and starPrefixMapping calls
- // (and addAttribute and namespaceAfterStartElement) as opposed to
- // SAX specific, for performance reasons as they reduce the overhead
- // of creating an AttList object upfront.
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isElementWellFormed(node);
- }
-
- // REVISIT: We apply the LSSerializer filter for elements before
- // namesapce fixup
- if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
- return;
- }
-
- // namespaces=true, record and fixup namspaced element
- if ((fFeatures & NAMESPACES) != 0) {
- fNSBinder.pushContext();
- fLocalNSBinder.reset();
-
- recordLocalNSDecl(node);
- fixupElementNS(node);
- }
-
- // Namespace normalization
- fSerializer.startElement(
- node.getNamespaceURI(),
- node.getLocalName(),
- node.getNodeName());
-
- serializeAttList(node);
-
- } else {
- fElementDepth--;
-
- // apply the LSSerializer filter
- if (!applyFilter(node, NodeFilter.SHOW_ELEMENT)) {
- return;
- }
-
- this.fSerializer.endElement(
- node.getNamespaceURI(),
- node.getLocalName(),
- node.getNodeName());
- // since endPrefixMapping was not used by SerializationHandler it was removed
- // for performance reasons.
-
- if ((fFeatures & NAMESPACES) != 0 ) {
- fNSBinder.popContext();
- }
-
- }
- }
-
- /**
- * Serializes the Attr Nodes of an Element.
- *
- * @param node The OwnerElement whose Attr Nodes are to be serialized.
- */
- protected void serializeAttList(Element node) throws SAXException {
- NamedNodeMap atts = node.getAttributes();
- int nAttrs = atts.getLength();
-
- for (int i = 0; i < nAttrs; i++) {
- Node attr = atts.item(i);
-
- String localName = attr.getLocalName();
- String attrName = attr.getNodeName();
- String attrPrefix = attr.getPrefix() == null ? "" : attr.getPrefix();
- String attrValue = attr.getNodeValue();
-
- // Determine the Attr's type.
- String type = null;
- if (fIsLevel3DOM) {
- type = ((Attr) attr).getSchemaTypeInfo().getTypeName();
- }
- type = type == null ? "CDATA" : type;
-
- String attrNS = attr.getNamespaceURI();
- if (attrNS !=null && attrNS.length() == 0) {
- attrNS=null;
- // we must remove prefix for this attribute
- attrName=attr.getLocalName();
- }
-
- boolean isSpecified = ((Attr) attr).getSpecified();
- boolean addAttr = true;
- boolean applyFilter = false;
- boolean xmlnsAttr =
- attrName.equals("xmlns") || attrName.startsWith("xmlns:");
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isAttributeWellFormed(attr);
- }
-
- //-----------------------------------------------------------------
- // start Attribute namespace fixup
- //-----------------------------------------------------------------
- // namespaces=true, normalize all non-namespace attributes
- // Step 3. Attribute
- if ((fFeatures & NAMESPACES) != 0 && !xmlnsAttr) {
-
- // If the Attr has a namespace URI
- if (attrNS != null) {
- attrPrefix = attrPrefix == null ? "" : attrPrefix;
-
- String declAttrPrefix = fNSBinder.getPrefix(attrNS);
- String declAttrNS = fNSBinder.getURI(attrPrefix);
-
- // attribute has no prefix (default namespace decl does not apply to
- // attributes)
- // OR
- // attribute prefix is not declared
- // OR
- // conflict: attribute has a prefix that conflicts with a binding
- if ("".equals(attrPrefix) || "".equals(declAttrPrefix)
- || !attrPrefix.equals(declAttrPrefix)) {
-
- // namespaceURI matches an in scope declaration of one or
- // more prefixes
- if (declAttrPrefix != null && !"".equals(declAttrPrefix)) {
- // pick the prefix that was found and change attribute's
- // prefix and nodeName.
- attrPrefix = declAttrPrefix;
-
- if (declAttrPrefix.length() > 0 ) {
- attrName = declAttrPrefix + ":" + localName;
- } else {
- attrName = localName;
- }
- } else {
- // The current prefix is not null and it has no in scope
- // declaration
- if (attrPrefix != null && !"".equals(attrPrefix)
- && declAttrNS == null) {
- // declare this prefix
- if ((fFeatures & NAMESPACEDECLS) != 0) {
- fSerializer.addAttribute(XMLNS_URI, attrPrefix,
- XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
- attrNS);
- fNSBinder.declarePrefix(attrPrefix, attrNS);
- fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
- }
- } else {
- // find a prefix following the pattern "NS" +index
- // (starting at 1)
- // make sure this prefix is not declared in the current
- // scope.
- int counter = 1;
- attrPrefix = "NS" + counter++;
-
- while (fLocalNSBinder.getURI(attrPrefix) != null) {
- attrPrefix = "NS" + counter++;
- }
- // change attribute's prefix and Name
- attrName = attrPrefix + ":" + localName;
-
- // create a local namespace declaration attribute
- // Add the xmlns declaration attribute
- if ((fFeatures & NAMESPACEDECLS) != 0) {
-
- fSerializer.addAttribute(XMLNS_URI, attrPrefix,
- XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
- attrNS);
- fNSBinder.declarePrefix(attrPrefix, attrNS);
- fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
- }
- }
- }
- }
-
- } else { // if the Attr has no namespace URI
- // Attr has no localName
- if (localName == null) {
- // DOM Level 1 node!
- String msg = Utils.messages.createMessage(
- MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
- new Object[] { attrName });
-
- if (fErrorHandler != null) {
- fErrorHandler
- .handleError(new DOMErrorImpl(
- DOMError.SEVERITY_ERROR, msg,
- MsgKey.ER_NULL_LOCAL_ELEMENT_NAME, null,
- null, null));
- }
-
- } else { // uri=null and no colon
- // attr has no namespace URI and no prefix
- // no action is required, since attrs don't use default
- }
- }
-
- }
-
-
- // discard-default-content=true
- // Default attr's are not passed to the filter and this contraint
- // is applied only when discard-default-content=true
- // What about default xmlns attributes???? check for xmlnsAttr
- if ((((fFeatures & DISCARDDEFAULT) != 0) && isSpecified)
- || ((fFeatures & DISCARDDEFAULT) == 0)) {
- applyFilter = true;
- } else {
- addAttr = false;
- }
-
- if (applyFilter) {
- // apply the filter for Attributes that are not default attributes
- // or namespace decl attributes
- if (fFilter != null
- && (fFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)
- != 0) {
-
- if (!xmlnsAttr) {
- short code = fFilter.acceptNode(attr);
- switch (code) {
- case NodeFilter.FILTER_REJECT :
- case NodeFilter.FILTER_SKIP :
- addAttr = false;
- break;
- default : //fall through..
- }
- }
- }
- }
-
- // if the node is a namespace node
- if (addAttr && xmlnsAttr) {
- // If namespace-declarations=true, add the node , else don't add it
- if ((fFeatures & NAMESPACEDECLS) != 0) {
- // The namespace may have been fixed up, in that case don't add it.
- if (localName != null && !"".equals(localName)) {
- fSerializer.addAttribute(attrNS, localName, attrName, type, attrValue);
- }
- }
- } else if (
- addAttr && !xmlnsAttr) { // if the node is not a namespace node
- // If namespace-declarations=true, add the node with the Attr nodes namespaceURI
- // else add the node setting it's namespace to null or else the serializer will later
- // attempt to add a xmlns attr for the prefixed attribute
- if (((fFeatures & NAMESPACEDECLS) != 0) && (attrNS != null)) {
- fSerializer.addAttribute(
- attrNS,
- localName,
- attrName,
- type,
- attrValue);
- } else {
- fSerializer.addAttribute(
- "",
- localName,
- attrName,
- type,
- attrValue);
- }
- }
-
- //
- if (xmlnsAttr && ((fFeatures & NAMESPACEDECLS) != 0)) {
- int index;
- // Use "" instead of null, as Xerces likes "" for the
- // name of the default namespace. Fix attributed
- // to "Steven Murray" <[email protected]>.
- String prefix =
- (index = attrName.indexOf(":")) < 0
- ? ""
- : attrName.substring(index + 1);
-
- if (!"".equals(prefix)) {
- fSerializer.namespaceAfterStartElement(prefix, attrValue);
- }
- }
- }
-
- }
-
- /**
- * Serializes an ProcessingInstruction Node.
- *
- * @param node The ProcessingInstruction Node to serialize
- */
- protected void serializePI(ProcessingInstruction node)
- throws SAXException {
- ProcessingInstruction pi = node;
- String name = pi.getNodeName();
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isPIWellFormed(node);
- }
-
- // apply the LSSerializer filter
- if (!applyFilter(node, NodeFilter.SHOW_PROCESSING_INSTRUCTION)) {
- return;
- }
-
- // String data = pi.getData();
- if (name.equals("xslt-next-is-raw")) {
- fNextIsRaw = true;
- } else {
- this.fSerializer.processingInstruction(name, pi.getData());
- }
- }
-
- /**
- * Serializes an CDATASection Node.
- *
- * @param node The CDATASection Node to serialize
- */
- protected void serializeCDATASection(CDATASection node)
- throws SAXException {
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isCDATASectionWellFormed(node);
- }
-
- // cdata-sections = true
- if ((fFeatures & CDATA) != 0) {
-
- // split-cdata-sections = true
- // Assumption: This parameter has an effect only when
- // cdata-sections=true
- // ToStream, by default splits cdata-sections. Hence the check
- // below.
- String nodeValue = node.getNodeValue();
- int endIndex = nodeValue.indexOf("]]>");
- if ((fFeatures & SPLITCDATA) != 0) {
- if (endIndex >= 0) {
- // The first node split will contain the ]] markers
- String relatedData = nodeValue.substring(0, endIndex + 2);
-
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_CDATA_SECTIONS_SPLIT,
- null);
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_WARNING,
- msg,
- MsgKey.ER_CDATA_SECTIONS_SPLIT,
- null,
- relatedData,
- null));
- }
- }
- } else {
- if (endIndex >= 0) {
- // The first node split will contain the ]] markers
- String relatedData = nodeValue.substring(0, endIndex + 2);
-
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_CDATA_SECTIONS_SPLIT,
- null);
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_ERROR,
- msg,
- MsgKey.ER_CDATA_SECTIONS_SPLIT));
- }
- // Report an error and return. What error???
- return;
- }
- }
-
- // apply the LSSerializer filter
- if (!applyFilter(node, NodeFilter.SHOW_CDATA_SECTION)) {
- return;
- }
-
- // splits the cdata-section
- if (fLexicalHandler != null) {
- fLexicalHandler.startCDATA();
- }
- dispatachChars(node);
- if (fLexicalHandler != null) {
- fLexicalHandler.endCDATA();
- }
- } else {
- dispatachChars(node);
- }
- }
-
- /**
- * Serializes an Text Node.
- *
- * @param node The Text Node to serialize
- */
- protected void serializeText(Text node) throws SAXException {
- if (fNextIsRaw) {
- fNextIsRaw = false;
- fSerializer.processingInstruction(
- javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING,
- "");
- dispatachChars(node);
- fSerializer.processingInstruction(
- javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING,
- "");
- } else {
- // keep track of dispatch or not to avoid duplicaiton of filter code
- boolean bDispatch = false;
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isTextWellFormed(node);
- }
-
- // if the node is whitespace
- // Determine the Attr's type.
- boolean isElementContentWhitespace = false;
- if (fIsLevel3DOM) {
- isElementContentWhitespace =
- node.isElementContentWhitespace();
- }
-
- if (isElementContentWhitespace) {
- // element-content-whitespace=true
- if ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) {
- bDispatch = true;
- }
- } else {
- bDispatch = true;
- }
-
- // apply the LSSerializer filter
- if (!applyFilter(node, NodeFilter.SHOW_TEXT)) {
- return;
- }
-
- if (bDispatch) {
- dispatachChars(node);
- }
- }
- }
-
- /**
- * Serializes an EntityReference Node.
- *
- * @param node The EntityReference Node to serialize
- * @param bStart Inicates if called from start or endNode
- */
- protected void serializeEntityReference(
- EntityReference node,
- boolean bStart)
- throws SAXException {
- if (bStart) {
- EntityReference eref = node;
- // entities=true
- if ((fFeatures & ENTITIES) != 0) {
-
- // perform well-formedness and other checking only if
- // entities = true
-
- // well-formed=true
- if ((fFeatures & WELLFORMED) != 0) {
- isEntityReferneceWellFormed(node);
- }
-
- // check "unbound-prefix-in-entity-reference" [fatal]
- // Raised if the configuration parameter "namespaces" is set to true
- if ((fFeatures & NAMESPACES) != 0) {
- checkUnboundPrefixInEntRef(node);
- }
-
- // The filter should not apply in this case, since the
- // EntityReference is not being expanded.
- // should we pass entity reference nodes to the filter???
- }
-
- if (fLexicalHandler != null) {
-
- // startEntity outputs only Text but not Element, Attr, Comment
- // and PI child nodes. It does so by setting the m_inEntityRef
- // in ToStream and using this to decide if a node is to be
- // serialized or not.
- fLexicalHandler.startEntity(eref.getNodeName());
- }
-
- } else {
- EntityReference eref = node;
- // entities=true or false,
- if (fLexicalHandler != null) {
- fLexicalHandler.endEntity(eref.getNodeName());
- }
- }
- }
-
-
- // ***********************************************************************
- // Methods to check well-formedness
- // ***********************************************************************
- /**
- * Taken from org.apache.xerces.dom.CoreDocumentImpl
- *
- * Check the string against XML's definition of acceptable names for
- * elements and attributes and so on using the XMLCharacterProperties
- * utility class
- */
- protected boolean isXMLName(String s, boolean xml11Version) {
-
- if (s == null) {
- return false;
- }
- if (!xml11Version)
- return XMLChar.isValidName(s);
- else
- return XML11Char.isXML11ValidName(s);
- }
-
- /**
- * Taken from org.apache.xerces.dom.CoreDocumentImpl
- *
- * Checks if the given qualified name is legal with respect
- * to the version of XML to which this document must conform.
- *
- * @param prefix prefix of qualified name
- * @param local local part of qualified name
- */
- protected boolean isValidQName(
- String prefix,
- String local,
- boolean xml11Version) {
-
- // check that both prefix and local part match NCName
- if (local == null)
- return false;
- boolean validNCName = false;
-
- if (!xml11Version) {
- validNCName =
- (prefix == null || XMLChar.isValidNCName(prefix))
- && XMLChar.isValidNCName(local);
- } else {
- validNCName =
- (prefix == null || XML11Char.isXML11ValidNCName(prefix))
- && XML11Char.isXML11ValidNCName(local);
- }
-
- return validNCName;
- }
-
- /**
- * Checks if a XML character is well-formed
- *
- * @param characters A String of characters to be checked for Well-Formedness
- * @param refInvalidChar A reference to the character to be returned that was determined invalid.
- */
- protected boolean isWFXMLChar(String chardata, Character refInvalidChar) {
- if (chardata == null || (chardata.length() == 0)) {
- return true;
- }
-
- char[] dataarray = chardata.toCharArray();
- int datalength = dataarray.length;
-
- // version of the document is XML 1.1
- if (fIsXMLVersion11) {
- //we need to check all characters as per production rules of XML11
- int i = 0;
- while (i < datalength) {
- if (XML11Char.isXML11Invalid(dataarray[i++])) {
- // check if this is a supplemental character
- char ch = dataarray[i - 1];
- if (XMLChar.isHighSurrogate(ch) && i < datalength) {
- char ch2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(ch2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(ch, ch2))) {
- continue;
- }
- }
- // Reference to invalid character which is returned
- refInvalidChar = new Character(ch);
- return false;
- }
- }
- } // version of the document is XML 1.0
- else {
- // we need to check all characters as per production rules of XML 1.0
- int i = 0;
- while (i < datalength) {
- if (XMLChar.isInvalid(dataarray[i++])) {
- // check if this is a supplemental character
- char ch = dataarray[i - 1];
- if (XMLChar.isHighSurrogate(ch) && i < datalength) {
- char ch2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(ch2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(ch, ch2))) {
- continue;
- }
- }
- // Reference to invalid character which is returned
- refInvalidChar = new Character(ch);
- return false;
- }
- }
- } // end-else fDocument.isXMLVersion()
-
- return true;
- } // isXMLCharWF
-
- /**
- * Checks if a XML character is well-formed. If there is a problem with
- * the character a non-null Character is returned else null is returned.
- *
- * @param characters A String of characters to be checked for Well-Formedness
- * @return Character A reference to the character to be returned that was determined invalid.
- */
- protected Character isWFXMLChar(String chardata) {
- Character refInvalidChar;
- if (chardata == null || (chardata.length() == 0)) {
- return null;
- }
-
- char[] dataarray = chardata.toCharArray();
- int datalength = dataarray.length;
-
- // version of the document is XML 1.1
- if (fIsXMLVersion11) {
- //we need to check all characters as per production rules of XML11
- int i = 0;
- while (i < datalength) {
- if (XML11Char.isXML11Invalid(dataarray[i++])) {
- // check if this is a supplemental character
- char ch = dataarray[i - 1];
- if (XMLChar.isHighSurrogate(ch) && i < datalength) {
- char ch2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(ch2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(ch, ch2))) {
- continue;
- }
- }
- // Reference to invalid character which is returned
- refInvalidChar = new Character(ch);
- return refInvalidChar;
- }
- }
- } // version of the document is XML 1.0
- else {
- // we need to check all characters as per production rules of XML 1.0
- int i = 0;
- while (i < datalength) {
- if (XMLChar.isInvalid(dataarray[i++])) {
- // check if this is a supplemental character
- char ch = dataarray[i - 1];
- if (XMLChar.isHighSurrogate(ch) && i < datalength) {
- char ch2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(ch2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(ch, ch2))) {
- continue;
- }
- }
- // Reference to invalid character which is returned
- refInvalidChar = new Character(ch);
- return refInvalidChar;
- }
- }
- } // end-else fDocument.isXMLVersion()
-
- return null;
- } // isXMLCharWF
-
- /**
- * Checks if a comment node is well-formed
- *
- * @param data The contents of the comment node
- * @return a boolean indiacating if the comment is well-formed or not.
- */
- protected void isCommentWellFormed(String data) {
- if (data == null || (data.length() == 0)) {
- return;
- }
-
- char[] dataarray = data.toCharArray();
- int datalength = dataarray.length;
-
- // version of the document is XML 1.1
- if (fIsXMLVersion11) {
- // we need to check all chracters as per production rules of XML11
- int i = 0;
- while (i < datalength) {
- char c = dataarray[i++];
- if (XML11Char.isXML11Invalid(c)) {
- // check if this is a supplemental character
- if (XMLChar.isHighSurrogate(c) && i < datalength) {
- char c2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(c2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(c, c2))) {
- continue;
- }
- }
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
- new Object[] { new Character(c)});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- } else if (c == '-' && i < datalength && dataarray[i] == '-') {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_DASH_IN_COMMENT,
- null);
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- }
- }
- } // version of the document is XML 1.0
- else {
- // we need to check all chracters as per production rules of XML 1.0
- int i = 0;
- while (i < datalength) {
- char c = dataarray[i++];
- if (XMLChar.isInvalid(c)) {
- // check if this is a supplemental character
- if (XMLChar.isHighSurrogate(c) && i < datalength) {
- char c2 = dataarray[i++];
- if (XMLChar.isLowSurrogate(c2)
- && XMLChar.isSupplemental(
- XMLChar.supplemental(c, c2))) {
- continue;
- }
- }
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_COMMENT,
- new Object[] { new Character(c)});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- } else if (c == '-' && i < datalength && dataarray[i] == '-') {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_DASH_IN_COMMENT,
- null);
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- }
- }
- }
- return;
- }
-
- /**
- * Checks if an element node is well-formed, by checking its Name for well-formedness.
- *
- * @param data The contents of the comment node
- * @return a boolean indiacating if the comment is well-formed or not.
- */
- protected void isElementWellFormed(Node node) {
- boolean isNameWF = false;
- if ((fFeatures & NAMESPACES) != 0) {
- isNameWF =
- isValidQName(
- node.getPrefix(),
- node.getLocalName(),
- fIsXMLVersion11);
- } else {
- isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
- }
-
- if (!isNameWF) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- new Object[] { "Element", node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- null,
- null,
- null));
- }
- }
- }
-
- /**
- * Checks if an attr node is well-formed, by checking it's Name and value
- * for well-formedness.
- *
- * @param data The contents of the comment node
- * @return a boolean indiacating if the comment is well-formed or not.
- */
- protected void isAttributeWellFormed(Node node) {
- boolean isNameWF = false;
- if ((fFeatures & NAMESPACES) != 0) {
- isNameWF =
- isValidQName(
- node.getPrefix(),
- node.getLocalName(),
- fIsXMLVersion11);
- } else {
- isNameWF = isXMLName(node.getNodeName(), fIsXMLVersion11);
- }
-
- if (!isNameWF) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- new Object[] { "Attr", node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- null,
- null,
- null));
- }
- }
-
- // Check the Attr's node value
- // WFC: No < in Attribute Values
- String value = node.getNodeValue();
- if (value.indexOf('<') >= 0) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_LT_IN_ATTVAL,
- new Object[] {
- ((Attr) node).getOwnerElement().getNodeName(),
- node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_LT_IN_ATTVAL,
- null,
- null,
- null));
- }
- }
-
- // we need to loop through the children of attr nodes and check their values for
- // well-formedness
- NodeList children = node.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- Node child = children.item(i);
- // An attribute node with no text or entity ref child for example
- // doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns");
- // followes by
- // element.setAttributeNodeNS(attribute);
- // can potentially lead to this situation. If the attribute
- // was a prefix Namespace attribute declaration then then DOM Core
- // should have some exception defined for this.
- if (child == null) {
- // we should probably report an error
- continue;
- }
- switch (child.getNodeType()) {
- case Node.TEXT_NODE :
- isTextWellFormed((Text) child);
- break;
- case Node.ENTITY_REFERENCE_NODE :
- isEntityReferneceWellFormed((EntityReference) child);
- break;
- default :
- }
- }
-
- // TODO:
- // WFC: Check if the attribute prefix is bound to
- // http://www.w3.org/2000/xmlns/
-
- // WFC: Unique Att Spec
- // Perhaps pass a seen boolean value to this method. serializeAttList will determine
- // if the attr was seen before.
- }
-
- /**
- * Checks if a PI node is well-formed, by checking it's Name and data
- * for well-formedness.
- *
- * @param data The contents of the comment node
- */
- protected void isPIWellFormed(ProcessingInstruction node) {
- // Is the PI Target a valid XML name
- if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- new Object[] { "ProcessingInstruction", node.getTarget()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- null,
- null,
- null));
- }
- }
-
- // Does the PI Data carry valid XML characters
-
- // REVISIT: Should we check if the PI DATA contains a ?> ???
- Character invalidChar = isWFXMLChar(node.getData());
- if (invalidChar != null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_PI,
- new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- }
- }
-
- /**
- * Checks if an CDATASection node is well-formed, by checking it's data
- * for well-formedness. Note that the presence of a CDATA termination mark
- * in the contents of a CDATASection is handled by the parameter
- * spli-cdata-sections
- *
- * @param data The contents of the comment node
- */
- protected void isCDATASectionWellFormed(CDATASection node) {
- // Does the data valid XML character data
- Character invalidChar = isWFXMLChar(node.getData());
- //if (!isWFXMLChar(node.getData(), invalidChar)) {
- if (invalidChar != null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_CDATA,
- new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- }
- }
-
- /**
- * Checks if an Text node is well-formed, by checking if it contains invalid
- * XML characters.
- *
- * @param data The contents of the comment node
- */
- protected void isTextWellFormed(Text node) {
- // Does the data valid XML character data
- Character invalidChar = isWFXMLChar(node.getData());
- if (invalidChar != null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_TEXT,
- new Object[] { Integer.toHexString(Character.getNumericValue(invalidChar.charValue())) });
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER,
- null,
- null,
- null));
- }
- }
- }
-
- /**
- * Checks if an EntityRefernece node is well-formed, by checking it's node name. Then depending
- * on whether it is referenced in Element content or in an Attr Node, checks if the EntityReference
- * references an unparsed entity or a external entity and if so throws raises the
- * appropriate well-formedness error.
- *
- * @param data The contents of the comment node
- * @parent The parent of the EntityReference Node
- */
- protected void isEntityReferneceWellFormed(EntityReference node) {
- // Is the EntityReference name a valid XML name
- if (!isXMLName(node.getNodeName(), fIsXMLVersion11)) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- new Object[] { "EntityReference", node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_INVALID_CHARACTER_IN_NODE_NAME,
- null,
- null,
- null));
- }
- }
-
- // determine the parent node
- Node parent = node.getParentNode();
-
- // Traverse the declared entities and check if the nodeName and namespaceURI
- // of the EntityReference matches an Entity. If so, check the if the notationName
- // is not null, if so, report an error.
- DocumentType docType = node.getOwnerDocument().getDoctype();
- if (docType != null) {
- NamedNodeMap entities = docType.getEntities();
- for (int i = 0; i < entities.getLength(); i++) {
- Entity ent = (Entity) entities.item(i);
-
- String nodeName =
- node.getNodeName() == null ? "" : node.getNodeName();
- String nodeNamespaceURI =
- node.getNamespaceURI() == null
- ? ""
- : node.getNamespaceURI();
- String entName =
- ent.getNodeName() == null ? "" : ent.getNodeName();
- String entNamespaceURI =
- ent.getNamespaceURI() == null ? "" : ent.getNamespaceURI();
- // If referenced in Element content
- // WFC: Parsed Entity
- if (parent.getNodeType() == Node.ELEMENT_NODE) {
- if (entNamespaceURI.equals(nodeNamespaceURI)
- && entName.equals(nodeName)) {
-
- if (ent.getNotationName() != null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
- new Object[] { node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_REF_TO_UNPARSED_ENT,
- null,
- null,
- null));
- }
- }
- }
- } // end if WFC: Parsed Entity
-
- // If referenced in an Attr value
- // WFC: No External Entity References
- if (parent.getNodeType() == Node.ATTRIBUTE_NODE) {
- if (entNamespaceURI.equals(nodeNamespaceURI)
- && entName.equals(nodeName)) {
-
- if (ent.getPublicId() != null
- || ent.getSystemId() != null
- || ent.getNotationName() != null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
- new Object[] { node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_WF_REF_TO_EXTERNAL_ENT,
- null,
- null,
- null));
- }
- }
- }
- } //end if WFC: No External Entity References
- }
- }
- } // isEntityReferneceWellFormed
-
- /**
- * If the configuration parameter "namespaces" is set to true, this methods
- * checks if an entity whose replacement text contains unbound namespace
- * prefixes is referenced in a location where there are no bindings for
- * the namespace prefixes and if so raises a LSException with the error-type
- * "unbound-prefix-in-entity-reference"
- *
- * @param Node, The EntityReference nodes whose children are to be checked
- */
- protected void checkUnboundPrefixInEntRef(Node node) {
- Node child, next;
- for (child = node.getFirstChild(); child != null; child = next) {
- next = child.getNextSibling();
-
- if (child.getNodeType() == Node.ELEMENT_NODE) {
-
- //If a NamespaceURI is not declared for the current
- //node's prefix, raise a fatal error.
- String prefix = child.getPrefix();
- if (prefix != null
- && fNSBinder.getURI(prefix) == null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
- new Object[] {
- node.getNodeName(),
- child.getNodeName(),
- prefix });
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_ELEM_UNBOUND_PREFIX_IN_ENTREF,
- null,
- null,
- null));
- }
- }
-
- NamedNodeMap attrs = child.getAttributes();
-
- for (int i = 0; i < attrs.getLength(); i++) {
- String attrPrefix = attrs.item(i).getPrefix();
- if (attrPrefix != null
- && fNSBinder.getURI(attrPrefix) == null) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
- new Object[] {
- node.getNodeName(),
- child.getNodeName(),
- attrs.item(i)});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_FATAL_ERROR,
- msg,
- MsgKey.ER_ATTR_UNBOUND_PREFIX_IN_ENTREF,
- null,
- null,
- null));
- }
- }
- }
- }
-
- if (child.hasChildNodes()) {
- checkUnboundPrefixInEntRef(child);
- }
- }
- }
-
- // ***********************************************************************
- // Namespace normalization
- // ***********************************************************************
- /**
- * Records local namespace declarations, to be used for normalization later
- *
- * @param Node, The element node, whose namespace declarations are to be recorded
- */
- protected void recordLocalNSDecl(Node node) {
- NamedNodeMap atts = ((Element) node).getAttributes();
- int length = atts.getLength();
-
- for (int i = 0; i < length; i++) {
- Node attr = atts.item(i);
-
- String localName = attr.getLocalName();
- String attrPrefix = attr.getPrefix();
- String attrValue = attr.getNodeValue();
- String attrNS = attr.getNamespaceURI();
-
- localName =
- localName == null
- || XMLNS_PREFIX.equals(localName) ? "" : localName;
- attrPrefix = attrPrefix == null ? "" : attrPrefix;
- attrValue = attrValue == null ? "" : attrValue;
- attrNS = attrNS == null ? "" : attrNS;
-
- // check if attribute is a namespace decl
- if (XMLNS_URI.equals(attrNS)) {
-
- // No prefix may be bound to http://www.w3.org/2000/xmlns/.
- if (XMLNS_URI.equals(attrValue)) {
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
- new Object[] { attrPrefix, XMLNS_URI });
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_ERROR,
- msg,
- MsgKey.ER_NS_PREFIX_CANNOT_BE_BOUND,
- null,
- null,
- null));
- }
- } else {
- // store the namespace-declaration
- if (XMLNS_PREFIX.equals(attrPrefix) ) {
- // record valid decl
- if (attrValue.length() != 0) {
- fNSBinder.declarePrefix(localName, attrValue);
- } else {
- // Error; xmlns:prefix=""
- }
- } else { // xmlns
- // empty prefix is always bound ("" or some string)
- fNSBinder.declarePrefix("", attrValue);
- }
- }
-
- }
- }
- }
-
- /**
- * Fixes an element's namespace
- *
- * @param Node, The element node, whose namespace is to be fixed
- */
- protected void fixupElementNS(Node node) throws SAXException {
- String namespaceURI = ((Element) node).getNamespaceURI();
- String prefix = ((Element) node).getPrefix();
- String localName = ((Element) node).getLocalName();
-
- if (namespaceURI != null) {
- //if ( Element's prefix/namespace pair (or default namespace,
- // if no prefix) are within the scope of a binding )
- prefix = prefix == null ? "" : prefix;
- String inScopeNamespaceURI = fNSBinder.getURI(prefix);
-
- if ((inScopeNamespaceURI != null
- && inScopeNamespaceURI.equals(namespaceURI))) {
- // do nothing, declaration in scope is inherited
-
- } else {
- // Create a local namespace declaration attr for this namespace,
- // with Element's current prefix (or a default namespace, if
- // no prefix). If there's a conflicting local declaration
- // already present, change its value to use this namespace.
-
- // Add the xmlns declaration attribute
- //fNSBinder.pushNamespace(prefix, namespaceURI, fElementDepth);
- if ((fFeatures & NAMESPACEDECLS) != 0) {
- if ("".equals(prefix) || "".equals(namespaceURI)) {
- ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceURI);
- } else {
- ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX + ":" + prefix, namespaceURI);
- }
- }
- fLocalNSBinder.declarePrefix(prefix, namespaceURI);
- fNSBinder.declarePrefix(prefix, namespaceURI);
-
- }
- } else {
- // Element has no namespace
- // DOM Level 1
- if (localName == null || "".equals(localName)) {
- // DOM Level 1 node!
- String msg =
- Utils.messages.createMessage(
- MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
- new Object[] { node.getNodeName()});
-
- if (fErrorHandler != null) {
- fErrorHandler.handleError(
- new DOMErrorImpl(
- DOMError.SEVERITY_ERROR,
- msg,
- MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
- null,
- null,
- null));
- }
- } else {
- namespaceURI = fNSBinder.getURI("");
- if (namespaceURI !=null && namespaceURI.length() > 0) {
- ((Element)node).setAttributeNS(XMLNS_URI, XMLNS_PREFIX, "");
- fLocalNSBinder.declarePrefix("", "");
- fNSBinder.declarePrefix("", "");
- }
- }
- }
- }
- /**
- * This table is a quick lookup of a property key (String) to the integer that
- * is the bit to flip in the fFeatures field, so the integers should have
- * values 1,2,4,8,16...
- *
- */
- private static final Hashtable s_propKeys = new Hashtable();
- static {
-
- // Initialize the mappings of property keys to bit values (Integer objects)
- // or mappings to a String object "", which indicates we are interested
- // in the property, but it does not have a simple bit value to flip
-
- // cdata-sections
- int i = CDATA;
- Integer val = new Integer(i);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_CDATA_SECTIONS,
- val);
-
- // comments
- int i1 = COMMENTS;
- val = new Integer(i1);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_COMMENTS,
- val);
-
- // element-content-whitespace
- int i2 = ELEM_CONTENT_WHITESPACE;
- val = new Integer(i2);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS
- + DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE,
- val);
- int i3 = ENTITIES;
-
- // entities
- val = new Integer(i3);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_ENTITIES,
- val);
-
- // namespaces
- int i4 = NAMESPACES;
- val = new Integer(i4);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_NAMESPACES,
- val);
-
- // namespace-declarations
- int i5 = NAMESPACEDECLS;
- val = new Integer(i5);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS
- + DOMConstants.DOM_NAMESPACE_DECLARATIONS,
- val);
-
- // split-cdata-sections
- int i6 = SPLITCDATA;
- val = new Integer(i6);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_SPLIT_CDATA,
- val);
-
- // discard-default-content
- int i7 = WELLFORMED;
- val = new Integer(i7);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS + DOMConstants.DOM_WELLFORMED,
- val);
-
- // discard-default-content
- int i8 = DISCARDDEFAULT;
- val = new Integer(i8);
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS
- + DOMConstants.DOM_DISCARD_DEFAULT_CONTENT,
- val);
-
- // We are interested in these properties, but they don't have a simple
- // bit value to deal with.
- s_propKeys.put(
- DOMConstants.S_DOM3_PROPERTIES_NS
- + DOMConstants.DOM_FORMAT_PRETTY_PRINT,
- "");
- s_propKeys.put(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "");
- s_propKeys.put(
- DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.S_XML_VERSION,
- "");
- s_propKeys.put(DOMConstants.S_XSL_OUTPUT_ENCODING, "");
- s_propKeys.put(DOMConstants.S_XERCES_PROPERTIES_NS + DOMConstants.DOM_ENTITIES, "");
- }
-
- /**
- * Initializes fFeatures based on the DOMConfiguration Parameters set.
- *
- * @param properties DOMConfiguraiton properties that were set and which are
- * to be used while serializing the DOM.
- */
- protected void initProperties(Properties properties) {
-
- for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {
-
- final String key = (String) keys.nextElement();
-
- // caonical-form
- // Other features will be enabled or disabled when this is set to true or false.
-
- // error-handler; set via the constructor
-
- // infoset
- // Other features will be enabled or disabled when this is set to true
-
- // A quick lookup for the given set of properties (cdata-sections ...)
- final Object iobj = s_propKeys.get(key);
- if (iobj != null) {
- if (iobj instanceof Integer) {
- // Dealing with a property that has a simple bit value that
- // we need to set
-
- // cdata-sections
- // comments
- // element-content-whitespace
- // entities
- // namespaces
- // namespace-declarations
- // split-cdata-sections
- // well-formed
- // discard-default-content
- final int BITFLAG = ((Integer) iobj).intValue();
- if ((properties.getProperty(key).endsWith("yes"))) {
- fFeatures = fFeatures | BITFLAG;
- } else {
- fFeatures = fFeatures & ~BITFLAG;
- }
- } else {
- // We are interested in the property, but it is not
- // a simple bit that we need to set.
-
- if ((DOMConstants.S_DOM3_PROPERTIES_NS
- + DOMConstants.DOM_FORMAT_PRETTY_PRINT)
- .equals(key)) {
- // format-pretty-print; set internally on the serializers via xsl:output properties in LSSerializer
- if ((properties.getProperty(key).endsWith("yes"))) {
- fSerializer.setIndent(true);
- fSerializer.setIndentAmount(3);
- } else {
- fSerializer.setIndent(false);
- }
- } else if (
- (DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL).equals(
- key)) {
- // omit-xml-declaration; set internally on the serializers via xsl:output properties in LSSerializer
- if ((properties.getProperty(key).endsWith("yes"))) {
- fSerializer.setOmitXMLDeclaration(true);
- } else {
- fSerializer.setOmitXMLDeclaration(false);
- }
- } else if (
- (
- DOMConstants.S_XERCES_PROPERTIES_NS
- + DOMConstants.S_XML_VERSION).equals(
- key)) {
- // Retreive the value of the XML Version attribute via the xml-version
- String version = properties.getProperty(key);
- if ("1.1".equals(version)) {
- fIsXMLVersion11 = true;
- fSerializer.setVersion(version);
- } else {
- fSerializer.setVersion("1.0");
- }
- } else if (
- (DOMConstants.S_XSL_OUTPUT_ENCODING).equals(key)) {
- // Retreive the value of the XML Encoding attribute
- String encoding = properties.getProperty(key);
- if (encoding != null) {
- fSerializer.setEncoding(encoding);
- }
- } else if ((DOMConstants.S_XERCES_PROPERTIES_NS
- + DOMConstants.DOM_ENTITIES).equals(key)) {
- // Preserve entity references in the document
- if ((properties.getProperty(key).endsWith("yes"))) {
- fSerializer.setDTDEntityExpansion(false);
- }
- else {
- fSerializer.setDTDEntityExpansion(true);
- }
- } else {
- // We shouldn't get here, ever, now what?
- }
- }
- }
- }
- // Set the newLine character to use
- if (fNewLine != null) {
- fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR, fNewLine);
- }
- }
-
-} //TreeWalker
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id$
+ */
+
+package org.apache.xml.serializer.dom3;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import org.apache.xml.serializer.dom3.NamespaceSupport;
+import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.serializer.utils.MsgKey;
+import org.apache.xml.serializer.utils.Utils;
+import org.apache.xml.serializer.utils.XML11Char;
+import org.apache.xml.serializer.utils.XMLChar;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Entity;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.ls.LSSerializerFilter;
+import org.w3c.dom.traversal.NodeFilter;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * Built on org.apache.xml.serializer.TreeWalker and adds functionality to
+ * traverse and serialize a DOM Node (Level 2 or Level 3) as specified in
+ * the DOM Level 3 LS Recommedation by evaluating and applying DOMConfiguration
+ * parameters and filters if any during serialization.
+ *
+ * @xsl.usage internal
+ */
+final class DOM3TreeWalker {
+
+ /**
+ * The SerializationHandler, it extends ContentHandler and when
+ * this class is instantiated via the constructor provided, a
+ * SerializationHandler object is passed to it.
+ */
+ private SerializationHandler fSerializer = null;
+
+ /** We do not need DOM2Helper since DOM Level 3 LS applies to DOM Level 2 or newer */
+
+ /** Locator object for this TreeWalker */
+ private LocatorImpl fLocator = new LocatorImpl();
+
+ /** ErrorHandler */
+ private DOMErrorHandler fErrorHandler = null;
+
+ /** LSSerializerFilter */
+ private LSSerializerFilter fFilter = null;
+
+ /** If the serializer is an instance of a LexicalHandler */
+ private LexicalHandler fLexicalHandler = null;
+
+ private int fWhatToShowFilter;
+
+ /** New Line character to use in serialization */
+ private String fNewLine = null;
+
+ /** DOMConfiguration Properties */
+ private Properties fDOMConfigProperties = null;
+
+ /** Keeps track if we are in an entity reference when entities=true */
+ private boolean fInEntityRef = false;
+
+ /** Stores the version of the XML document to be serialize */
+ private String fXMLVersion = null;
+
+ /** XML Version, default 1.0 */
+ private boolean fIsXMLVersion11 = false;
+
+ /** Is the Node a Level 3 DOM node */
+ private boolean fIsLevel3DOM = false;
+
+ /** DOM Configuration Parameters */
+ private int fFeatures = 0;
+
+ /** Flag indicating whether following text to be processed is raw text */
+ boolean fNextIsRaw = false;
+
+ //
[... 2033 lines stripped ...]