Author: davenewton
Date: Fri Apr 25 09:04:45 2008
New Revision: 651634

URL: http://svn.apache.org/viewvc?rev=651634&view=rev
Log:
WW-2365 - https://issues.apache.org/struts/browse/WW-2365

- Added support for both report and export parameters.

- Minor refactoring:
  - Moved some init and output code out of execute.
  - Normalized PDF reports to be the same as the rest.
  - Resulted in cleaner code, lower cyclometric comp.

Still no tests for this result type.

Modified:
    
struts/struts2/trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java

Modified: 
struts/struts2/trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java?rev=651634&r1=651633&r2=651634&view=diff
==============================================================================
--- 
struts/struts2/trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java
 (original)
+++ 
struts/struts2/trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java
 Fri Apr 25 09:04:45 2008
@@ -44,6 +44,7 @@
 import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
 import net.sf.jasperreports.engine.export.JRHtmlExporter;
 import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
+import net.sf.jasperreports.engine.export.JRPdfExporter;
 import net.sf.jasperreports.engine.export.JRRtfExporter;
 import net.sf.jasperreports.engine.export.JRXlsExporter;
 import net.sf.jasperreports.engine.export.JRXmlExporter;
@@ -128,21 +129,39 @@
 
     private static final long serialVersionUID = -2523174799621182907L;
 
-
     private final static Logger LOG = 
LoggerFactory.getLogger(JasperReportsResult.class);
 
-
     protected String dataSource;
     protected String format;
     protected String documentName;
     protected String contentDisposition;
     protected String delimiter;
     protected String imageServletUrl = "/images/";
+    
+    /**
+     * Names a report parameters map stack value, allowing 
+     * additional report parameters from the action. 
+     */
+    protected String reportParameters;
+    
+    /**
+     * Names an exporter parameters map stack value,
+     * allowing the use of custom export parameters.
+     */
+    protected String exportParameters;
 
+    /**
+     * Default ctor.
+     */
     public JasperReportsResult() {
         super();
     }
 
+    /**
+     * Default ctor with location.
+     * 
+     * @param location Result location.
+     */
     public JasperReportsResult(String location) {
         super(location);
     }
@@ -175,161 +194,211 @@
         this.delimiter = delimiter;
     }
 
-    protected void doExecute(String finalLocation, ActionInvocation 
invocation) throws Exception {
-        if (this.format == null) {
-            this.format = FORMAT_PDF;
-        }
-
-        if (dataSource == null) {
-            String message = "No dataSource specified...";
-            LOG.error(message);
-            throw new RuntimeException(message);
-        }
+       public String getReportParameters() {
+               return reportParameters;
+       }
+
+       public void setReportParameters(String reportParameters) {
+               this.reportParameters = reportParameters;
+       }
+       
+       public String getExportParameters() {
+               return exportParameters;
+       }
+
+       public void setExportParameters(String exportParameters) {
+               this.exportParameters = exportParameters;
+       }
+
+       protected void doExecute(String finalLocation, ActionInvocation 
invocation) throws Exception {
+               // Will throw a runtime exception if no "datasource" property. 
TODO Best place for that is...?
+        initializeProperties(invocation);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Creating JasperReport for dataSource = " + dataSource + 
", format = " + this.format);
+            LOG.debug("Creating JasperReport for dataSource = " + dataSource + 
", format = " + format);
         }
 
         HttpServletRequest request = (HttpServletRequest) 
invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
         HttpServletResponse response = (HttpServletResponse) 
invocation.getInvocationContext().get(ServletActionContext.HTTP_RESPONSE);
 
