| /* |
| * Copyright 1999-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. |
| */ |
| package org.apache.cocoon.components.language.markup; |
| |
| import org.apache.avalon.framework.logger.AbstractLogEnabled; |
| |
| import org.apache.cocoon.ProcessingException; |
| import org.apache.cocoon.components.source.SourceUtil; |
| import org.apache.cocoon.xml.AbstractXMLPipe; |
| import org.apache.cocoon.util.TraxErrorHandler; |
| import org.apache.excalibur.source.Source; |
| |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.sax.SAXResult; |
| import javax.xml.transform.sax.SAXTransformerFactory; |
| import javax.xml.transform.sax.TransformerHandler; |
| import javax.xml.transform.stream.StreamResult; |
| import java.io.StringWriter; |
| import java.util.Properties; |
| |
| /** |
| * A logicsheet-based implementation of <code>MarkupCodeGenerator</code> |
| * |
| * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a> |
| * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> |
| * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a> |
| * @version CVS $Id: LogicsheetCodeGenerator.java,v 1.3 2004/03/05 13:02:47 bdelacretaz Exp $ |
| */ |
| public class LogicsheetCodeGenerator extends AbstractLogEnabled implements MarkupCodeGenerator { |
| |
| private ContentHandler serializerContentHandler; |
| |
| private AbstractXMLPipe end; |
| |
| private TransformerHandler currentParent; |
| |
| private StringWriter writer; |
| |
| /** The trax TransformerFactory */ |
| private SAXTransformerFactory tfactory = null; |
| |
| /** |
| * Initialize the LogicsheetCodeGenerator. |
| */ |
| public void initialize() { |
| Properties format = new Properties(); |
| try { |
| // Set the serializer which would act as ContentHandler for the last transformer |
| // FIXME (SSA) change a home made content handler, that extract the PCDATA |
| // from the last remaining element |
| TransformerHandler handler = getTransformerFactory().newTransformerHandler(); |
| |
| // Set the output properties |
| format.put(OutputKeys.METHOD,"text"); |
| // FIXME (SSA) remove the nice identing. For debug purpose only. |
| format.put(OutputKeys.INDENT,"yes"); |
| handler.getTransformer().setOutputProperties(format); |
| |
| this.writer = new StringWriter(); |
| handler.setResult(new StreamResult(writer)); |
| this.serializerContentHandler = handler; |
| } catch (TransformerConfigurationException tce) { |
| getLogger().error("LogicsheetCodeGenerator: unable to get TransformerHandler", tce); |
| } |
| } |
| |
| /** |
| * Helper for TransformerFactory. |
| */ |
| private SAXTransformerFactory getTransformerFactory() |
| { |
| if(tfactory == null) { |
| tfactory = (SAXTransformerFactory) TransformerFactory.newInstance(); |
| tfactory.setErrorListener(new TraxErrorHandler(getLogger())); |
| } |
| return tfactory; |
| } |
| |
| /** |
| * Add a logicsheet to the logicsheet list |
| * |
| * @param logicsheet The logicsheet to be added |
| */ |
| public void addLogicsheet(Logicsheet logicsheet) throws ProcessingException { |
| if (this.currentParent == null) { |
| // Setup the first transformer of the chain. |
| this.currentParent = logicsheet.getTransformerHandler(); |
| |
| // the parent is the rootReader |
| this.end.setContentHandler(this.currentParent); |
| |
| // Set content handler for the end of the chain : serializer |
| this.currentParent.setResult(new SAXResult(this.serializerContentHandler)); |
| } else { |
| // Build the transformer chain on the fly |
| TransformerHandler newParent = logicsheet.getTransformerHandler(); |
| |
| // the currentParent is the parent of the new logicsheet filter |
| this.currentParent.setResult(new SAXResult(newParent)); |
| |
| // reset the new parent and the contentHanlder |
| this.currentParent = newParent; |
| this.currentParent.setResult(new SAXResult(this.serializerContentHandler)); |
| } |
| } |
| |
| /** |
| * Generate source code from the given source. Filename information is |
| * ignored in the logicsheet-based code generation approach. |
| * |
| * @param source The source of the markup |
| * @return The generated source code |
| * @exception Exception If an error occurs during code generation |
| */ |
| public String generateCode(Source source, AbstractXMLPipe filter) |
| throws Exception { |
| try { |
| // set the root XMLReader of the transformer chain |
| this.end = filter; |
| // start the parsing |
| SourceUtil.toSAX(source, filter); |
| return this.writer.toString(); |
| } catch (SAXException e) { |
| if(e.getException() != null) { |
| getLogger().debug("Got SAXException; Rethrowing cause exception", e); |
| throw e.getException(); |
| } |
| getLogger().debug("Got SAXException", e); |
| throw e; |
| } |
| } |
| } |