FileDocCategorySizeDatePackage
DOM2SAX.javaAPI DocJava SE 5 API12790Fri Aug 26 14:55:40 BST 2005com.sun.org.apache.xalan.internal.xsltc.trax

DOM2SAX

public class DOM2SAX extends Object implements Locator, XMLReader
author
G. Todd Miller

Fields Summary
private static final String
EMPTYSTRING
private static final String
XMLNS_PREFIX
private Node
_dom
private ContentHandler
_sax
private LexicalHandler
_lex
private SAXImpl
_saxImpl
private Hashtable
_nsPrefixes
Constructors Summary
public DOM2SAX(Node root)


       
	_dom = root;
    
Methods Summary
private voidendPrefixMapping(java.lang.String prefix)

	final Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    _sax.endPrefixMapping(prefix);
	    uriStack.pop();
	}
    
public intgetColumnNumber()
This class is only used internally so this method should never be called.

 
	return 0; 
    
public org.xml.sax.ContentHandlergetContentHandler()

 
	return _sax;
    
public org.xml.sax.DTDHandlergetDTDHandler()
This class is only used internally so this method should never be called.

 
	return null;
    
public org.xml.sax.EntityResolvergetEntityResolver()
This class is only used internally so this method should never be called.

	return null;
    
public org.xml.sax.ErrorHandlergetErrorHandler()
This class is only used internally so this method should never be called.

	return null;
    
public booleangetFeature(java.lang.String name)
This class is only used internally so this method should never be called.

	return false;
    
public intgetLineNumber()
This class is only used internally so this method should never be called.

 
	return 0; 
    
private static java.lang.StringgetLocalName(org.w3c.dom.Node node)
If the DOM was created using a DOM 1.0 API, the local name may be null. If so, get the local name from the qualified name before generating the SAX event.

	final String localName = node.getLocalName();

	if (localName == null) {
	    final String qname = node.getNodeName();
	    final int col = qname.lastIndexOf(':");
	    return (col > 0) ? qname.substring(col + 1) : qname;
	}
	return localName;
    
private java.lang.StringgetNodeTypeFromCode(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;
    
public java.lang.ObjectgetProperty(java.lang.String name)
This class is only used internally so this method should never be called.

	return null;
    
public java.lang.StringgetPublicId()
This class is only used internally so this method should never be called.

 
	return null; 
    
public java.lang.StringgetSystemId()
This class is only used internally so this method should never be called.

 
	return null; 
    
public voidparse(java.lang.String sysId)
This class is only used internally so this method should never be called.

	throw new IOException("This method is not yet implemented.");
    
public voidparse(org.xml.sax.InputSource unused)

        parse(_dom);
    
public voidparse()

	if (_dom != null) {
	    boolean isIncomplete = 
		(_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);

	    if (isIncomplete) {
		_sax.startDocument();
		parse(_dom);
		_sax.endDocument();
	    }
	    else {
		parse(_dom);
	    }
	}
    
private voidparse(org.w3c.dom.Node node)
Traverse the DOM and generate SAX events for a handler. A startElement() event passes all attributes, including namespace declarations.

        Node first = null;
 	if (node == null) return;

        switch (node.getNodeType()) {
	case Node.ATTRIBUTE_NODE:         // handled by ELEMENT_NODE
	case Node.DOCUMENT_FRAGMENT_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:
	    final String cdata = node.getNodeValue();
	    if (_lex != null) {
		_lex.startCDATA();
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
		_lex.endCDATA();
 	    } 
	    else {
		// in the case where there is no lex handler, we still
		// want the text of the cdate to make its way through.
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
	    }	
	    break;

	case Node.COMMENT_NODE:           // should be handled!!!
	    if (_lex != null) {
		final String value = node.getNodeValue();
		_lex.comment(value.toCharArray(), 0, value.length());
	    }
	    break;
	case Node.DOCUMENT_NODE:
	    _sax.setDocumentLocator(this);

	    _sax.startDocument();
	    Node next = node.getFirstChild();
	    while (next != null) {
		parse(next);
		next = next.getNextSibling();
	    }
	    _sax.endDocument();
	    break;

	case Node.ELEMENT_NODE:
	    String prefix;
	    Vector pushedPrefixes = new Vector();
	    final AttributesImpl attrs = new AttributesImpl();
	    final NamedNodeMap map = node.getAttributes();
	    final int length = map.getLength();

	    // Process all namespace declarations
	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		// Ignore everything but NS declarations here
		if (qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNodeValue();
		    final int colon = qnameAttr.lastIndexOf(':");
		    prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
		    if (startPrefixMapping(prefix, uriAttr)) {
			pushedPrefixes.addElement(prefix);
		    }
		}
	    }

	    // Process all other attributes
	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		// Ignore NS declarations here
		if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNamespaceURI();
		    final String localNameAttr = getLocalName(attr);

		    // Uri may be implicitly declared
		    if (uriAttr != null) {	
			final int colon = qnameAttr.lastIndexOf(':");
			prefix = (colon > 0) ? qnameAttr.substring(0, colon) : EMPTYSTRING;
			if (startPrefixMapping(prefix, uriAttr)) {
			    pushedPrefixes.addElement(prefix);
			}
		    }

		    // Add attribute to list
		    attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr), 
			qnameAttr, "CDATA", attr.getNodeValue());
		}
	    }

	    // Now process the element itself
	    final String qname = node.getNodeName();
	    final String uri = node.getNamespaceURI();
	    final String localName = getLocalName(node);

	    // Uri may be implicitly declared
	    if (uri != null) {	
		final int colon = qname.lastIndexOf(':");
		prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
		if (startPrefixMapping(prefix, uri)) {
		    pushedPrefixes.addElement(prefix);
		}
	    }

	    // Generate SAX event to start element
	    if (_saxImpl != null) {
	        _saxImpl.startElement(uri, localName, qname, attrs, node);
	    }
	    else {
	        _sax.startElement(uri, localName, qname, attrs);
	    }

	    // 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
	    _sax.endElement(uri, localName, qname);

	    // Generate endPrefixMapping() for all pushed prefixes
	    final int nPushedPrefixes = pushedPrefixes.size();
	    for (int i = 0; i < nPushedPrefixes; i++) {
		endPrefixMapping((String) pushedPrefixes.elementAt(i));
	    }
	    break;

	case Node.PROCESSING_INSTRUCTION_NODE:
	    _sax.processingInstruction(node.getNodeName(),
				       node.getNodeValue());
	    break;

	case Node.TEXT_NODE:
	    final String data = node.getNodeValue();
	    _sax.characters(data.toCharArray(), 0, data.length());
	    break;
	}
    