-        //construct the data source for the report
+        // Handle IE special case: it sends a "contype" request first.
+        // TODO Set content type to config settings?
+        if ("contype".equals(request.getHeader("User-Agent"))) {
+               try {
+                       response.setContentType("application/pdf");
+                       response.setContentLength(0);
+                       
+                       ServletOutputStream outputStream = 
response.getOutputStream();
+                       outputStream.close();
+               } catch (IOException e) {
+                       LOG.error("Error writing report output", e);
+                       throw new ServletException(e.getMessage(), e);
+               }
+               return;
+        }
+
+        // Construct the data source for the report.
         ValueStack stack = invocation.getStack();
         ValueStackDataSource stackDataSource = new ValueStackDataSource(stack, 
dataSource);
 
-        format = conditionalParse(format, invocation);
-        dataSource = conditionalParse(dataSource, invocation);
-
-        if (contentDisposition != null) {
-            contentDisposition = conditionalParse(contentDisposition, 
invocation);
+        // Determine the directory that the report file is in and set the 
reportDirectory parameter
+        // For WW 2.1.7:
+        //  ServletContext servletContext = ((ServletConfig) 
invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONFIG)).getServletContext();
+        ServletContext servletContext = (ServletContext) 
invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONTEXT);
+        String systemId = servletContext.getRealPath(finalLocation);
+        Map parameters = new ValueStackShadowMap(stack);
+        File directory = new File(systemId.substring(0, 
systemId.lastIndexOf(File.separator)));
+        parameters.put("reportDirectory", directory);
+        parameters.put(JRParameter.REPORT_LOCALE, 
invocation.getInvocationContext().getLocale());
+
+        // Add any report parameters from action to param map.
+        Map reportParams = (Map) stack.findValue(reportParameters);
+        if (reportParams != null) {
+               LOG.debug("Found report parameters; adding to parameters...");
+               parameters.putAll(reportParams);
         }
 
-        if (documentName != null) {
-            documentName = conditionalParse(documentName, invocation);
-        }
+        byte[] output;
+        JasperPrint jasperPrint;
 
