fixes issue 38518: Compile subreports with HttpSecureAppServlet.renderJR
authorCarlos Aristu <carlos.aristu@openbravo.com>
Fri, 18 May 2018 12:42:38 +0200
changeset 33976 3404760330bc
parent 33975 3ac8e2eb5a9e
child 33977 4d0349cd40a0
fixes issue 38518: Compile subreports with HttpSecureAppServlet.renderJR

It has been deprecate the ability of specifying to the reporting API if the sub-reports should be compiled or not. Instead the API is smart enough to find the subreports (if any) and compile them. Besides, note that this subreport search will be performed just once per report, because the compilation results are cached since[1].

With this change, reports generated both with HttpSecureAppServlet and BaseReportActionHandler will compile the subreports in a transparent way, i.e., without the need of explicitly specifying it.


[1] https://issues.openbravo.com/view.php?id=37741
modules/org.openbravo.client.application/src/org/openbravo/client/application/report/BaseReportActionHandler.java
modules/org.openbravo.client.application/src/org/openbravo/client/application/report/CompiledReportManager.java
modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportCompiler.java
modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportingUtils.java
src/org/openbravo/base/secureApp/HttpSecureAppServlet.java
src/org/openbravo/common/actionhandler/CashflowForecastReportActionHandler.java
src/org/openbravo/erpCommon/utility/reporting/ReportManager.java
src/org/openbravo/erpReports/RptM_Requisition.java
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/BaseReportActionHandler.java	Thu May 17 19:30:38 2018 +0000
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/BaseReportActionHandler.java	Fri May 18 12:42:38 2018 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2018 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -574,14 +574,18 @@
   }
 
   /**
-   * Override this method to define if the sub-reports generated with the handler must be compiled.
-   * If true, it will compile all sub-report jrxml files placed in the same folder as the main
-   * report and whose related parameter name starts with SUBREP_
-   *
-   * @return true if the handler must compile the sub-reports. Otherwise, it returns false.
+   * This method has no effect. Classes extending {@code BaseReportActionHandler} will always try to
+   * compile the sub-reports (if any). Note that the sub-reports to be compiled will be the .jrxml
+   * files placed in the same folder as the main report and whose related parameter name starts with
+   * <b>SUBREP_</b>.
+   * 
+   * @return {@code true}
+   * 
+   * @deprecated This method has no effect
    */
+  @Deprecated
   protected boolean isCompilingSubreports() {
-    return false;
+    return true;
   }
 
   private void doJRExport(String jrTemplatePath, ExportType expType, String strFileName,
@@ -602,8 +606,7 @@
       }
       ReportingUtils.exportJR(jrTemplatePath, expType, jrParameters,
           new File(ReportingUtils.getTempFolder(), strFileName), true,
-          getReportConnectionProvider(), getReportData(parameters), localExportParameters,
-          isCompilingSubreports());
+          getReportConnectionProvider(), getReportData(parameters), localExportParameters);
     } finally {
       ReportSemaphoreHandling.getInstance().release();
     }
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/CompiledReportManager.java	Thu May 17 19:30:38 2018 +0000
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/CompiledReportManager.java	Fri May 18 12:42:38 2018 +0200
@@ -56,11 +56,6 @@
     return instance;
   }
 
-  JasperReport compileReport(String reportPath, String language) throws JRException {
-    return compileReport(reportPath, language,
-        DalConnectionProvider.getReadOnlyConnectionProvider());
-  }
-
   JasperReport compileReport(String reportPath, String language,
       ConnectionProvider connectionProvider) throws JRException {
     CompiledReport compiledReport = getCompiledReport(reportPath, language);
@@ -156,7 +151,7 @@
 
     public CompiledReport(JasperReport mainReport, Map<String, JasperReport> subReports) {
       this.mainReport = mainReport;
-      this.subReports = subReports;
+      this.subReports = !subReports.isEmpty() ? subReports : null;
     }
   }
 }
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportCompiler.java	Thu May 17 19:30:38 2018 +0000
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportCompiler.java	Fri May 18 12:42:38 2018 +0200
@@ -28,6 +28,7 @@
 import org.openbravo.base.exception.OBException;
 import org.openbravo.dal.core.DalContextListener;
 import org.openbravo.database.ConnectionProvider;
