You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2007/12/19 16:25:04 UTC
svn commit: r605576 -
/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java
Author: vgritsenko
Date: Wed Dec 19 07:25:04 2007
New Revision: 605576
URL: http://svn.apache.org/viewvc?rev=605576&view=rev
Log:
fix javadoc, cleanup implementation
Modified:
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java?rev=605576&r1=605575&r2=605576&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/generation/StreamGenerator.java Wed Dec 19 07:25:04 2007
@@ -35,34 +35,37 @@
import java.io.StringReader;
/**
+ * The <code>StreamGenerator</code> is a class that reads XML from a request
+ * InputStream and generates SAX Events.
+ *
+ * <p>For the POST requests with a mimetype of <code>application/x-www-form-urlencoded</code>
+ * or <code>multipart/form-data<code> the xml data is expected to be associated
+ * with the sitemap parameter <code>form-name</code>.
+ *
+ * <p>For the POST requests with mimetypes <code>text/plain</code>, <code>text/xml</code>,
+ * <code>application/xhtml+xml</code>, <code>application/xml</code> the xml data
+ * is expected to be in the body of the POST request and its length is specified
+ * by the value returned by {@link Request#getContentLength} method.
+ *
+ * <p>The StreamGenerator uses helper {@link PostInputStream} class for InputStream
+ * reading operations. At the time when Parser is reading the data out of the
+ * InputStream, Parser has no knowledge about the length of data to be read.
+ * The only way to signal to the Parser that all data was read from the
+ * InputStream is to control reading operation - by the means of
+ * PostInputStream - and to return to the requestor '-1' when the
+ * number of bytes read is equal to the content length value.
+ *
* @cocoon.sitemap.component.documentation
* The <code>StreamGenerator</code> is a class that reads XML from a
* request InputStream and generates SAX Events.
- *
* @cocoon.sitemap.component.name stream
* @cocoon.sitemap.component.label content
+ * @cocoon.sitemap.component.documentation.caching No
* @cocoon.sitemap.component.pooling.max 16
*
- * For the POST requests with a mimetype of application/x-www-form-urlencoded,
- * or multipart/form-data the xml data is expected to be associated with the
- * sitemap parameter 'form-name'.
- *
- * For the POST requests with mimetypes: text/plain, text/xml,
- * application/xhtml+xml, application/xml the xml data is in the body of the POST request and
- * its length is specified by the value returned by getContentLength()
- * method. The StreamGenerator uses helper
- * org.apache.cocoon.util.PostInputStream class for InputStream
- * reading operations. At the time that Parser is reading the data
- * out of InputStream - Parser has no knowledge about the length of
- * data to be read. The only way to signal to the Parser that all
- * data was read from the InputStream is to control reading operation-
- * PostInputStream--and to return to the requestor '-1' when the
- * number of bytes read is equal to the getContentLength() value.
- *
* @version $Id$
*/
-public class StreamGenerator extends ServiceableGenerator
-{
+public class StreamGenerator extends ServiceableGenerator {
/** The parameter holding the name associated with the xml data **/
public static final String FORM_NAME = "form-name";
@@ -75,8 +78,8 @@
* All instance variables are set to <code>null</code>.
*/
public void recycle() {
- super.recycle();
this.inputSource = null;
+ super.recycle();
}
/**
@@ -86,7 +89,7 @@
throws IOException, SAXException, ProcessingException {
SAXParser parser = null;
int len = 0;
- String contentType = null;
+ String contentType;
Request request = ObjectModelHelper.getRequest(this.objectModel);
try {
@@ -97,57 +100,59 @@
getLogger().debug("no Content-Type header - using contentType parameter: " + contentType);
}
if (contentType == null) {
- throw new IOException("both Content-Type header and defaultContentType parameter are not set");
+ throw new IOException("Both Content-Type header and defaultContentType parameter are not set");
}
}
+
if (contentType.startsWith("application/x-www-form-urlencoded") ||
contentType.startsWith("multipart/form-data")) {
String parameter = parameters.getParameter(FORM_NAME, null);
if (parameter == null) {
- throw new ProcessingException(
- "StreamGenerator expects a sitemap parameter called '" +
- FORM_NAME + "' for handling form data"
- );
+ throw new ProcessingException("StreamGenerator expects a sitemap parameter called '" +
+ FORM_NAME + "' for handling form data");
}
+
Object xmlObject = request.get(parameter);
- Reader xmlReader = null;
+ Reader xmlReader;
if (xmlObject instanceof String) {
- xmlReader = new StringReader((String)xmlObject);
+ xmlReader = new StringReader((String) xmlObject);
} else if (xmlObject instanceof Part) {
- xmlReader = new InputStreamReader(((Part)xmlObject).getInputStream());
+ xmlReader = new InputStreamReader(((Part) xmlObject).getInputStream());
} else {
throw new ProcessingException("Unknown request object encountered named " +
parameter + " : " + xmlObject);
- }
- inputSource = new InputSource(xmlReader);
+ }
+
+ this.inputSource = new InputSource(xmlReader);
} else if (contentType.startsWith("text/plain") ||
contentType.startsWith("text/xml") ||
contentType.startsWith("application/xhtml+xml") ||
contentType.startsWith("application/xml")) {
HttpServletRequest httpRequest = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
- if ( httpRequest == null ) {
+ if (httpRequest == null) {
throw new ProcessingException("This feature is only available in an http environment.");
}
len = request.getContentLength();
- if (len > 0) {
- PostInputStream anStream = new PostInputStream(httpRequest.getInputStream(), len);
- inputSource = new InputSource(anStream);
- } else {
+ if (len <= 0) {
throw new IOException("getContentLen() == 0");
}
+
+ PostInputStream anStream = new PostInputStream(httpRequest.getInputStream(), len);
+ this.inputSource = new InputSource(anStream);
} else {
throw new IOException("Unexpected getContentType(): " + request.getContentType());
}
if (getLogger().isDebugEnabled()) {
- getLogger().debug("processing stream ContentType=" + contentType + " ContentLen=" + len);
+ getLogger().debug("Processing stream ContentType=" + contentType + " ContentLength=" + len);
}
- String charset = getCharacterEncoding(request, contentType) ;
- if( charset != null) {
+ String charset = getCharacterEncoding(request, contentType);
+ if (charset != null) {
this.inputSource.setEncoding(charset);
}
- parser = (SAXParser)this.manager.lookup(SAXParser.ROLE);
+
+ parser = (SAXParser) this.manager.lookup(SAXParser.ROLE);
parser.parse(this.inputSource, super.xmlConsumer);
} catch (IOException e) {
getLogger().error("StreamGenerator.generate()", e);
@@ -159,71 +164,73 @@
getLogger().error("Could not get parser", e);
throw new ProcessingException("Exception in StreamGenerator.generate()", e);
} finally {
- this.manager.release( parser);
+ this.manager.release(parser);
}
}
/**
- * Content type HTTP header can contains character encodinf info
- * for ex. Content-Type: text/xml; charset=UTF-8
- * If the servlet is following spec 2.3 and higher the servlet API can be used to retrieve character encoding part of
- * Content-Type header. Some containers can choose to not unpack charset info - the spec is not strong about it.
- * in any case this method can be used as a latest resource to retrieve the passed charset value.
- * <code>null</code> is returned.
- * It is very common mistake to send : Content-Type: text/xml; charset="UTF-8".
- * Some containers are not filtering this mistake and the processing results in exception..
- * The getCharacterEncoding() compensates for above mistake.
- *
- * @param contentType value associated with Content-Type HTTP header.
- */
+ * Content type HTTP header can contain character encoding information,
+ * for example: <code>Content-Type: text/xml; charset=UTF-8</code>.
+ *
+ * <p>If the servlet is following spec 2.3 and higher, the servlet API can
+ * be used to retrieve character encoding part of Content-Type header. Some
+ * containers can choose to not unpack charset info - the spec is not strong
+ * about it. In any case, this method can be used as a last resort to
+ * retrieve the passed charset value.
+ *
+ * <p>It is very common mistake to send : <code>Content-Type: text/xml; charset="UTF-8"</code>.
+ * Some containers are not filtering this mistake and the processing results in exception.
+ * This method compensates for the above mistake.
+ *
+ * <p>If contentType is null or has no charset part, <code>null</code> is returned.
+ *
+ * @param contentType value associated with Content-Type HTTP header.
+ */
public String getCharacterEncoding(Request req, String contentType) {
- String charencoding = null;
- String charset = "charset=";
if (contentType == null) {
return null;
}
- int idx = contentType.indexOf(charset);
+
+ int idx = contentType.indexOf("charset=");
if (idx == -1) {
return null;
}
- try {
- charencoding = req.getCharacterEncoding();
- if ( charencoding != null) {
- getLogger().debug("charset from container: " + charencoding);
- charencoding = charencoding.trim();
- if ((charencoding.length() > 2) && (charencoding.startsWith("\""))&& (charencoding.endsWith("\""))) {
- charencoding = charencoding.substring(1, charencoding.length() - 1);
+ String encoding;
+ try {
+ encoding = req.getCharacterEncoding();
+ if (encoding != null) {
+ encoding = cleanup(encoding);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Using charset from container: " + encoding);
}
- getLogger().debug("charset from container clean: " + charencoding);
- return charencoding;
- } else {
- return extractCharset( contentType, idx );
+
+ return encoding;
}
- } catch(Throwable e) {
- // We will be there if the container do not implement getCharacterEncoding() method
- return extractCharset( contentType, idx );
+ } catch (Throwable e) {
+ // We will be there if the container did not implement getCharacterEncoding() method
}
- }
-
- protected String extractCharset(String contentType, int idx) {
- String charencoding = null;
- String charset = "charset=";
-
- getLogger().debug("charset from extractCharset");
- charencoding = contentType.substring(idx + charset.length());
- int idxEnd = charencoding.indexOf(";");
+ encoding = contentType.substring(idx + "charset=".length());
+ int idxEnd = encoding.indexOf(";");
if (idxEnd != -1) {
- charencoding = charencoding.substring(0, idxEnd);
+ encoding = encoding.substring(0, idxEnd);
}
- charencoding = charencoding.trim();
- if ((charencoding.length() > 2) && (charencoding.startsWith("\""))&& (charencoding.endsWith("\""))) {
- charencoding = charencoding.substring(1, charencoding.length() - 1);
+
+ encoding = cleanup(encoding);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Using charset from header: " + encoding);
}
- getLogger().debug("charset from extractCharset: " + charencoding);
- return charencoding.trim();
+ return encoding;
}
-}
+ private String cleanup(String encoding) {
+ encoding = encoding.trim();
+ if (encoding.length() > 2 && encoding.startsWith("\"") && encoding.endsWith("\"")) {
+ encoding = encoding.substring(1, encoding.length() - 1);
+ }
+
+ return encoding;
+ }
+}