001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.language.markup;
018:
019: import org.apache.avalon.framework.logger.AbstractLogEnabled;
020:
021: import org.apache.cocoon.ProcessingException;
022: import org.apache.cocoon.components.source.SourceUtil;
023: import org.apache.cocoon.xml.AbstractXMLPipe;
024: import org.apache.cocoon.util.TraxErrorHandler;
025: import org.apache.excalibur.source.Source;
026:
027: import org.xml.sax.ContentHandler;
028: import org.xml.sax.SAXException;
029:
030: import javax.xml.transform.OutputKeys;
031: import javax.xml.transform.TransformerConfigurationException;
032: import javax.xml.transform.TransformerFactory;
033: import javax.xml.transform.sax.SAXResult;
034: import javax.xml.transform.sax.SAXTransformerFactory;
035: import javax.xml.transform.sax.TransformerHandler;
036: import javax.xml.transform.stream.StreamResult;
037: import java.io.StringWriter;
038: import java.util.Properties;
039:
040: /**
041: * A logicsheet-based implementation of <code>MarkupCodeGenerator</code>
042: *
043: * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
044: * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
045: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
046: * @version CVS $Id: LogicsheetCodeGenerator.java 433543 2006-08-22 06:22:54Z crossley $
047: */
048: public class LogicsheetCodeGenerator extends AbstractLogEnabled
049: implements MarkupCodeGenerator {
050:
051: private ContentHandler serializerContentHandler;
052:
053: private AbstractXMLPipe end;
054:
055: private TransformerHandler currentParent;
056:
057: private StringWriter writer;
058:
059: /** The trax TransformerFactory */
060: private SAXTransformerFactory tfactory = null;
061:
062: /**
063: * Initialize the LogicsheetCodeGenerator.
064: */
065: public void initialize() {
066: Properties format = new Properties();
067: try {
068: // Set the serializer which would act as ContentHandler for the last transformer
069: // FIXME (SSA) change a home made content handler, that extract the PCDATA
070: // from the last remaining element
071: TransformerHandler handler = getTransformerFactory()
072: .newTransformerHandler();
073:
074: // Set the output properties
075: format.put(OutputKeys.METHOD, "text");
076: // FIXME (SSA) remove the nice identing. For debug purpose only.
077: format.put(OutputKeys.INDENT, "yes");
078: handler.getTransformer().setOutputProperties(format);
079:
080: this .writer = new StringWriter();
081: handler.setResult(new StreamResult(writer));
082: this .serializerContentHandler = handler;
083: } catch (TransformerConfigurationException tce) {
084: getLogger()
085: .error(
086: "LogicsheetCodeGenerator: unable to get TransformerHandler",
087: tce);
088: }
089: }
090:
091: /**
092: * Helper for TransformerFactory.
093: */
094: private SAXTransformerFactory getTransformerFactory() {
095: if (tfactory == null) {
096: tfactory = (SAXTransformerFactory) TransformerFactory
097: .newInstance();
098: tfactory
099: .setErrorListener(new TraxErrorHandler(getLogger()));
100: }
101: return tfactory;
102: }
103:
104: /**
105: * Add a logicsheet to the logicsheet list
106: *
107: * @param logicsheet The logicsheet to be added
108: */
109: public void addLogicsheet(Logicsheet logicsheet)
110: throws ProcessingException {
111: if (this .currentParent == null) {
112: // Setup the first transformer of the chain.
113: this .currentParent = logicsheet.getTransformerHandler();
114:
115: // the parent is the rootReader
116: this .end.setContentHandler(this .currentParent);
117:
118: // Set content handler for the end of the chain : serializer
119: this .currentParent.setResult(new SAXResult(
120: this .serializerContentHandler));
121: } else {
122: // Build the transformer chain on the fly
123: TransformerHandler newParent = logicsheet
124: .getTransformerHandler();
125:
126: // the currentParent is the parent of the new logicsheet filter
127: this .currentParent.setResult(new SAXResult(newParent));
128:
129: // reset the new parent and the contentHanlder
130: this .currentParent = newParent;
131: this .currentParent.setResult(new SAXResult(
132: this .serializerContentHandler));
133: }
134: }
135:
136: /**
137: * Generate source code from the given source. Filename information is
138: * ignored in the logicsheet-based code generation approach.
139: *
140: * @param source The source of the markup
141: * @return The generated source code
142: * @exception Exception If an error occurs during code generation
143: */
144: public String generateCode(Source source, AbstractXMLPipe filter)
145: throws Exception {
146: try {
147: // set the root XMLReader of the transformer chain
148: this .end = filter;
149: // start the parsing
150: SourceUtil.toSAX(source, filter);
151: return this .writer.toString();
152: } catch (SAXException e) {
153: if (e.getException() != null) {
154: getLogger().debug(
155: "Got SAXException; Rethrowing cause exception",
156: e);
157: throw e.getException();
158: }
159: getLogger().debug("Got SAXException", e);
160: throw e;
161: }
162: }
163: }
|