+import org.openbravo.service.db.DalConnectionProvider;
 import org.openbravo.uiTranslation.TranslationHandler;
 import org.openbravo.utils.Replace;
 import org.slf4j.Logger;
@@ -87,7 +88,7 @@
    * present this process assumes the subreport is a .jrxml file. It does not support the
    * possibility that this subreport file could be a .jasper file.
    * 
-   * @param connectionProvider
+   * @param provider
    *          A connection provider in case the report needs it.
    * @return a Map containing the compiled sub-reports. The keys of the map are the name of the
    *         parameter that references to each sub-report.
@@ -96,6 +97,8 @@
    *           error message.
    */
   Map<String, JasperReport> compileSubReports(ConnectionProvider provider) throws OBException {
+    ConnectionProvider cp = provider != null ? provider : DalConnectionProvider
+        .getReadOnlyConnectionProvider();
     try {
       Map<String, JasperReport> compiledSubReports = new HashMap<>();
       for (Object parameterObj : getMainDesign().getParametersList()) {
@@ -103,7 +106,7 @@
         if (parameter.getName().startsWith("SUBREP_")) {
           String parameterName = parameter.getName();
           String subReportName = Replace.replace(parameterName, "SUBREP_", "") + ".jrxml";
-          JasperDesign jasperDesign = getJasperDesign(provider, templateLocation + subReportName);
+          JasperDesign jasperDesign = getJasperDesign(cp, templateLocation + subReportName);
           JasperReport jasperReportLines = compileJasperReport(jasperDesign);
           compiledSubReports.put(parameterName, jasperReportLines);
         }
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportingUtils.java	Thu May 17 19:30:38 2018 +0000
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/report/ReportingUtils.java	Fri May 18 12:42:38 2018 +0200
@@ -140,31 +140,9 @@
   }
 
   /**
-   * @see ReportingUtils#exportJR(String, ExportType, Map, File, boolean, ConnectionProvider,
-   *      JRDataSource, Map, boolean)
-   */
-  public static void exportJR(String jasperFilePath, ExportType expType,
-      Map<String, Object> parameters, File target, boolean addProcessDefinitionParameters,
-      ConnectionProvider connectionProvider, JRDataSource data,
-      Map<Object, Object> additionalExportParameters) throws OBException {
-    exportJR(jasperFilePath, expType, parameters, target, addProcessDefinitionParameters,
-        connectionProvider, data, additionalExportParameters, false);
-  }
-
-  /**
-   * @see ReportingUtils#exportJR(String, ExportType, Map, OutputStream, boolean,
-   *      ConnectionProvider, JRDataSource, Map, boolean)
-   */
-  public static void exportJR(String jasperFilePath, ExportType expType,
-      Map<String, Object> parameters, OutputStream outputStream,
-      boolean addProcessDefinitionParameters, ConnectionProvider connectionProvider,
-      JRDataSource data, Map<Object, Object> additionalExportParameters) throws OBException {
-    exportJR(jasperFilePath, expType, parameters, outputStream, addProcessDefinitionParameters,
-        connectionProvider, data, additionalExportParameters, false);
-  }
-
-  /**
-   * Exports the report to a file.
+   * Exports the report to a file. This method will try to compile the sub-reports (if any). Note
+   * that the sub-reports to be compiled will be the .jrxml files placed in the same folder as the
+   * main report and whose related parameter name starts with <b>SUBREP_</b>.
    * 
    * @param jasperFilePath
    *          The path to the JR template of the report.
@@ -183,10 +161,6 @@
    *          The data to be used in the report, if required.
    * @param additionalExportParameters
    *          Additional export parameters than can be added to configure the resulting report.
-   * @param compileSubreports
-   *          A flag to indicate if the sub-reports should be compiled too. If true, the sub-report
-   *          jrxml files should be placed in the same folder as the main report and their related
-   *          parameter name should start with SUBREP_
    * @throws OBException
    *           In case there is any error generating the report an exception is thrown with the
    *           error message.
@@ -194,7 +168,7 @@
   public static void exportJR(String jasperFilePath, ExportType expType,
       Map<String, Object> parameters, File target, boolean addProcessDefinitionParameters,
       ConnectionProvider connectionProvider, JRDataSource data,
-      Map<Object, Object> additionalExportParameters, boolean compileSubreports) throws OBException {
+      Map<Object, Object> additionalExportParameters) throws OBException {
 
     JRSwapFileVirtualizer virtualizer = null;
     Map<Object, Object> exportParameters = new HashMap<>();
@@ -214,8 +188,8 @@
     if (addProcessDefinitionParameters) {
       addProcessDefinitionParameters(parameters);
     }
-    JasperPrint jasperPrint = generateJasperPrint(jasperFilePath, parameters, compileSubreports,
-        connectionProvider, data);
+    JasperPrint jasperPrint = generateJasperPrint(jasperFilePath, parameters, connectionProvider,
+        data);
     if (expType == ExportType.HTML) {
       HttpSession session = (HttpSession) parameters.get("HTTP_SESSION");
       if (session != null) {
@@ -236,7 +210,9 @@
   }
 
   /**
-   * Exports the report to an output stream.
+   * Exports the report to an output stream. This method will try to compile the sub-reports (if
+   * any). Note that the sub-reports to be compiled will be the .jrxml files placed in the same
+   * folder as the main report and whose related parameter name starts with <b>SUBREP_</b>.
    * 
    * @param jasperFilePath
    *          The path to the JR template of the report.
@@ -255,10 +231,6 @@
    *          The data to be used in the report, if required.
    * @param additionalExportParameters
    *          Additional export parameters than can be added to configure the resulting report.
-   * @param compileSubreports
-   *          A flag to indicate if the sub-reports should be compiled too. If true, the sub-report
-   *          jrxml files should be placed in the same folder as the main report and their related
-   *          parameter name should start with SUBREP_
    * @throws OBException
    *           In case there is any error generating the report an exception is thrown with the
    *           error message.
@@ -266,8 +238,7 @@
   public static void exportJR(String jasperFilePath, ExportType expType,
       Map<String, Object> parameters, OutputStream outputStream,
       boolean addProcessDefinitionParameters, ConnectionProvider connectionProvider,
-      JRDataSource data, Map<Object, Object> additionalExportParameters, boolean compileSubreports)
-      throws OBException {
+      JRDataSource data, Map<Object, Object> additionalExportParameters) throws OBException {
 
     JRSwapFileVirtualizer virtualizer = null;
     Map<Object, Object> exportParameters = new HashMap<>();
@@ -287,8 +258,8 @@
     if (addProcessDefinitionParameters) {
       addProcessDefinitionParameters(parameters);
     }
-    JasperPrint jasperPrint = generateJasperPrint(jasperFilePath, parameters, compileSubreports,
-        connectionProvider, data);
+    JasperPrint jasperPrint = generateJasperPrint(jasperFilePath, parameters, connectionProvider,
+        data);
     if (expType == ExportType.HTML) {
       HttpSession session = (HttpSession) parameters.get("HTTP_SESSION");
       if (session != null) {
@@ -309,6 +280,38 @@
   }
 
   /**
+   * Exports the report to a file.
+   * 
+   * @deprecated The compileSubreports parameter has no effect. Therefore, use
+   *             {@link ReportingUtils#exportJR(String, ExportType, Map, File, boolean, ConnectionProvider, JRDataSource, Map)}
+   *             instead.
+   */
+  public static void exportJR(String jasperFilePath, ExportType expType,
+      Map<String, Object> parameters, File target, boolean addProcessDefinitionParameters,
+      ConnectionProvider connectionProvider, JRDataSource data,
+      Map<Object, Object> additionalExportParameters, boolean compileSubreports) throws OBException {
+    exportJR(jasperFilePath, expType, parameters, target, addProcessDefinitionParameters,
+        connectionProvider, data, additionalExportParameters);
+  }
+
+  /**
+   * Exports the report to an output stream.
+   * 
+   * @deprecated The compileSubreports parameter has no effect. Therefore, use
+   *             {@link ReportingUtils#exportJR(String, ExportType, Map, OutputStream, boolean, ConnectionProvider, JRDataSource, Map)}
+   *             instead.
+   */
+  @Deprecated
+  public static void exportJR(String jasperFilePath, ExportType expType,
+      Map<String, Object> parameters, OutputStream outputStream,
+      boolean addProcessDefinitionParameters, ConnectionProvider connectionProvider,
+      JRDataSource data, Map<Object, Object> additionalExportParameters, boolean compileSubreports)
+      throws OBException {
+    exportJR(jasperFilePath, expType, parameters, outputStream, addProcessDefinitionParameters,
+        connectionProvider, data, additionalExportParameters);
+  }
+
+  /**
    * Saves a pre-compiled report into a file.
    * 
    * @param jasperPrint
@@ -930,14 +933,24 @@
   /**
    * Generates a compiled, translated and filled report into a JasperPrint object.
    * 
+   * @deprecated The compileSubreports parameter has no effect. Therefore, use
+   *             {@link ReportingUtils#generateJasperPrint(String, Map, ConnectionProvider, JRDataSource)}
+   *             instead.
+   */
+  @Deprecated
+  public static JasperPrint generateJasperPrint(String jasperFilePath,
+      Map<String, Object> parameters, boolean compileSubreports,
+      ConnectionProvider connectionProvider, JRDataSource data) throws OBException {
+    return generateJasperPrint(jasperFilePath, parameters, connectionProvider, data);
+  }
+
+  /**
+   * Generates a compiled, translated and filled report into a JasperPrint object.
+   * 
    * @param jasperFilePath
    *          The path to the JR template of the report.
    * @param parameters
    *          The parameters to be sent to Jasper Report.
-   * @param compileSubreports
-   *          A flag to indicate if the sub-reports of the report should be compiled too. If true,
-   *          the sub-report jrxml files should be placed in the same folder as the main report and
-   *          their name should start with SUBREP_
    * @param connectionProvider
    *          A connection provider in case the report needs it.
    * @param data
@@ -948,8 +961,8 @@
    *           error message.
    */
   public static JasperPrint generateJasperPrint(String jasperFilePath,
-      Map<String, Object> parameters, boolean compileSubreports,
-      ConnectionProvider connectionProvider, JRDataSource data) throws OBException {
+      Map<String, Object> parameters, ConnectionProvider connectionProvider, JRDataSource data)
+      throws OBException {
     long t1 = System.currentTimeMillis();
     try {
       setReportFormatFactory(parameters);
@@ -963,12 +976,9 @@
 
       String language = OBContext.getOBContext().getLanguage().getLanguage();
       JasperReport jReport;
-      if (compileSubreports && connectionProvider != null) {
-        jReport = compiledReportManager.compileReportWithSubreports(jasperFilePath, language,
-            parameters, connectionProvider);
-      } else {
-        jReport = compiledReportManager.compileReport(jasperFilePath, language);
-      }
+
+      jReport = compiledReportManager.compileReportWithSubreports(jasperFilePath, language,
+          parameters, connectionProvider);
 
       ReportFiller reportFiller = new ReportFiller(jReport, parameters);
       if (connectionProvider != null) {
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Thu May 17 19:30:38 2018 +0000
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Fri May 18 12:42:38 2018 +0200
@@ -1247,13 +1247,13 @@
         localExportParameters.put(ReportingUtils.IMAGES_URI, localAddress
             + "/servlets/image?image={0}");
         ReportingUtils.exportJR(localStrReportName, expType, localDesignParameters, os, false,
-            readOnlyCP, data, localExportParameters, renderJRShouldCompileSubreports());
+            readOnlyCP, data, localExportParameters);
       } else if (expType != ExportType.XML) {
         reportId = UUID.randomUUID();
         File outputFile = new File(globalParameters.strFTPDirectory + "/" + localStrFileName + "-"
             + (reportId) + "." + localStrOutputType);
         ReportingUtils.exportJR(localStrReportName, expType, localDesignParameters, outputFile,
-            false, readOnlyCP, data, localExportParameters, renderJRShouldCompileSubreports());
+            false, readOnlyCP, data, localExportParameters);
         response.setContentType("text/html;charset=UTF-8");
         response.setHeader("Content-disposition", "inline" + "; filename=" + localStrFileName + "-"
             + (reportId) + ".html");
@@ -1297,19 +1297,6 @@
   }
 
   /**
-   * This method should be overridden by those classes which want to compile the sub-reports when
-   * invoking renderJR. Note that the sub-reports to be compiled will be the .jrxml files placed in
-   * the same folder as the main report and whose related parameter name starts with <b>SUBREP_</b>.
-   * By default, this method returns {@code false}.
-   * 
-   * @return {@code true} if renderJR should use the reporting engine to compile the sub-reports
-   *         automatically. Otherwise, this method should return {@code false}.
-   */
-  protected boolean renderJRShouldCompileSubreports() {
-    return false;
-  }
-
-  /**
    * Saves the file and request for download. This approach is required to close the loading pop-up
    * window.
    */
--- a/src/org/openbravo/common/actionhandler/CashflowForecastReportActionHandler.java	Thu May 17 19:30:38 2018 +0000
+++ b/src/org/openbravo/common/actionhandler/CashflowForecastReportActionHandler.java	Fri May 18 12:42:38 2018 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2016-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2016-2018 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -27,8 +27,6 @@
 
 import javax.servlet.ServletException;
 
-import net.sf.jasperreports.engine.JRDataSource;
-
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateFormatUtils;
 import org.codehaus.jettison.json.JSONObject;
@@ -45,6 +43,8 @@
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.service.db.DalConnectionProvider;
 
+import net.sf.jasperreports.engine.JRDataSource;
+
 /**
  * Cashflow Forecast Action Handler for the Process Definition
  */
@@ -121,11 +121,6 @@
     }
   }
 
