Thanks. Much better now. I implemented a couple of small changes on
top of it, please check out whether you agree (find the patch
attached).

Eelco

>
> Matej Knopp wrote:
> > Hi.
> >
> > There's a slight performace problem with JRResource, that it creates
> > JasperReport in it's constructor. I've 10 resource links on one page  so
> > it means that 10 JasperReports will be initialized everytime page is
> > created, even if none of them gets clicked. The performance penalty is
> > not small - 400ms.
> >  So I think the JasperReport should be initialized lazyly, only when
> > the  resource is really used.
> >  I've atached "fixed" JRResource, it may not be the best solution, but
> > it works for me. (Look in the constructor(s) to see how it works)
> >
> > -Matej
> >
Index: src/java/wicket/contrib/jasperreports/JRResource.java
===================================================================
RCS file: 
/cvsroot/wicket-stuff/wicket-contrib-jasperreports/src/java/wicket/contrib/jasperreports/JRResource.java,v
retrieving revision 1.1
diff -u -r1.1 JRResource.java
--- src/java/wicket/contrib/jasperreports/JRResource.java       20 Sep 2005 
20:00:46 -0000      1.1
+++ src/java/wicket/contrib/jasperreports/JRResource.java       21 Nov 2005 
18:36:46 -0000
@@ -21,6 +21,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.net.URL;
 import java.sql.Connection;
 import java.util.Map;
@@ -54,7 +55,7 @@
        /**
         * Provides JDBC connection.
         */
-       public static interface IDatabaseConnectionProvider
+       public static interface IDatabaseConnectionProvider extends Serializable
        {
                /**
                 * Gets a JDBC connection to use when filling the report.
@@ -70,8 +71,32 @@
                void release();
        }
 
-       /** the compiled report this resource references. */
-       private JasperReport jasperReport;
+       /**
+        * Factory class for lazy initialization of the jasper report.
+        */
+       private static interface JasperReportFactory extends Serializable
+       {
+               /**
+                * Create a jasper report instance.
+                * 
+                * @return the new jasper report instance.
+                * @throws JRException
+                */
+               JasperReport newJasperReport() throws JRException;
+       };
+
+       /** the connection provider if any for filling this report. */
+       private IDatabaseConnectionProvider connectionProvider;
+
+       /** factory for delayed report creation. */
+       private JasperReportFactory jasperReportFactory;
+
+       /**
+        * The compiled report this resource references. Made transient as we 
don't
+        * want our report to be serialized while we can recreate it at other
+        * servers at will using the factory.
+        */
+       private transient JasperReport jasperReport;
 
        /** the report parameters. */
        private Map reportParameters;
@@ -79,9 +104,6 @@
        /** the datasource if any for filling this report. */
        private JRDataSource reportDataSource;
 
-       /** the connection provider if any for filling this report. */
-       private IDatabaseConnectionProvider connectionProvider;
-
        /**
         * When set, a header 'Content-Disposition: attachment;
         * filename="${fileName}"' will be added to the response, resulting in a
@@ -106,18 +128,15 @@
         * @param report
         *            the report input stream
         */
-       public JRResource(InputStream report)
+       public JRResource(final InputStream report)
        {
-               super();
-               setCacheable(false);
-               try
+               this(new JasperReportFactory()
                {
-                       jasperReport = (JasperReport) 
JRLoader.loadObject(report);
-               }
-               catch (JRException e)
-               {
-                       throw new WicketRuntimeException(e);
-               }
+                       public JasperReport newJasperReport() throws JRException
+                       {
+                               return (JasperReport) 
JRLoader.loadObject(report);
+                       };
+               });
        }
 
        /**
@@ -126,18 +145,15 @@
         * @param report
         *            the report input stream
         */
-       public JRResource(URL report)
+       public JRResource(final URL report)
        {
-               super();
-               setCacheable(false);
-               try
-               {
-                       jasperReport = (JasperReport) 
JRLoader.loadObject(report);
-               }
-               catch (JRException e)
+               this(new JasperReportFactory()
                {
-                       throw new WicketRuntimeException(e);
-               }
+                       public JasperReport newJasperReport() throws JRException
+                       {
+                               return (JasperReport) 
JRLoader.loadObject(report);
+                       };
+               });
        }
 
        /**
@@ -146,27 +162,53 @@
         * @param report
         *            the report input stream
         */
-       public JRResource(File report)
+       public JRResource(final File report)
+       {
+               this(new JasperReportFactory()
+               {
+                       public JasperReport newJasperReport() throws JRException
+                       {
+                               return (JasperReport) 
JRLoader.loadObject(report);
+                       };
+               });
+       }
+
+       /**
+        * Construct.
+        * 
+        * @param jasperReportFactory
+        *            report factory for lazy initialization
+        */
+       private JRResource(JasperReportFactory jasperReportFactory)
        {
                super();
                setCacheable(false);
-               try
-               {
-                       jasperReport = (JasperReport) 
JRLoader.loadObject(report);
-               }
-               catch (JRException e)
-               {
-                       throw new WicketRuntimeException(e);
-               }
+
+               this.jasperReportFactory = jasperReportFactory;
        }
 
        /**
-        * Gets jasperReport.
+        * Gets jasperReport. This implementation uses an internal factory to 
lazily
+        * create the report. After creation the report is cached (set as the
+        * jasperReport property). Override this method in case you want to 
provide
+        * some alternative creation/ caching scheme.
         * 
         * @return jasperReport
         */
        public JasperReport getJasperReport()
        {
+               // if the report has not yet been initialized and can be, 
initialize it
+               if (jasperReport == null && jasperReportFactory != null)
+               {
+                       try
+                       {
+                               
setJasperReport(jasperReportFactory.newJasperReport());
+                       }
+                       catch (JRException e)
+                       {
+                               throw new WicketRuntimeException(e);
+                       }
+               }
                return jasperReport;
        }
 
@@ -282,6 +324,7 @@
 
        /**
         * Called by getData to obtain an exporter instance.
+        * 
         * @return an exporter instance
         */
        protected abstract JRAbstractExporter newExporter();
@@ -337,6 +380,7 @@
        protected JasperPrint newJasperPrint() throws JRException
        {
                final JasperPrint jasperPrint;
+
                JasperReport jasperReport = getJasperReport();
                Map reportParameters = getReportParameters();
                JRDataSource reportDataSource = getReportDataSource();
@@ -385,4 +429,4 @@
 
                }
        }
-}
+}
\ No newline at end of file

Reply via email to