/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * 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.
 */

package com.sun.org.apache.xalan.internal.xsltc.trax;

import java.io.IOException;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.ext.Locator2;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import com.sun.org.apache.xml.internal.serializer.NamespaceMappings;

Author:Santiago Pericas-Geertsen, Sunitha Reddy
/** * @author Santiago Pericas-Geertsen * @author Sunitha Reddy */
public class DOM2TO implements XMLReader, Locator2 { private final static String EMPTYSTRING = ""; private static final String XMLNS_PREFIX = "xmlns";
A reference to the DOM to be traversed.
/** * A reference to the DOM to be traversed. */
private Node _dom;
A reference to the output handler receiving the events.
/** * A reference to the output handler receiving the events. */
private SerializationHandler _handler; private String xmlVersion = null; private String xmlEncoding = null; public DOM2TO(Node root, SerializationHandler handler) { _dom = root; _handler = handler; } public ContentHandler getContentHandler() { return null; } public void setContentHandler(ContentHandler handler) { // Empty } public void parse(InputSource unused) throws IOException, SAXException { parse(_dom); } public void parse() throws IOException, SAXException { if (_dom != null) { boolean isIncomplete = (_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE); if (isIncomplete) { _handler.startDocument(); parse(_dom); _handler.endDocument(); } else { parse(_dom); } } }
Traverse the DOM and generate TO events for a handler. Notice that we need to handle implicit namespace declarations too.
/** * Traverse the DOM and generate TO events for a handler. Notice that * we need to handle implicit namespace declarations too. */
private void parse(Node node) throws IOException, SAXException { if (node == null) return; switch (node.getNodeType()) { case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE case Node.DOCUMENT_TYPE_NODE : case Node.ENTITY_NODE : case Node.ENTITY_REFERENCE_NODE: case Node.NOTATION_NODE : // These node types are ignored!!! break; case Node.CDATA_SECTION_NODE: _handler.startCDATA(); _handler.characters(node.getNodeValue()); _handler.endCDATA(); break; case Node.COMMENT_NODE: // should be handled!!! _handler.comment(node.getNodeValue()); break; case Node.DOCUMENT_NODE: setDocumentInfo((Document)node); _handler.setDocumentLocator(this); _handler.startDocument(); Node next = node.getFirstChild(); while (next != null) { parse(next); next = next.getNextSibling(); } _handler.endDocument(); break; case Node.DOCUMENT_FRAGMENT_NODE: next = node.getFirstChild(); while (next != null) { parse(next); next = next.getNextSibling(); } break; case Node.ELEMENT_NODE: // Generate SAX event to start element final String qname = node.getNodeName(); _handler.startElement(null, null, qname); int colon; String prefix; final NamedNodeMap map = node.getAttributes(); final int length = map.getLength(); // Process all namespace attributes first for (int i = 0; i < length; i++) { final Node attr = map.item(i); final String qnameAttr = attr.getNodeName(); // Is this a namespace declaration? if (qnameAttr.startsWith(XMLNS_PREFIX)) { final String uriAttr = attr.getNodeValue(); colon = qnameAttr.lastIndexOf(':'); prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING; _handler.namespaceAfterStartElement(prefix, uriAttr); } } // Process all non-namespace attributes next NamespaceMappings nm = new NamespaceMappings(); for (int i = 0; i < length; i++) { final Node attr = map.item(i); final String qnameAttr = attr.getNodeName(); // Is this a regular attribute? if (!qnameAttr.startsWith(XMLNS_PREFIX)) { final String uriAttr = attr.getNamespaceURI(); // Uri may be implicitly declared if (uriAttr != null && !uriAttr.equals(EMPTYSTRING) ) { colon = qnameAttr.lastIndexOf(':'); // Fix for bug 26319 // For attributes not given an prefix explictly // but having a namespace uri we need // to explicitly generate the prefix String newPrefix = nm.lookupPrefix(uriAttr); if (newPrefix == null) newPrefix = nm.generateNextPrefix(); prefix = (colon > 0) ? qnameAttr.substring(0, colon) : newPrefix; _handler.namespaceAfterStartElement(prefix, uriAttr); _handler.addAttribute((prefix + ":" + qnameAttr), attr.getNodeValue()); } else { _handler.addAttribute(qnameAttr, attr.getNodeValue()); } } } // Now element namespace and children final String uri = node.getNamespaceURI(); final String localName = node.getLocalName(); // Uri may be implicitly declared if (uri != null) { colon = qname.lastIndexOf(':'); prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING; _handler.namespaceAfterStartElement(prefix, uri); }else { // Fix for bug 26319 // If an element foo is created using // createElementNS(null,locName) // then the element should be serialized // <foo xmlns=" "/> if (uri == null && localName != null) { prefix = EMPTYSTRING; _handler.namespaceAfterStartElement(prefix, EMPTYSTRING); } } // Traverse all child nodes of the element (if any) next = node.getFirstChild(); while (next != null) { parse(next); next = next.getNextSibling(); } // Generate SAX event to close element _handler.endElement(qname); break; case Node.PROCESSING_INSTRUCTION_NODE: _handler.processingInstruction(node.getNodeName(), node.getNodeValue()); break; case Node.TEXT_NODE: _handler.characters(node.getNodeValue()); break; } }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public DTDHandler getDTDHandler() { return null; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public ErrorHandler getErrorHandler() { return null; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return false; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void parse(String sysId) throws IOException, SAXException { throw new IOException("This method is not yet implemented."); }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void setDTDHandler(DTDHandler handler) throws NullPointerException { }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void setEntityResolver(EntityResolver resolver) throws NullPointerException { }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public EntityResolver getEntityResolver() { return null; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void setErrorHandler(ErrorHandler handler) throws NullPointerException { }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return null; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public int getColumnNumber() { return 0; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public int getLineNumber() { return 0; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public String getPublicId() { return null; }
This class is only used internally so this method should never be called.
/** * This class is only used internally so this method should never * be called. */
public String getSystemId() { return null; } private void setDocumentInfo(Document document) { if (!document.getXmlStandalone()) _handler.setStandalone(Boolean.toString(document.getXmlStandalone())); setXMLVersion(document.getXmlVersion()); setEncoding(document.getXmlEncoding()); } public String getXMLVersion() { return xmlVersion; } private void setXMLVersion(String version) { if (version != null) { xmlVersion = version; _handler.setVersion(xmlVersion); } } public String getEncoding() { return xmlEncoding; } private void setEncoding(String encoding) { if (encoding != null) { xmlEncoding = encoding; _handler.setEncoding(encoding); } } // Debugging private String getNodeTypeFromCode(short code) { String retval = null; switch (code) { case Node.ATTRIBUTE_NODE : retval = "ATTRIBUTE_NODE"; break; case Node.CDATA_SECTION_NODE : retval = "CDATA_SECTION_NODE"; break; case Node.COMMENT_NODE : retval = "COMMENT_NODE"; break; case Node.DOCUMENT_FRAGMENT_NODE : retval = "DOCUMENT_FRAGMENT_NODE"; break; case Node.DOCUMENT_NODE : retval = "DOCUMENT_NODE"; break; case Node.DOCUMENT_TYPE_NODE : retval = "DOCUMENT_TYPE_NODE"; break; case Node.ELEMENT_NODE : retval = "ELEMENT_NODE"; break; case Node.ENTITY_NODE : retval = "ENTITY_NODE"; break; case Node.ENTITY_REFERENCE_NODE : retval = "ENTITY_REFERENCE_NODE"; break; case Node.NOTATION_NODE : retval = "NOTATION_NODE"; break; case Node.PROCESSING_INSTRUCTION_NODE : retval = "PROCESSING_INSTRUCTION_NODE"; break; case Node.TEXT_NODE: retval = "TEXT_NODE"; break; } return retval; } }