-  @Override
-  protected boolean isCompilingSubreports() {
-    return true;
-  }
-
   private Map<String, Object> obtainLinesFieldProvider(CashflowForecastData[] dataSummary,
       String strDatePlanned, boolean breakByDate, VariablesSecureApp vars, ConnectionProvider conn)
       throws ServletException {
--- a/src/org/openbravo/erpCommon/utility/reporting/ReportManager.java	Thu May 17 19:30:38 2018 +0000
+++ b/src/org/openbravo/erpCommon/utility/reporting/ReportManager.java	Fri May 18 12:42:38 2018 +0200
@@ -110,7 +110,7 @@
               + Utility.messageBD(_connectionProvider, "Invoice", language));
     }
     try {
-      jasperPrint = ReportingUtils.generateJasperPrint(templateFile, designParameters, true,
+      jasperPrint = ReportingUtils.generateJasperPrint(templateFile, designParameters,
           _connectionProvider, null);
     } catch (final Exception exception) {
       log4j.error(exception.getMessage());
--- a/src/org/openbravo/erpReports/RptM_Requisition.java	Thu May 17 19:30:38 2018 +0000
+++ b/src/org/openbravo/erpReports/RptM_Requisition.java	Fri May 18 12:42:38 2018 +0200
@@ -63,11 +63,6 @@
     renderJR(vars, response, null, "pdf", parameters, null, null);
   }
 
-  @Override
-  protected boolean renderJRShouldCompileSubreports() {
-    return true;
-  }
-
   public String getServletInfo() {
     return "Servlet that presents the RptMRequisitions seeker";
   } // End of getServletInfo() method