Author: adrianc
Date: Tue Dec 11 22:38:23 2007
New Revision: 603483
URL: http://svn.apache.org/viewvc?rev=603483&view=rev
Log:
FOP code improvements, based on
https://issues.apache.org/jira/browse/OFBIZ-1414.
The Jira issue mentions rendering to temp files, but I kept that out of the
commit. If we get out of memory errors in the future, it will be easy to add it
back in.
Added:
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopWorker.java
Modified:
ofbiz/trunk/applications/content/src/org/ofbiz/content/email/EmailServices.java
ofbiz/trunk/applications/content/src/org/ofbiz/content/output/OutputServices.java
ofbiz/trunk/framework/example/src/org/ofbiz/example/ExamplePrintServices.java
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopFactory.java
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/FopPdfViewHandler.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
Modified:
ofbiz/trunk/applications/content/src/org/ofbiz/content/email/EmailServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/content/src/org/ofbiz/content/email/EmailServices.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/applications/content/src/org/ofbiz/content/email/EmailServices.java
(original)
+++
ofbiz/trunk/applications/content/src/org/ofbiz/content/email/EmailServices.java
Tue Dec 11 22:38:23 2007
@@ -36,7 +36,7 @@
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.mail.MimeMessageWrapper;
-import org.ofbiz.webapp.view.ApacheFopFactory;
+import org.ofbiz.webapp.view.ApacheFopWorker;
import org.ofbiz.widget.html.HtmlScreenRenderer;
import org.ofbiz.widget.screen.ScreenRenderer;
import org.xml.sax.SAXException;
@@ -355,27 +355,19 @@
}
*/
- // create the in/output stream for the generation
+ // create the input stream for the generation
+ StreamSource src = new StreamSource(new
StringReader(writer.toString()));
+
+ // create the output stream for the generation
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- FopFactory fopFactory = ApacheFopFactory.instance();
- Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, baos);
- TransformerFactory transFactory =
TransformerFactory.newInstance();
- Transformer transformer = transFactory.newTransformer();
-
- Reader reader = new StringReader(writer.toString());
- Source src = new StreamSource(reader);
- Result res = new SAXResult(fop.getDefaultHandler());
-
- // Start XSLT transformation and FOP processing
- transformer.transform(src, res);
+ Fop fop = ApacheFopWorker.createFopInstance(baos,
MimeConstants.MIME_PDF);
+ ApacheFopWorker.transform(src, null, fop);
+
// and generate the PDF
baos.flush();
baos.close();
- // We don't want to cache the images that get loaded by the
FOP engine
- fopFactory.getImageFactory().clearCaches();
-
// store in the list of maps for sendmail....
List bodyParts = FastList.newInstance();
if (bodyText != null) {
@@ -397,12 +389,6 @@
} catch (FOPException fe) {
String errMsg = "Error rendering PDF attachment for email: " +
fe.toString();
Debug.logError(fe, errMsg, module);
- return ServiceUtil.returnError(errMsg);
- } catch (TransformerConfigurationException tce) {
- String errMsg = "FOP TransformerConfiguration Exception: " +
tce.toString();
- return ServiceUtil.returnError(errMsg);
- } catch (TransformerException te) {
- String errMsg = "FOP transform failed: " + te.toString();
return ServiceUtil.returnError(errMsg);
} catch (SAXException se) {
String errMsg = "Error rendering PDF attachment for email: " +
se.toString();
Modified:
ofbiz/trunk/applications/content/src/org/ofbiz/content/output/OutputServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/content/src/org/ofbiz/content/output/OutputServices.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/applications/content/src/org/ofbiz/content/output/OutputServices.java
(original)
+++
ofbiz/trunk/applications/content/src/org/ofbiz/content/output/OutputServices.java
Tue Dec 11 22:38:23 2007
@@ -31,7 +31,7 @@
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.webapp.view.ApacheFopFactory;
+import org.ofbiz.webapp.view.ApacheFopWorker;
import org.ofbiz.widget.fo.FoFormRenderer;
import org.ofbiz.widget.html.HtmlScreenRenderer;
import org.ofbiz.widget.screen.ScreenRenderer;
@@ -126,27 +126,18 @@
screensAtt.getContext().put("formStringRenderer", foFormRenderer);
screensAtt.render(screenLocation);
- // create the in/output stream for the generation
+ // create the input stream for the generation
+ StreamSource src = new StreamSource(new
StringReader(writer.toString()));
+
+ // create the output stream for the generation
ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ Fop fop = ApacheFopWorker.createFopInstance(baos,
MimeConstants.MIME_PDF);
+ ApacheFopWorker.transform(src, null, fop);
- FopFactory fopFactory = ApacheFopFactory.instance();
- Fop fop = fopFactory.newFop(contentType, baos);
- TransformerFactory transFactory = TransformerFactory.newInstance();
- Transformer transformer = transFactory.newTransformer();
-
- Reader reader = new StringReader(writer.toString());
- Source src = new StreamSource(reader);
- Result res = new SAXResult(fop.getDefaultHandler());
-
- // Start XSLT transformation and FOP processing
- transformer.transform(src, res);
- // and generate the stream
baos.flush();
baos.close();
- // We don't want to cache the images that get loaded by the FOP
engine
- fopFactory.getImageFactory().clearCaches();
-
// Print is sent
DocFlavor psInFormat = new
DocFlavor.INPUT_STREAM(printerContentType);
InputStream bais = new ByteArrayInputStream(baos.toByteArray());
@@ -209,12 +200,6 @@
String errMsg = "Error rendering [" + contentType + "]: " +
fe.toString();
Debug.logError(fe, errMsg, module);
return ServiceUtil.returnError(errMsg);
- } catch (TransformerConfigurationException tce) {
- String errMsg = "FOP TransformerConfiguration Exception: " +
tce.toString();
- return ServiceUtil.returnError(errMsg);
- } catch (TransformerException te) {
- String errMsg = "FOP transform failed: " + te.toString();
- return ServiceUtil.returnError(errMsg);
} catch (SAXException se) {
String errMsg = "Error rendering [" + contentType + "]: " +
se.toString();
Debug.logError(se, errMsg, module);
@@ -258,27 +243,18 @@
screensAtt.getContext().put("formStringRenderer", foFormRenderer);
screensAtt.render(screenLocation);
- // create the in/output stream for the generation
+ // create the input stream for the generation
+ StreamSource src = new StreamSource(new
StringReader(writer.toString()));
+
+ // create the output stream for the generation
ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ Fop fop = ApacheFopWorker.createFopInstance(baos,
MimeConstants.MIME_PDF);
+ ApacheFopWorker.transform(src, null, fop);
- FopFactory fopFactory = ApacheFopFactory.instance();
- Fop fop = fopFactory.newFop(contentType, baos);
- TransformerFactory transFactory = TransformerFactory.newInstance();
- Transformer transformer = transFactory.newTransformer();
-
- Reader reader = new StringReader(writer.toString());
- Source src = new StreamSource(reader);
- Result res = new SAXResult(fop.getDefaultHandler());
-
- // Start XSLT transformation and FOP processing
- transformer.transform(src, res);
- // and generate the stream
baos.flush();
baos.close();
- // We don't want to cache the images that get loaded by the FOP
engine
- fopFactory.getImageFactory().clearCaches();
-
fileName += UtilDateTime.nowAsString();
if ("application/pdf".equals(contentType)) {
fileName += ".pdf";
@@ -307,12 +283,6 @@
} catch (FOPException fe) {
String errMsg = "Error rendering [" + contentType + "]: " +
fe.toString();
Debug.logError(fe, errMsg, module);
- return ServiceUtil.returnError(errMsg);
- } catch (TransformerConfigurationException tce) {
- String errMsg = "FOP TransformerConfiguration Exception: " +
tce.toString();
- return ServiceUtil.returnError(errMsg);
- } catch (TransformerException te) {
- String errMsg = "FOP transform failed: " + te.toString();
return ServiceUtil.returnError(errMsg);
} catch (SAXException se) {
String errMsg = "Error rendering [" + contentType + "]: " +
se.toString();
Modified:
ofbiz/trunk/framework/example/src/org/ofbiz/example/ExamplePrintServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/src/org/ofbiz/example/ExamplePrintServices.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/framework/example/src/org/ofbiz/example/ExamplePrintServices.java
(original)
+++
ofbiz/trunk/framework/example/src/org/ofbiz/example/ExamplePrintServices.java
Tue Dec 11 22:38:23 2007
@@ -20,13 +20,12 @@
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Fop;
-import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.webapp.view.ApacheFopFactory;
+import org.ofbiz.webapp.view.ApacheFopWorker;
import org.ofbiz.widget.html.HtmlScreenRenderer;
import org.ofbiz.widget.screen.ScreenRenderer;
import org.xml.sax.SAXException;
@@ -51,14 +50,6 @@
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Sides;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
public class ExamplePrintServices {
@@ -98,46 +89,16 @@
return ServiceUtil.returnError(errMsg);
}
- String reportXmlDocument = reportWriter.toString();
+ // set the input source (XSL-FO) and generate the PDF
+ StreamSource src = new StreamSource(new
StringReader(reportWriter.toString()));
- // create the in/output stream for the generation
+ // create the output stream for the generation
ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-
- FopFactory fopFactory;
+
try {
- fopFactory = ApacheFopFactory.instance();
- Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
- TransformerFactory transFactory = TransformerFactory.newInstance();
- Transformer transformer = transFactory.newTransformer();
-
- // set the input source (XSL-FO) and generate the PDF
- Reader reader = new StringReader(reportXmlDocument);
- Source src = new StreamSource(reader);
-
- // load the FOP driver
-
- // Get handler that is used in the generation process
- Result res = new SAXResult(fop.getDefaultHandler());
-
- // read the XSL-FO XML into the W3 Document
-
- // Start XSLT transformation and FOP processing
- transformer.transform(src, res);
- // and generate the PDF
- // We don't want to cache the images that get loaded by the FOP
engine
- fopFactory.getImageFactory().clearCaches();
-
+ Fop fop = ApacheFopWorker.createFopInstance(out,
MimeConstants.MIME_PDF);
+ ApacheFopWorker.transform(src, null, fop);
} catch (FOPException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (TransformerConfigurationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (TransformerFactoryConfigurationError e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Modified:
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopFactory.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopFactory.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopFactory.java
(original)
+++
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopFactory.java
Tue Dec 11 22:38:23 2007
@@ -18,11 +18,9 @@
*******************************************************************************/
package org.ofbiz.webapp.view;
-import org.apache.fop.apps.FopFactory;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.webapp.view.ApacheFopWorker;
-import java.io.File;
+import org.apache.fop.apps.FopFactory;
/**
* Apache FOP Factory used to provide a singleton instance of the FopFactory.
Best pratices recommended
@@ -34,34 +32,8 @@
public static final String module = ApacheFopFactory.class.getName();
- private static final FopFactory fopFactory;
-
- static {
- // Create the factory
- fopFactory = FopFactory.newInstance();
-
- // Limit the validation for backwards compatibility
- fopFactory.setStrictValidation(false);
-
- try {
- String fopPath = UtilProperties.getPropertyValue("fop.properties",
"fop.path", "framework/webapp/config");
- File userConfigFile = new File(fopPath + "/fop.xconf");
- fopFactory.setUserConfig(userConfigFile);
- String fopFontBaseUrl = fopFactory.getFontBaseURL();
- if (fopFontBaseUrl == null) {
- String ofbizHome = System.getProperty("ofbiz.home");
- fopFontBaseUrl =
UtilProperties.getPropertyValue("fop.properties", "fop.font.base.url",
- "file:///" + ofbizHome +
"/framework/webapp/config/");
- fopFactory.setFontBaseURL(fopFontBaseUrl);
- }
- Debug.logInfo("FOP-FontBaseURL: " + fopFontBaseUrl, module);
- } catch (Exception e) {
- Debug.logWarning("Error reading FOP configuration", module);
- }
- }
-
+ /** @deprecated use ApacheFopWorker.getFactoryInstance() */
public static FopFactory instance() {
- return fopFactory;
+ return ApacheFopWorker.getFactoryInstance();
}
-
}
Added:
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopWorker.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopWorker.java?rev=603483&view=auto
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopWorker.java
(added)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/ApacheFopWorker.java
Tue Dec 11 22:38:23 2007
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * 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.ofbiz.webapp.view;
+
+import java.io.*;
+import java.net.URL;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+
+import org.ofbiz.base.location.FlexibleLocation;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+
+/**
+ * Apache FOP worker class.
+ */
+
+public class ApacheFopWorker {
+
+ public static final String module = ApacheFopWorker.class.getName();
+ /** File name prefix used for temporary files. Currently set to
+ * <code>org.ofbiz.webapp.view.ApacheFopWorker-</code>.
+ */
+ public static final String tempFilePrefix =
"org.ofbiz.webapp.view.ApacheFopWorker-";
+
+ protected static FopFactory fopFactory = null;
+
+ /** Returns an instance of the FopFactory class. FOP documentation
recommends
+ * the reuse of the factory instance because of the startup time.
+ * @return FopFactory The FopFactory instance
+ */
+ public static FopFactory getFactoryInstance() {
+ if (fopFactory == null) {
+ synchronized (ApacheFopWorker.class) {
+ if (fopFactory != null) {
+ return fopFactory;
+ }
+ // Create the factory
+ fopFactory = FopFactory.newInstance();
+
+ // Limit the validation for backwards compatibility
+ fopFactory.setStrictValidation(false);
+
+ try {
+ String fopPath =
UtilProperties.getPropertyValue("fop.properties", "fop.path",
"framework/webapp/config");
+ File userConfigFile = new File(fopPath + "/fop.xconf");
+ fopFactory.setUserConfig(userConfigFile);
+ String fopFontBaseUrl = fopFactory.getFontBaseURL();
+ if (fopFontBaseUrl == null) {
+ String ofbizHome = System.getProperty("ofbiz.home");
+ fopFontBaseUrl =
UtilProperties.getPropertyValue("fop.properties", "fop.font.base.url",
"file:///" + ofbizHome + "/framework/webapp/config/");
+ fopFactory.setFontBaseURL(fopFontBaseUrl);
+ }
+ Debug.logInfo("FOP-FontBaseURL: " + fopFontBaseUrl,
module);
+ } catch (Exception e) {
+ Debug.logWarning("Error reading FOP configuration",
module);
+ }
+ }
+ }
+ return fopFactory;
+ }
+
+ /** Transform an xsl-fo file to the specified file format.
+ * @param srcFile The xsl-fo File instance
+ * @param destFile The target (result) File instance
+ * @param stylesheetFile Optional stylesheet File instance
+ * @param outputFormat Optional output format, defaults to
"application/pdf"
+ */
+ public static void transform(File srcFile, File destFile, File
stylesheetFile, String outputFormat) throws IOException, FOPException {
+ StreamSource src = new StreamSource(srcFile);
+ StreamSource stylesheet = stylesheetFile == null ? null : new
StreamSource(stylesheetFile);
+ BufferedOutputStream dest = new BufferedOutputStream(new
FileOutputStream(destFile));
+ Fop fop = createFopInstance(dest, outputFormat);
+ if (fop.getUserAgent().getBaseURL() == null) {
+ String baseURL = null;
+ try {
+ File parentFile = new
File(srcFile.getAbsolutePath()).getParentFile();
+ baseURL = parentFile.toURI().toURL().toExternalForm();
+ } catch (Exception e) {
+ baseURL = "";
+ }
+ fop.getUserAgent().setBaseURL(baseURL);
+ }
+ transform(src, stylesheet, fop);
+ dest.close();
+ }
+
+ /** Transform an xsl-fo InputStream to the specified OutputStream format.
+ * @param srcStream The xsl-fo InputStream instance
+ * @param destStream The target (result) OutputStream instance
+ * @param stylesheetStream Optional stylesheet InputStream instance
+ * @param outputFormat Optional output format, defaults to
"application/pdf"
+ */
+ public static void transform(InputStream srcStream, OutputStream
destStream, InputStream stylesheetStream, String outputFormat) throws
FOPException {
+ StreamSource src = new StreamSource(srcStream);
+ StreamSource stylesheet = stylesheetStream == null ? null : new
StreamSource(stylesheetStream);
+ Fop fop = createFopInstance(destStream, outputFormat);
+ transform(src, stylesheet, fop);
+ }
+
+ /** Transform an xsl-fo StreamSource to the specified output format.
+ * @param src The xsl-fo StreamSource instance
+ * @param stylesheet Optional stylesheet StreamSource instance
+ * @param fop
+ */
+ public static void transform(StreamSource src, StreamSource stylesheet,
Fop fop) throws FOPException {
+ Result res = new SAXResult(fop.getDefaultHandler());
+ try {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer;
+ if (stylesheet == null) {
+ transformer = factory.newTransformer();
+ } else {
+ transformer = factory.newTransformer(stylesheet);
+ }
+ transformer.setURIResolver(new
LocalResolver(transformer.getURIResolver()));
+ transformer.transform(src, res);
+ FopFactory fopFactory = getFactoryInstance();
+ fopFactory.getImageFactory().clearCaches();
+ } catch (Exception e) {
+ throw new FOPException(e);
+ }
+ }
+
+ /** Returns a new Fop instance. Note: FOP documentation recommends using
+ * a Fop instance for one transform run only.
+ * @param out The target (result) OutputStream instance
+ * @param outputFormat Optional output format, defaults to
"application/pdf"
+ * @return Fop instance
+ */
+ public static Fop createFopInstance(OutputStream out, String outputFormat)
throws FOPException {
+ if (UtilValidate.isEmpty(outputFormat)) {
+ outputFormat = MimeConstants.MIME_PDF;
+ }
+ FopFactory fopFactory = getFactoryInstance();
+ FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
+ Fop fop;
+ if (out != null) {
+ fop = fopFactory.newFop(outputFormat, foUserAgent, out);
+ } else {
+ fop = fopFactory.newFop(outputFormat, foUserAgent);
+ }
+ return fop;
+ }
+
+ /** Returns a temporary File instance. The temporary file name starts with
+ * <a href="#tempFilePrefix">tempFilePrefix</a> and ends with ".xml".
+ * Calling methods are responsible for deleting the temporary file.<p>
+ * FOP performs transforms in memory, so if there is any chance FO output
+ * will be more than a few pages, it would be best to keep FO input in a
temporary
+ * file.</p>
+ * @return File instance
+ */
+ public static File createTempFoXmlFile() throws IOException {
+ File tempXmlFile = File.createTempFile(tempFilePrefix, ".xml");
+ tempXmlFile.deleteOnExit();
+ return tempXmlFile;
+ }
+
+ /** Returns a temporary File instance. The temporary file name starts with
+ * <a href="#tempFilePrefix">tempFilePrefix</a> and ends with ".res".
+ * Calling methods are responsible for deleting the temporary file.<p>
+ * FOP performs transforms in memory, so if there is any chance FO output
+ * will be more than a few pages, it would be best to keep FO output in a
temporary
+ * file.</p>
+ * @return File instance
+ */
+ public static File createTempResultFile() throws IOException {
+ File tempResultFile = File.createTempFile(tempFilePrefix, ".res");
+ tempResultFile.deleteOnExit();
+ return tempResultFile;
+ }
+
+ /** Local URI resolver for the Transformer class.
+ */
+ public static class LocalResolver implements URIResolver {
+
+ private URIResolver defaultResolver;
+
+ protected LocalResolver() {}
+
+ public LocalResolver(URIResolver defaultResolver) {
+ this.defaultResolver = defaultResolver;
+ }
+
+ public Source resolve(String href, String base) throws
TransformerException {
+ URL locationUrl = null;
+ try {
+ locationUrl = FlexibleLocation.resolveLocation(href);
+ if (locationUrl != null) {
+ return new StreamSource(locationUrl.openStream());
+ }
+ } catch (Exception e) {
+ throw new TransformerException(e.getMessage());
+ }
+ return defaultResolver.resolve(href, base);
+ }
+ }
+}
Modified:
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/FopPdfViewHandler.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/FopPdfViewHandler.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/FopPdfViewHandler.java
(original)
+++
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/view/FopPdfViewHandler.java
Tue Dec 11 22:38:23 2007
@@ -20,10 +20,14 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
@@ -53,8 +57,10 @@
// render the byte array
ByteArrayOutputStream out = null;
+ Reader reader = new StringReader(writer.toString());
+ Source src = new StreamSource(reader);
try {
- out = FopRenderer.render(writer);
+ ApacheFopWorker.transform(src, out, null, contentType);
} catch (GeneralException e) {
throw new ViewHandlerException(e.getMessage(), e.getNested());
}
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
(original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
Tue Dec 11 22:38:23 2007
@@ -48,13 +48,14 @@
import org.ofbiz.widget.form.ModelFormField.TextField;
import org.ofbiz.widget.form.ModelFormField.TextFindField;
import org.ofbiz.widget.form.ModelFormField.TextareaField;
+import org.ofbiz.widget.html.HtmlWidgetRenderer;
/**
* Widget Library - FO Form Renderer implementation
*
*/
-public class FoFormRenderer implements FormStringRenderer {
+public class FoFormRenderer extends HtmlWidgetRenderer implements
FormStringRenderer {
public static final String module = FoFormRenderer.class.getName();
@@ -68,12 +69,6 @@
this.response = response;
}
- public void appendWhitespace(StringBuffer buffer) {
- // appending line ends for now, but this could be replaced with a
simple space or something
- buffer.append("\r\n");
- //buffer.append(' ');
- }
-
private void makeBlockString(StringBuffer buffer, String widgetStyle,
String text) {
buffer.append("<fo:block");
if (UtilValidate.isNotEmpty(widgetStyle)) {
@@ -88,31 +83,31 @@
public void renderDisplayField(StringBuffer buffer, Map context,
DisplayField displayField) {
ModelFormField modelFormField = displayField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
displayField.getDescription(context));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderHyperlinkField(StringBuffer buffer, Map context,
HyperlinkField hyperlinkField) {
ModelFormField modelFormField = hyperlinkField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
hyperlinkField.getDescription(context));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderTextField(StringBuffer buffer, Map context, TextField
textField) {
ModelFormField modelFormField = textField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, textField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderTextareaField(StringBuffer buffer, Map context,
TextareaField textareaField) {
ModelFormField modelFormField = textareaField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderDateTimeField(StringBuffer buffer, Map context,
DateTimeField dateTimeField) {
ModelFormField modelFormField = dateTimeField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderDropDownField(StringBuffer buffer, Map context,
DropDownField dropDownField) {
@@ -140,7 +135,7 @@
}
}
}
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderCheckField(StringBuffer buffer, Map context, CheckField
checkField) {
@@ -174,12 +169,15 @@
}
public void renderFormOpen(StringBuffer buffer, Map context, ModelForm
modelForm) {
+ renderBeginningBoundaryComment(buffer, "Form Widget", modelForm);
}
public void renderFormClose(StringBuffer buffer, Map context, ModelForm
modelForm) {
+ renderEndingBoundaryComment(buffer, "Form Widget", modelForm);
}
public void renderMultiFormClose(StringBuffer buffer, Map context,
ModelForm modelForm) {
+ renderEndingBoundaryComment(buffer, "Form Widget", modelForm);
}
public void renderFormatListWrapperOpen(StringBuffer buffer, Map context,
ModelForm modelForm) {
@@ -198,28 +196,28 @@
buffer.append(FoScreenRenderer.getFoStyle(areaStyle));
}
buffer.append("/>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatListWrapperClose(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("</fo:table-body>");
buffer.append("</fo:table>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowOpen(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("<fo:table-header>");
buffer.append("<fo:table-row>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowClose(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("</fo:table-row>");
buffer.append("</fo:table-header>");
buffer.append("<fo:table-body>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowCellOpen(StringBuffer buffer, Map
context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
@@ -232,23 +230,23 @@
buffer.append("font-weight=\"bold\" text-align=\"center\"
border=\"solid black\" padding=\"2pt\"");
buffer.append(">");
buffer.append("<fo:block>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowCellClose(StringBuffer buffer, Map
context, ModelForm modelForm, ModelFormField modelFormField) {
buffer.append("</fo:block>");
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowFormCellOpen(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("<fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowFormCellClose(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatHeaderRowFormCellTitleSeparator(StringBuffer
buffer, Map context, ModelForm modelForm, ModelFormField modelFormField,
boolean isLast) {
@@ -256,12 +254,12 @@
public void renderFormatItemRowOpen(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("<fo:table-row>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatItemRowClose(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("</fo:table-row>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatItemRowCellOpen(StringBuffer buffer, Map context,
ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
@@ -277,62 +275,62 @@
}
buffer.append(FoScreenRenderer.getFoStyle(areaStyle));
buffer.append(">");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatItemRowCellClose(StringBuffer buffer, Map context,
ModelForm modelForm, ModelFormField modelFormField) {
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatItemRowFormCellOpen(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("<fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatItemRowFormCellClose(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
// TODO: multi columns (position attribute) in single forms are still not
implemented
public void renderFormatSingleWrapperOpen(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("<fo:table>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
buffer.append("<fo:table-column column-width=\"2in\"/>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
buffer.append("<fo:table-column/>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
buffer.append("<fo:table-body>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatSingleWrapperClose(StringBuffer buffer, Map
context, ModelForm modelForm) {
buffer.append("</fo:table-body>");
buffer.append("</fo:table>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowOpen(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("<fo:table-row>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowClose(StringBuffer buffer, Map context,
ModelForm modelForm) {
buffer.append("</fo:table-row>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowTitleCellOpen(StringBuffer buffer, Map
context, ModelFormField modelFormField) {
buffer.append("<fo:table-cell font-weight=\"bold\"
text-align=\"right\" padding=\"3pt\">");
buffer.append("<fo:block>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowTitleCellClose(StringBuffer buffer, Map
context, ModelFormField modelFormField) {
buffer.append("</fo:block>");
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowSpacerCell(StringBuffer buffer, Map
context, ModelFormField modelFormField) {
@@ -340,12 +338,12 @@
public void renderFormatFieldRowWidgetCellOpen(StringBuffer buffer, Map
context, ModelFormField modelFormField, int positions, int positionSpan,
Integer nextPositionInRow) {
buffer.append("<fo:table-cell text-align=\"left\" padding=\"2pt\"
padding-left=\"5pt\">");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatFieldRowWidgetCellClose(StringBuffer buffer, Map
context, ModelFormField modelFormField, int positions, int positionSpan,
Integer nextPositionInRow) {
buffer.append("</fo:table-cell>");
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderFormatEmptySpace(StringBuffer buffer, Map context,
ModelForm modelForm) {
@@ -355,25 +353,25 @@
public void renderTextFindField(StringBuffer buffer, Map context,
TextFindField textFindField) {
ModelFormField modelFormField = textFindField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderRangeFindField(StringBuffer buffer, Map context,
RangeFindField rangeFindField) {
ModelFormField modelFormField = rangeFindField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderDateFindField(StringBuffer buffer, Map context,
DateFindField dateFindField) {
ModelFormField modelFormField = dateFindField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderLookupField(StringBuffer buffer, Map context,
LookupField lookupField) {
ModelFormField modelFormField = lookupField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderNextPrev(StringBuffer buffer, Map context, ModelForm
modelForm) {
@@ -382,7 +380,7 @@
public void renderFileField(StringBuffer buffer, Map context, FileField
textField) {
ModelFormField modelFormField = textField.getModelFormField();
this.makeBlockString(buffer, modelFormField.getWidgetStyle(),
modelFormField.getEntry(context, textField.getDefaultValue(context)));
- this.appendWhitespace(buffer);
+ appendWhitespace(buffer);
}
public void renderPasswordField(StringBuffer buffer, Map context,
PasswordField passwordField) {
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
(original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
Tue Dec 11 22:38:23 2007
@@ -20,34 +20,18 @@
import java.io.IOException;
import java.io.Writer;
-import java.util.Locale;
import java.util.Map;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.GenericDelegator;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.WidgetContentWorker;
+import org.ofbiz.widget.html.HtmlWidgetRenderer;
import org.ofbiz.widget.screen.ModelScreenWidget;
import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.ofbiz.service.LocalDispatcher;
-import javolution.util.FastMap;
/**
* Widget Library - HTML Form Renderer implementation
*/
-public class FoScreenRenderer implements ScreenStringRenderer {
+public class FoScreenRenderer extends HtmlWidgetRenderer implements
ScreenStringRenderer {
public static final String module = FoScreenRenderer.class.getName();
@@ -63,10 +47,10 @@
}
public void renderSectionBegin(Writer writer, Map context,
ModelScreenWidget.Section section) throws IOException {
- // do nothing, this is just a place holder container for HTML
+ renderBeginningBoundaryComment(writer,
section.isMainSection?"Screen":"Section Widget", section);
}
public void renderSectionEnd(Writer writer, Map context,
ModelScreenWidget.Section section) throws IOException {
- // do nothing, this is just a place holder container for HTML
+ renderEndingBoundaryComment(writer,
section.isMainSection?"Screen":"Section Widget", section);
}
public void renderContainerBegin(Writer writer, Map context,
ModelScreenWidget.Container container) throws IOException {
@@ -141,10 +125,5 @@
public void renderSubContentEnd(Writer writer, Map context,
ModelScreenWidget.SubContent content) throws IOException {
// TODO: not implemented
- }
-
- public void appendWhitespace(Writer writer) throws IOException {
- // appending line ends for now, but this could be replaced with a
simple space or something
- writer.write("\r\n");
}
}
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java?rev=603483&r1=603482&r2=603483&view=diff
==============================================================================
---
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
(original)
+++
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
Tue Dec 11 22:38:23 2007
@@ -23,20 +23,14 @@
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.xml.transform.*;
-import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
-import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.Fop;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.apps.FOPException;
import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.webapp.view.ApacheFopWorker;
import org.ofbiz.webapp.view.ViewHandler;
import org.ofbiz.webapp.view.ViewHandlerException;
-import org.ofbiz.webapp.view.ApacheFopFactory;
import org.ofbiz.widget.fo.FoFormRenderer;
import org.ofbiz.widget.fo.FoScreenRenderer;
@@ -50,8 +44,6 @@
protected ServletContext servletContext = null;
protected FoScreenRenderer foScreenRenderer = new FoScreenRenderer();
- private final String DEFAULT_ERROR_TEMPLATE =
"component://common/widget/CommonScreens.xml#FoError";
-
/**
* @see
org.ofbiz.webapp.view.ViewHandler#init(javax.servlet.ServletContext)
*/
@@ -64,15 +56,8 @@
*/
public void render(String name, String page, String info, String
contentType, String encoding, HttpServletRequest request, HttpServletResponse
response) throws ViewHandlerException {
- if (UtilValidate.isEmpty(contentType)) {
- contentType = "application/pdf";
- }
-
// render and obtain the XSL-FO
Writer writer = new StringWriter();
-
- FopFactory fopFactory = ApacheFopFactory.instance();
-
try {
ScreenRenderer screens = new ScreenRenderer(writer, null,
foScreenRenderer);
screens.populateContextForRequest(request, response,
servletContext);
@@ -84,88 +69,45 @@
throw new ViewHandlerException("Problems with the response
writer/output stream", t);
}
+ // set the input source (XSL-FO) and generate the output stream of
contentType
+ Reader reader = new StringReader(writer.toString());
+ StreamSource src = new StreamSource(reader);
+ if (Debug.verboseOn()) {
+ Debug.logVerbose("Transforming the following xsl-fo template: " +
writer.toString(), module);
+ }
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
- TransformerFactory transFactory = TransformerFactory.newInstance();
+ try {
+ Fop fop = ApacheFopWorker.createFopInstance(out, contentType);
+ ApacheFopWorker.transform(src, null, fop);
+ } catch (Exception e) {
+ throw createException("Unable to transform FO file", e, response);
+ }
+ // set the content type and length
+ response.setContentType(contentType);
+ response.setContentLength(out.size());
+ // write to the browser
try {
- Fop fop = fopFactory.newFop(contentType, out);
- Transformer transformer = transFactory.newTransformer();
+ out.writeTo(response.getOutputStream());
+ response.getOutputStream().flush();
+ } catch (IOException e) {
+ throw createException("Unable write to browser OutputStream", e,
response);
+ }
+ }
- // set the input source (XSL-FO) and generate the output stream of
contentType
- Reader reader = new StringReader(writer.toString());
- Source src = new StreamSource(reader);
-
- if (Debug.verboseOn()) {
- Debug.logVerbose("Transforming the following xsl-fo template:
" + writer.toString(), module);
- }
- /*
- try {
- String buf = writer.toString();
- java.io.FileWriter fw = new java.io.FileWriter(new
java.io.File("/tmp/xslfo.out"));
- fw.write(buf.toString());
- fw.close();
- } catch (IOException e) {
- throw new ViewHandlerException("Unable write to browser
OutputStream", e);
- }
- */
-
- // Get handler that is used in the generation process
- Result res = new SAXResult(fop.getDefaultHandler());
-
- try {
- // Transform the FOP XML source
- transformer.transform(src, res);
-
- } catch (TransformerException e) {
- Debug.logError("FOP transform failed: " + e, module );
- Debug.logInfo("Rendering the error message using the default
error template: " + DEFAULT_ERROR_TEMPLATE, module );
- try {
- writer = new StringWriter();
- out = new ByteArrayOutputStream();
- fopFactory = ApacheFopFactory.instance();
- transFactory = TransformerFactory.newInstance();
- transformer = transFactory.newTransformer();
- fop = fopFactory.newFop(contentType, out);
- res = new SAXResult(fop.getDefaultHandler());
- ScreenRenderer screens = new ScreenRenderer(writer, null,
foScreenRenderer);
- screens.populateContextForRequest(request, response,
servletContext);
- screens.getContext().put("errorMessage", e.toString());
- screens.render(DEFAULT_ERROR_TEMPLATE);
- transformer.transform(new StreamSource(new
StringReader(writer.toString())), res);
- } catch (Throwable t) {
- // If we cannot even create the error page, then we return
the original error
- throw new ViewHandlerException("Unable to transform FO to
" + contentType, e);
- }
- }
-
- // We don't want to cache the images that get loaded by the FOP
engine
- fopFactory.getImageFactory().clearCaches();
-
- // set the content type and length
- response.setContentType(contentType);
- response.setContentLength(out.size());
-
- // write to the browser
- try {
- out.writeTo(response.getOutputStream());
- response.getOutputStream().flush();
- } catch (IOException e) {
- throw new ViewHandlerException("Unable write to browser
OutputStream", e);
- }
-
- } catch (TransformerConfigurationException e) {
- Debug.logError("FOP TransformerConfiguration Exception " + e,
module);
- throw new ViewHandlerException("Transformer Configuration Error",
e);
- } catch (FOPException e) {
- Debug.logError("FOP Exception " + e, module);
- throw new ViewHandlerException("FOP Error", e);
- } finally {
- try {
- out.close();
- } catch (IOException e) {
- Debug.logError("Unable to close output stream " + e, module);
- }
+ protected ViewHandlerException createException(String msg, Exception e,
HttpServletResponse response) {
+ Debug.logError(msg + ": " + e, module);
+ String htmlString = "<html><head><title>FOP Rendering
Error</title></head><body>" + msg + ": " + e.getMessage() + "</body></html>";
+ response.setContentType("text/html");
+ response.setContentLength(htmlString.length());
+ try {
+ response.getOutputStream().write(htmlString.getBytes());
+ } catch (IOException i) {
+ Debug.logError("Multiple errors rendering FOP", module);
}
+ return new ViewHandlerException(msg, e);
}
+
}