Re: [Wicket-user] wicket-contrib-jaspperreports JRResource optimalization
Btw, there's a problem with current implementation. After the report is done, you can't generated another report (e.g. clicking twice on the same link). Because datasource is the same and it's at the end. So all further calls to datasource.next() will result in false. The solution now is either: a) having datasource that can automatically rewind - not a big deal, but perhaps problem when you have result set data source b) using getDataSource as data source factory. I think there should be more explicit way to specify data source factory than overriding getDataSource. Or at least it should be mentioned in the javadoc? Any ideas? -Matej Matej Knopp wrote: Checked it out, I really like it. Mine was just a quick hack ;) -Matej Eelco Hillenius wrote: 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 --- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628alloc_id=16845op=click ___ Wicket-user mailing list Wicket-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wicket-user
Re: [Wicket-user] wicket-contrib-jaspperreports JRResource optimalization
Uh, I forgot, PdfDataSource is final, so option B is not even an option now ;) Matej Knopp wrote: Btw, there's a problem with current implementation. After the report is done, you can't generated another report (e.g. clicking twice on the same link). Because datasource is the same and it's at the end. So all further calls to datasource.next() will result in false. The solution now is either: a) having datasource that can automatically rewind - not a big deal, but perhaps problem when you have result set data source b) using getDataSource as data source factory. I think there should be more explicit way to specify data source factory than overriding getDataSource. Or at least it should be mentioned in the javadoc? Any ideas? -Matej Matej Knopp wrote: Checked it out, I really like it. Mine was just a quick hack ;) -Matej Eelco Hillenius wrote: 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 --- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628alloc_id=16845op=click ___ Wicket-user mailing list Wicket-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wicket-user --- This SF.Net email is sponsored by the JBoss Inc. Get Certified Today Register for a JBoss Training Course. Free Certification Exam for All Training Attendees Through End of 2005. For more info visit: http://ads.osdn.com/?ad_id=7628alloc_id=16845op=click ___ Wicket-user mailing list Wicket-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wicket-user
Re: [Wicket-user] wicket-contrib-jaspperreports JRResource optimalization
Okay, once more, without antivirus message attached to java file and one unnecessary try/catch block :) 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 __ NOD32 1.1295 (20051120) Information __ This message was checked by NOD32 antivirus system. http://www.eset.com /* * $Id: JRResource.java,v 1.1 2005/09/20 20:00:46 eelco12 Exp $ * $Revision: 1.1 $ * $Date: 2005/09/20 20:00:46 $ * * == * Licensed 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 framework.wicket.jr; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; import java.net.URL; import java.sql.Connection; import java.util.Map; import net.sf.jasperreports.engine.JRAbstractExporter; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.util.JRLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import wicket.WicketRuntimeException; import wicket.protocol.http.WebResponse; import wicket.resource.DynamicByteArrayResource; /** * Base class for jasper reports resources. * * @author Eelco Hillenius */ public abstract class JRResource extends DynamicByteArrayResource { /** logger. */ private static Log log = LogFactory.getLog(JRResource.class); /** * Provides JDBC connection. */ public static interface IDatabaseConnectionProvider { /** * Gets a JDBC connection to use when filling the report. * * @return a JDBC connection */ Connection get(); /** * Called when the report is generated and the connection can be * released again. */ void release(); } /** the compiled report this resource references. */ private JasperReport jasperReport; /** the report parameters. */ private Map reportParameters; /** the datasource if any for filling this report. */ private JRDataSource reportDataSource; /** the connection provider if any for filling this report. */ private IDatabaseConnectionProvider connectionProvider; private static abstract class JasperReportInitializer { abstract JasperReport createJasperReport() throws JRException; }; /** initializer for delayed report initialization. */ private JasperReportInitializer initializer; /** * When set, a header 'Content-Disposition: attachment; * filename=${fileName}' will be added to the response, resulting in a * download dialog. No magical extensions are added, so you should make sure * the file has the extension you want yourself. */ private String fileName; /** * Construct without a report. You must provide a report before you can use * this resource. */ public JRResource() { super(); setCacheable(false); } /** * Construct. * * @param report *the report input stream */ public JRResource(final InputStream report) { super(); setCacheable(false); initializer = new JasperReportInitializer() { JasperReport createJasperReport() throws JRException { return (JasperReport)
Re: [Wicket-user] wicket-contrib-jaspperreports JRResource optimalization
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 - 1.1 +++ src/java/wicket/contrib/jasperreports/JRResource.java 21 Nov 2005 18:36:46 - @@ -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 + { +