-        // (Map) ActionContext.getContext().getSession().get("IMAGES_MAP");
-        if (!TextUtils.stringSet(format)) {
-            format = FORMAT_PDF;
+        // Fill the report and produce a print object
+        try {
+            JasperReport jasperReport = (JasperReport) 
JRLoader.loadObject(systemId);
+            jasperPrint = JasperFillManager.fillReport(jasperReport, 
parameters, stackDataSource);
+        } catch (JRException e) {
+            LOG.error("Error building report for uri " + systemId, e);
+            throw new ServletException(e.getMessage(), e);
         }
 
-        if (!"contype".equals(request.getHeader("User-Agent"))) {
-            // Determine the directory that the report file is in and set the 
reportDirectory parameter
-            // For WW 2.1.7:
-            //  ServletContext servletContext = ((ServletConfig) 
invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONFIG)).getServletContext();
-            ServletContext servletContext = (ServletContext) 
invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONTEXT);
-            String systemId = servletContext.getRealPath(finalLocation);
-            Map parameters = new ValueStackShadowMap(stack);
-            File directory = new File(systemId.substring(0, 
systemId.lastIndexOf(File.separator)));
-            parameters.put("reportDirectory", directory);
-            parameters.put(JRParameter.REPORT_LOCALE, 
invocation.getInvocationContext().getLocale());
-
-            byte[] output;
-            JasperPrint jasperPrint;
-
-            // Fill the report and produce a print object
-            try {
-                JasperReport jasperReport = (JasperReport) 
JRLoader.loadObject(systemId);
-
-                jasperPrint =
-                        JasperFillManager.fillReport(jasperReport,
-                                parameters,
-                                stackDataSource);
-            } catch (JRException e) {
-                LOG.error("Error building report for uri " + systemId, e);
-                throw new ServletException(e.getMessage(), e);
+        // Export the print object to the desired output format
+        try {
+            if (contentDisposition != null || documentName != null) {
+                final StringBuffer tmp = new StringBuffer();
+                tmp.append((contentDisposition == null) ? "inline" : 
contentDisposition);
+
+                if (documentName != null) {
+                    tmp.append("; filename=");
+                    tmp.append(documentName);
+                    tmp.append(".");
+                    tmp.append(format.toLowerCase());
+                }
+
+                response.setHeader("Content-disposition", tmp.toString());
             }
 
-            // Export the print object to the desired output format
-            try {
-                if (contentDisposition != null || documentName != null) {
-                    final StringBuffer tmp = new StringBuffer();
-                    tmp.append((contentDisposition == null) ? "inline" : 
contentDisposition);
-
-                    if (documentName != null) {
-                        tmp.append("; filename=");
-                        tmp.append(documentName);
-                        tmp.append(".");
-                        tmp.append(format.toLowerCase());
-                    }
+            JRExporter exporter;
 
-                    response.setHeader("Content-disposition", tmp.toString());
-                }
+            if (format.equals(FORMAT_PDF)) {
+                response.setContentType("application/pdf");
+                exporter = new JRPdfExporter();
+            } else if (format.equals(FORMAT_CSV)) {
+                response.setContentType("text/plain");
+                exporter = new JRCsvExporter();
+            } else if (format.equals(FORMAT_HTML)) {
+                response.setContentType("text/html");
+
+                // IMAGES_MAPS seems to be only supported as "backward 
compatible" from JasperReports 1.1.0
+
+                Map imagesMap = new HashMap();
+                request.getSession(true).setAttribute("IMAGES_MAP", imagesMap);
+
+                exporter = new JRHtmlExporter();
+                exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, 
imagesMap);
+                exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, 
request.getContextPath() + imageServletUrl);
+                
+                // Needed to support chart images:
+                exporter.setParameter(JRExporterParameter.JASPER_PRINT, 
jasperPrint);
+                
request.getSession().setAttribute("net.sf.jasperreports.j2ee.jasper_print", 
jasperPrint);
+            } else if (format.equals(FORMAT_XLS)) {
+                response.setContentType("application/vnd.ms-excel");
+                exporter = new JRXlsExporter();
+            } else if (format.equals(FORMAT_XML)) {
+                response.setContentType("text/xml");
+                exporter = new JRXmlExporter();
+            } else if (format.equals(FORMAT_RTF)) {
+                response.setContentType("application/rtf");
+                exporter = new JRRtfExporter();
+            } else {
+                throw new ServletException("Unknown report format: " + format);
+            }
+            
+            Map exportParams = (Map) stack.findValue(exportParameters);
+            if (exportParams != null) {
+               LOG.debug("Found export parameters; adding to exporter 
parameters...");
+               exporter.getParameters().putAll(exportParams);
+            }
 
-                if (format.equals(FORMAT_PDF)) {
-                    response.setContentType("application/pdf");
+            output = exportReportToBytes(jasperPrint, exporter);
+        } catch (JRException e) {
+            String message = "Error producing " + format + " report for uri " 
+ systemId;
+            LOG.error(message, e);
+            throw new ServletException(e.getMessage(), e);
+        }
 
-                    // response.setHeader("Content-disposition", "inline; 
filename=report.pdf");
-                    output = 
JasperExportManager.exportReportToPdf(jasperPrint);
-                } else {
-                    JRExporter exporter;
-
-                    if (format.equals(FORMAT_CSV)) {
-                        response.setContentType("text/plain");
-                        exporter = new JRCsvExporter();
-                    } else if (format.equals(FORMAT_HTML)) {
-                        response.setContentType("text/html");
-
-                        // IMAGES_MAPS seems to be only supported as "backward 
compatible" from JasperReports 1.1.0
-
-                        Map imagesMap = new HashMap();
-
-                        request.getSession(true).setAttribute("IMAGES_MAP", 
imagesMap);
-                        exporter = new JRHtmlExporter();
-                        
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
-                        
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, 
request.getContextPath() + imageServletUrl);
-                        // Needed to support chart images:
-                        
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
-                        
request.getSession().setAttribute("net.sf.jasperreports.j2ee.jasper_print", 
jasperPrint);
-
-                    } else if (format.equals(FORMAT_XLS)) {
-                        response.setContentType("application/vnd.ms-excel");
-                        exporter = new JRXlsExporter();
-                    } else if (format.equals(FORMAT_XML)) {
-                        response.setContentType("text/xml");
-                        exporter = new JRXmlExporter();
-                    } else if (format.equals(FORMAT_RTF)) {
-                        response.setContentType("application/rtf");
-                        exporter = new JRRtfExporter();
-                    } else {
-                        throw new ServletException("Unknown report format: " + 
format);
-                    }
+        response.setContentLength(output.length);
 
-                    output = exportReportToBytes(jasperPrint, exporter);
-                }
-            } catch (JRException e) {
-                String message = "Error producing " + format + " report for 
uri " + systemId;
-                LOG.error(message, e);
-                throw new ServletException(e.getMessage(), e);
-            }
+        // Will throw ServletException on IOException.
+        writeReport(response, output);
+    }
 
