/* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.xml.internal.txw2.output; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMResult; import java.util.ArrayList; import java.util.Stack; import com.sun.xml.internal.txw2.TxwException; /** * {@link XmlSerializer} for {@link javax.xml.transform.dom.DOMResult} and {@link org.w3c.dom.Node}. * * @author Ryan.Shoemaker@Sun.COM */ public class DomSerializer implements XmlSerializer { // delegate to SaxSerializer private final SaxSerializer serializer; public DomSerializer(Node node) { Dom2SaxAdapter adapter = new Dom2SaxAdapter(node); serializer = new SaxSerializer(adapter,adapter,false); } public DomSerializer(DOMResult domResult) { Node node = domResult.getNode(); if (node == null) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); domResult.setNode(doc); serializer = new SaxSerializer(new Dom2SaxAdapter(doc),null,false); } catch (ParserConfigurationException pce) { throw new TxwException(pce); } } else { serializer = new SaxSerializer(new Dom2SaxAdapter(node),null,false); } } // XmlSerializer api's - delegate to SaxSerializer public void startDocument() { serializer.startDocument(); } public void beginStartTag(String uri, String localName, String prefix) { serializer.beginStartTag(uri, localName, prefix); } public void writeAttribute(String uri, String localName, String prefix, StringBuilder value) { serializer.writeAttribute(uri, localName, prefix, value); } public void writeXmlns(String prefix, String uri) { serializer.writeXmlns(prefix, uri); } public void endStartTag(String uri, String localName, String prefix) { serializer.endStartTag(uri, localName, prefix); } public void endTag() { serializer.endTag(); } public void text(StringBuilder text) { serializer.text(text); } public void cdata(StringBuilder text) { serializer.cdata(text); } public void comment(StringBuilder comment) { serializer.comment(comment); } public void endDocument() { serializer.endDocument(); } public void flush() { // no flushing } } /** * Builds a DOM tree from SAX2 events. * * @author Vivek Pandey */ class Dom2SaxAdapter implements ContentHandler, LexicalHandler { private final Node _node; private final Stack _nodeStk = new Stack(); private boolean inCDATA; public final Element getCurrentElement() { return (Element) _nodeStk.peek(); } /** * Document object that owns the specified node. */ private final Document _document; /** * @param node * Nodes will be created and added under this object. */ public Dom2SaxAdapter(Node node) { _node = node; _nodeStk.push(_node); if( node instanceof Document ) this._document = (Document)node; else this._document = node.getOwnerDocument(); } /** * Creates a fresh empty DOM document and adds nodes under this document. */ public Dom2SaxAdapter() throws ParserConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(false); _document = factory.newDocumentBuilder().newDocument(); _node = _document; _nodeStk.push( _document ); } public Node getDOM() { return _node; } public void startDocument() { } public void endDocument(){ } public void startElement(String namespace, String localName, String qName, Attributes attrs){ // some broken DOM implementatino (we confirmed it with SAXON) // return null from this method. Element element = _document.createElementNS(namespace, qName); if( element==null ) { // if so, report an user-friendly error message, // rather than dying mysteriously with NPE. throw new TxwException("Your DOM provider doesn't support the createElementNS method properly"); } // process namespace bindings for( int i=0; i