- /*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * $Id: DOM2TO.java,v 1.9 2004/02/20 19:30:40 bhakti Exp $
- */
-
- package com.sun.org.apache.xalan.internal.xsltc.trax;
-
- import java.io.IOException;
-
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Node;
- 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.Locator;
- 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
- */
- public class DOM2TO implements XMLReader, Locator {
-
- private final static String EMPTYSTRING = "";
- private static final String XMLNS_PREFIX = "xmlns";
-
- /**
- * A reference to the DOM to be traversed.
- */
- private Node _dom;
-
- /**
- * A reference to the output handler receiving the events.
- */
- private SerializationHandler _handler;
-
- 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.
- */
- 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:
- _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);
-
- String prefix;
- final NamedNodeMap map = node.getAttributes();
- final int length = map.getLength();
-
- // Process all other attributes
- NamespaceMappings nm = new NamespaceMappings();
- for (int i = 0; i < length; i++) {
- int colon;
- final Node attr = map.item(i);
- final String qnameAttr = attr.getNodeName();
-
- 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);
- }
- else {
- 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) {
- final int 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.
- */
- public DTDHandler getDTDHandler() {
- return null;
- }
-
- /**
- * 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.
- */
- public boolean getFeature(String name) throws SAXNotRecognizedException,
- SAXNotSupportedException
- {
- return false;
- }
-
- /**
- * 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.
- */
- 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.
- */
- public void setDTDHandler(DTDHandler handler) throws NullPointerException {
- }
-
- /**
- * 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.
- */
- public EntityResolver getEntityResolver() {
- return null;
- }
-
- /**
- * 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.
- */
- public void setProperty(String name, Object value) throws
- SAXNotRecognizedException, SAXNotSupportedException {
- }
-
- /**
- * 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.
- */
- public int getColumnNumber() {
- return 0;
- }
-
- /**
- * 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.
- */
- public String getPublicId() {
- return null;
- }
-
- /**
- * This class is only used internally so this method should never
- * be called.
- */
- public String getSystemId() {
- return null;
- }
-
- // 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;
- }
- }