-            response.setContentLength(output.length);
+       /**
+        * Writes report bytes to response output stream.
+        * 
+        * @param response Current response.
+        * @param output Report bytes to write.
+        * @throws ServletException on stream IOException.
+        */
+       private void writeReport(HttpServletResponse response, byte[] output) 
throws ServletException {
+               ServletOutputStream outputStream = null;
+        try {
+            outputStream = response.getOutputStream();
+            outputStream.write(output);
+            outputStream.flush();
+        } catch (IOException e) {
+            LOG.error("Error writing report output", e);
+            throw new ServletException(e.getMessage(), e);
+        } finally {
+               try {
+                       if (outputStream != null) {
+                               outputStream.close();
+                       }
+               } catch (IOException e) {
+                       LOG.error("Error closing report output stream", e);
+                       throw new ServletException(e.getMessage(), e);
+               }
+        }
+       }
 
-            ServletOutputStream ouputStream;
+       /**
+        * Sets up result properties, parsing etc.
+        * 
+        * @param invocation Current invocation.
+        * @throws Exception on initialization error.
+        */
+       private void initializeProperties(ActionInvocation invocation) throws 
Exception {
+               if (dataSource == null) {
+            String message = "No dataSource specified...";
+            LOG.error(message);
+            throw new RuntimeException(message);
+        }
+        dataSource = conditionalParse(dataSource, invocation);
 
-            try {
-                ouputStream = response.getOutputStream();
-                ouputStream.write(output);
-                ouputStream.flush();
-                ouputStream.close();
-            } catch (IOException e) {
-                LOG.error("Error writing report output", e);
-                throw new ServletException(e.getMessage(), e);
-            }
-        } else {
-            // Code to handle "contype" request from IE
-            try {
-                ServletOutputStream outputStream;
-                response.setContentType("application/pdf");
-                response.setContentLength(0);
-                outputStream = response.getOutputStream();
-                outputStream.close();
-            } catch (IOException e) {
-                LOG.error("Error writing report output", e);
-                throw new ServletException(e.getMessage(), e);
-            }
+        format = conditionalParse(format, invocation);
+        if (!TextUtils.stringSet(format)) {
+            format = FORMAT_PDF;
         }
-    }
+
+        if (contentDisposition != null) {
+            contentDisposition = conditionalParse(contentDisposition, 
invocation);
+        }
+
+        if (documentName != null) {
+            documentName = conditionalParse(documentName, invocation);
+        }
+
+        reportParameters = conditionalParse(reportParameters, invocation);
+        exportParameters = conditionalParse(exportParameters, invocation);
+       }
 
     /**
      * Run a Jasper report to CSV format and put the results in a byte array
@@ -356,4 +425,5 @@
 
         return output;
     }
+
 }


Reply via email to