/* * 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 org.apache.cocoon.xml; import org.apache.avalon.framework.logger.Logger; import org.xml.sax.Attributes; import org.xml.sax.DocumentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributeListImpl; import java.util.Vector; /** * This class is an utility class "wrapping" around a SAX version 1.0 * <code>DocumentHandler</code> and forwarding it those events received throug * its <code>XMLConsumers</code> interface. * <br> * This class fully supports XML namespaces, converting * <code>startPrefixMapping(...)</code> and <code>endPrefixMapping(...)</code> * calls into appropriate <code>xmlns</code> and <code>xmlns:...</code> element * attributes. * * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a> * (Apache Software Foundation) * @version CVS $Id$ */ public class DocumentHandlerWrapper extends AbstractXMLConsumer { protected Logger log; /** The current namespaces table. */ private NamespacesTable namespaces=new NamespacesTable(); /** The vector of namespaces declarations to include in the next element. */ private Vector undecl=new Vector(); /** The current <code>DocumentHandler</code>. */ protected DocumentHandler documentHandler=null; /** * Create a new <code>DocumentHandlerWrapper</code> instance. */ public DocumentHandlerWrapper() { super(); } /** * Create a new <code>DocumentHandlerWrapper</code> instance. */ public DocumentHandlerWrapper(DocumentHandler document) { this(); this.setDocumentHandler(document); } /** * Provide component with a logger. * * @param logger the logger */ public void enableLogging(Logger logger) { if (this.log == null) { this.log = logger; } } /** * Implementation of the recycle method */ public void recycle() { this.documentHandler = null; } /** * Set the <code>DocumentHandler</code> that will receive XML data. * * @exception IllegalStateException If the <code>DocumentHandler</code> * was already set. */ public void setDocumentHandler(DocumentHandler document) throws IllegalStateException { if (this.documentHandler!=null) throw new IllegalStateException(); this.documentHandler=document; } /** * Receive an object for locating the origin of SAX document events. */ public void setDocumentLocator (Locator locator) { if (this.documentHandler==null) return; else this.documentHandler.setDocumentLocator(locator); } /** * Receive notification of the beginning of a document. */ public void startDocument () throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); this.documentHandler.startDocument(); } /** * Receive notification of the end of a document. */ public void endDocument () throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); this.documentHandler.endDocument(); } /** * Begin the scope of a prefix-URI Namespace mapping. */ public void startPrefixMapping(String prefix, String uri) throws SAXException { this.undecl.addElement(this.namespaces.addDeclaration(prefix,uri)); } /** * End the scope of a prefix-URI mapping. */ public void endPrefixMapping(String prefix) throws SAXException { if (namespaces.removeDeclaration(prefix)==null) throw new SAXException("Namespace prefix \""+prefix+ "\" never declared"); } /** * Receive notification of the beginning of an element. */ public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); NamespacesTable.Name name=this.namespaces.resolve(uri,raw,null,loc); // Create the AttributeList AttributeListImpl a2=new AttributeListImpl(); // Set the xmlns:...="..." attributes if (this.undecl.size()>0) { for (int x=0; x<this.undecl.size(); x++) { NamespacesTable.Declaration dec=null; dec=(NamespacesTable.Declaration)this.undecl.elementAt(x); String aname="xmlns"; if (dec.getPrefix().length()>0) aname="xmlns:"+dec.getPrefix(); a2.addAttribute(aname,"CDATA",dec.getUri()); } this.undecl.clear(); } // Set the real attributes for (int x=0; x<a.getLength(); x++) { NamespacesTable.Name aname=namespaces.resolve(a.getURI(x), a.getQName(x), null, a.getLocalName(x)); a2.addAttribute(aname.getQName(),a.getType(x),a.getValue(x)); } // Call the document handler startElement() method. this.documentHandler.startElement(name.getQName(),a2); } /** * Receive notification of the end of an element. */ public void endElement(String uri, String loc, String raw) throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); NamespacesTable.Name name=this.namespaces.resolve(uri,raw,null,loc); this.documentHandler.endElement(name.getQName()); } /** * Receive notification of character data. */ public void characters(char ch[], int start, int len) throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); this.documentHandler.characters(ch,start,len); } /** * Receive notification of ignorable whitespace in element content. */ public void ignorableWhitespace(char ch[], int start, int len) throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); this.documentHandler.ignorableWhitespace(ch,start,len); } /** * Receive notification of a processing instruction. */ public void processingInstruction(String target, String data) throws SAXException { if (this.documentHandler==null) throw new SAXException("DocumentHandler not set"); this.documentHandler.processingInstruction(target,data); } }