/* * Copyright 2006 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$ */ package org.apache.fop.util; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * ContentHandlerFactory which constructs ContentHandlers that build DOM Documents. */ public class DOMBuilderContentHandlerFactory implements ContentHandlerFactory { private static SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); private String namespaceURI; private DOMImplementation domImplementation; /** * Main Constructor * @param namespaceURI the main namespace URI for the DOM to be parsed * @param domImplementation the DOMImplementation to use for build the DOM */ public DOMBuilderContentHandlerFactory(String namespaceURI, DOMImplementation domImplementation) { this.namespaceURI = namespaceURI; this.domImplementation = domImplementation; } /** @see org.apache.fop.util.ContentHandlerFactory#getSupportedNamespaces() */ public String[] getSupportedNamespaces() { return new String[] {namespaceURI}; } /** @see org.apache.fop.util.ContentHandlerFactory#createContentHandler() */ public ContentHandler createContentHandler() throws SAXException { return new Handler(); } private class Handler extends DelegatingContentHandler implements ContentHandlerFactory.ObjectSource { private Document doc; private ObjectBuiltListener obListener; public Handler() throws SAXException { super(); } public Document getDocument() { return this.doc; } /** * @see org.apache.fop.util.ContentHandlerFactory.ObjectSource#getObject() */ public Object getObject() { return getDocument(); } /** * @see org.apache.fop.util.ContentHandlerFactory.ObjectSource */ public void setObjectBuiltListener(ObjectBuiltListener listener) { this.obListener = listener; } /** * @see org.apache.fop.util.DelegatingContentHandler#startDocument() */ public void startDocument() throws SAXException { //Suppress startDocument() call if doc has not been set, yet. It will be done later. if (doc != null) { super.startDocument(); } } /** * @see org.apache.fop.util.DelegatingContentHandler */ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if (doc == null) { TransformerHandler handler; try { handler = tFactory.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new SAXException("Error creating a new TransformerHandler", e); } doc = domImplementation.createDocument(namespaceURI, qName, null); //It's easier to work with an empty document, so remove the root element doc.removeChild(doc.getDocumentElement()); handler.setResult(new DOMResult(doc)); setDelegateContentHandler(handler); setDelegateLexicalHandler(handler); setDelegateDTDHandler(handler); handler.startDocument(); } super.startElement(uri, localName, qName, atts); } /** * @see org.apache.fop.util.DelegatingContentHandler#endDocument() */ public void endDocument() throws SAXException { super.endDocument(); if (obListener != null) { obListener.notifyObjectBuilt(getObject()); } } } }