gianugo 2003/03/03 14:44:10
Modified: src/blocks/html/java/org/apache/cocoon/generation HTMLGenerator.java src/documentation/xdocs/userdocs/generators html-generator.xml . changes.xml Log: Extended the HTMLGenerator so that it can handle HTML snippets provided as request parameter or as POST data, passing them through Tidy to ensure well-formedness. Revision Changes Path 1.6 +89 -24 xml-cocoon2/src/blocks/html/java/org/apache/cocoon/generation/HTMLGenerator.java Index: HTMLGenerator.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/blocks/html/java/org/apache/cocoon/generation/HTMLGenerator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- HTMLGenerator.java 27 Feb 2003 22:25:19 -0000 1.5 +++ HTMLGenerator.java 3 Mar 2003 22:44:10 -0000 1.6 @@ -50,7 +50,22 @@ */ package org.apache.cocoon.generation; -import org.apache.excalibur.xml.xpath.XPathProcessor; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Map; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; @@ -64,44 +79,40 @@ import org.apache.cocoon.caching.CacheableProcessingComponent; import org.apache.cocoon.components.source.SourceUtil; import org.apache.cocoon.components.url.URLFactory; -import org.apache.cocoon.environment.ObjectModelHelper; -import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.environment.URLFactorySourceResolver; +import org.apache.cocoon.environment.http.HttpEnvironment; +import org.apache.cocoon.util.PostInputStream; import org.apache.cocoon.xml.XMLUtils; import org.apache.cocoon.xml.dom.DOMStreamer; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceException; import org.apache.excalibur.source.SourceValidity; +import org.apache.excalibur.xml.xpath.XPathProcessor; import org.w3c.dom.NodeList; import org.w3c.tidy.Tidy; import org.xml.sax.SAXException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Map; -import java.util.Properties; - /** * @author <a href="mailto:[EMAIL PROTECTED]">Davanum Srinivas</a> * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Gianugo Rabellino</a> + * * @version CVS $Id$ */ public class HTMLGenerator extends ComposerGenerator implements Configurable, CacheableProcessingComponent, Disposable { - - /** The source */ + + /** The parameter that specifies what request attribute to use, if any */ + public static final String FORM_NAME = "form-name"; + + /** The source, if coming from a file */ private Source inputSource; - + + /** The source, if coming from the request */ + private InputStream requestStream; + /** XPATH expression */ private String xpath = null; @@ -155,6 +166,7 @@ if (this.inputSource != null) { this.resolver.release( this.inputSource ); this.inputSource = null; + this.requestStream = null; } this.xpath = null; super.recycle(); @@ -168,7 +180,48 @@ throws ProcessingException, SAXException, IOException { super.setup(resolver, objectModel, src, par); - Request request = ObjectModelHelper.getRequest(objectModel); + HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT); + + if (src == null) { + // Handle this request as the StreamGenerator does (from the POST + // request or from a request parameter), but try to make sure + // that the output will be well-formed + + String contentType = request.getContentType(); + + if (contentType == null ) { + throw new IOException("Content-type was not specified for this request"); + } else if (contentType.startsWith("application/x-www-form-urlencoded") || + contentType.startsWith("multipart/form-data")) { + String requested = parameters.getParameter(FORM_NAME, null); + if (requested == null) { + throw new ProcessingException( + "HtmlGenerator with no \"src\" parameter expects a sitemap parameter called '" + + FORM_NAME + "' for handling form data" + ); + } + + String sXml = request.getParameter(requested); + + requestStream = new ByteArrayInputStream(sXml.getBytes()); + + } else if (contentType.startsWith("text/plain") || + contentType.startsWith("text/xml") || + contentType.startsWith("application/xml")) { + + int len = request.getContentLength(); + if (len > 0) { + requestStream = new PostInputStream(request.getInputStream(), len); + } else { + throw new IOException("getContentLen() == 0"); + } + } else { + throw new IOException("Unexpected getContentType(): " + request.getContentType()); + } + + + } + xpath = request.getParameter("xpath"); if(xpath == null) xpath = par.getParameter("xpath",null); @@ -183,7 +236,8 @@ } try { - this.inputSource = resolver.resolveURI(super.source); + if (source != null) + this.inputSource = resolver.resolveURI(super.source); } catch (SourceException se) { throw SourceUtil.handle("Unable to resolve " + super.source, se); } @@ -198,6 +252,9 @@ * is currently not cacheable. */ public java.io.Serializable generateKey() { + if (this.inputSource == null) + return null; + if (this.xpath != null) { StringBuffer buffer = new StringBuffer(this.inputSource.getURI()); buffer.append(':').append(this.xpath); @@ -216,6 +273,8 @@ * component is currently not cacheable. */ public SourceValidity generateValidity() { + if (this.inputSource == null) + return null; return this.inputSource.getValidity(); } @@ -231,7 +290,7 @@ tidy.setXmlOut(true); if (this.properties == null) { - tidy.setXHTML(true); + tidy.setXHTML(true); } else { tidy.setConfigurationFromProps(this.properties); } @@ -246,7 +305,11 @@ tidy.setErrout(errorWriter); // Extract the document using JTidy and stream it. - org.w3c.dom.Document doc = tidy.parseDOM(new BufferedInputStream(this.inputSource.getInputStream()), null); + + if (inputSource != null) + requestStream = this.inputSource.getInputStream(); + + org.w3c.dom.Document doc = tidy.parseDOM(new BufferedInputStream(requestStream), null); // FIXME: Jtidy doesn't warn or strip duplicate attributes in same // tag; stripping. @@ -258,6 +321,7 @@ getLogger().warn(stringWriter.toString()); } + if(xpath != null) { Transformer serializer = TransformerFactory.newInstance().newTransformer(); @@ -285,6 +349,7 @@ throw new ProcessingException("Exception in HTMLGenerator.generate()",e); } } + public void dispose() { if (this.manager != null) { 1.3 +16 -0 xml-cocoon2/src/documentation/xdocs/userdocs/generators/html-generator.xml Index: html-generator.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/src/documentation/xdocs/userdocs/generators/html-generator.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- html-generator.xml 1 Dec 2002 22:11:24 -0000 1.2 +++ html-generator.xml 3 Mar 2003 22:44:10 -0000 1.3 @@ -9,6 +9,7 @@ <authors> <person name="Carsten Ziegeler" email="[EMAIL PROTECTED]"/> <person name="Sylvain Wallez" email="[EMAIL PROTECTED]"/> + <person name="Gianugo Rabellino " email="[EMAIL PROTECTED]"/> </authors> <abstract>This document describes the html generator of Cocoon.</abstract> </header> @@ -33,6 +34,21 @@ <map:generate src="document.html" type="html"/> ]]> </source> + <p>The html generator, however, can operate also on a request + attribute or on a XML POST request. This can be done also by the + <link href="stream-generator.html">stream generator</link>, with whom + it shares the syntax: the added bonus here is that you can + "sanitize" a possibly non well-formed XML snippet for further + reuse later. In order to use this feature for request attributes, + just omit the "src" attribute and set a parameter like the following + one in the sitemap:</p> + +<source> +<![CDATA[ + <map:parameter name="form-name" value="my-request-attribute"/> +]]> +</source> + </s1> <s1 title="Configuring JTidy"> <p>Without any configuration, the generator produces an XHTML document, with the proper namespace. However, 1.361 +6 -1 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.360 retrieving revision 1.361 diff -u -r1.360 -r1.361 --- changes.xml 3 Mar 2003 10:14:08 -0000 1.360 +++ changes.xml 3 Mar 2003 22:44:10 -0000 1.361 @@ -41,6 +41,11 @@ </devs> <release version="@version@" date="@date@"> + <action dev="GR" type="add"> + Extended the HTMLGenerator so that it can handle HTML snippets + provided as request parameter or as POST data, passing them through + Tidy to ensure well-formedness. + </action> <action dev="CZ" type="add"> New caching cinclude transformer. The cinclude transformer can now cache the aggregated content for a distinct period of time. In addition it can