public voidsetContentHandler(org.xml.sax.ContentHandler handler)

	_sax = handler;
	if (handler instanceof LexicalHandler) {
	    _lex = (LexicalHandler) handler;
	}
	
	if (handler instanceof SAXImpl) {
	    _saxImpl = (SAXImpl)handler;
	}
    
public voidsetDTDHandler(org.xml.sax.DTDHandler handler)
This class is only used internally so this method should never be called.

    
public voidsetEntityResolver(org.xml.sax.EntityResolver resolver)
This class is only used internally so this method should never be called.

    
public voidsetErrorHandler(org.xml.sax.ErrorHandler handler)
This class is only used internally so this method should never be called.

    
public voidsetFeature(java.lang.String name, boolean value)
This class is only used internally so this method should never be called.

    
public voidsetProperty(java.lang.String name, java.lang.Object value)
This class is only used internally so this method should never be called.

    
private booleanstartPrefixMapping(java.lang.String prefix, java.lang.String uri)
Begin the scope of namespace prefix. Forward the event to the SAX handler only if the prefix is unknown or it is mapped to a different URI.

	boolean pushed = true;
	Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    if (uriStack.isEmpty()) {
		_sax.startPrefixMapping(prefix, uri);
		uriStack.push(uri);
	    }
	    else {
		final String lastUri = (String) uriStack.peek();
		if (!lastUri.equals(uri)) {
		    _sax.startPrefixMapping(prefix, uri);
		    uriStack.push(uri);
		}
		else {
		    pushed = false;
		}
	    }	
	}
	else {
	    _sax.startPrefixMapping(prefix, uri);
	    _nsPrefixes.put(prefix, uriStack = new Stack());
	    uriStack.push(uri);
	}
	return pushed;