2006 IR Open Discussion Posted August 18, 2006 Posted August 18, 2006 By: Juan Gil - delphiero Master-detail reports with Collection beans 2003-05-05 08:39 First, excuse my English. I'm Spanish. I wanted to use Jasper Report to create master-detail reports based on beans, instead of database connections. The datasource of the report is a collection of beans that have a property that is another collection of beans that i want to list in a subreport. Using JRBeanCollectionDataSource I could list main collection but i couldn't list the detail. I develop a new class, based on JRBeanCollectionDataSource with a new method, getDetailDataSource , to get a bean collection property like a JRDataSource. This way we can pass the detail datasource to the subreport. Here I include an simple implementation. this method could be included in the JRBeanCollectionDataSource but I expect your comments before do it. /****************************************************************************** * * If you need to create a master-detail report based on bean collections * you can use this class instead of JRBeanCollectionDataSource. This class * includes a new method, getCollectionProperty, that allows us to get a Collection * property as a JRDataSource and pass it to the detail subreport. * * How to use it ? * * 1. When loading the data to the report use the new class to hold the data. * * JRExtraBeanCollectionDataSource ds = new JRExtraBeanCollectionDataSource(<collection>); * jPrint = JasperManager.fillReport(jReport, parametros, ds); * * 2. In the report template use getDetailCollection of the REPORT_DATA_SOURCE * to pass the datasource to the detail report * * In the subreport's datasourceExpression, pass the detail collection to the * subreport like this : * * <dataSourceExpression>((header.base.JReports.data.JRExtraBeanCollectionDataSource)$P{REPORT_DATA_SOURCE}).getCollectionProperty("detalleNominaAdaptada")></dataSourceExpression> * * * ============================================================================ * The JasperReports License, Version 1.0 * ============================================================================ * * Copyright © 2001-2003 Teodor Danciu ([email protected]). All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by Teodor Danciu (http://jasperreports.sourceforge.net)." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The name "JasperReports" must not be used to endorse or promote products * derived from this software without prior written permission. For written * permission, please contact [email protected]. * * 5. Products derived from this software may not be called "JasperReports", nor * may "JasperReports" appear in their name, without prior written permission * of Teodor Danciu. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ============================================================================ * GNU Lesser General Public License * ============================================================================ * * JasperReports - Free Java report-generating library. * Copyright © 2001-2003 Teodor Danciu [email protected] * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * Teodor Danciu * 173, Calea Calarasilor, Bl. 42, Sc. 1, Ap. 18 * Postal code 741181, Sector 3 * Bucharest, ROMANIA * Email: [email protected] */ package header.base.JReports.data; import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; import dori.jasper.engine.JRDataSource; import dori.jasper.engine.JRException; import dori.jasper.engine.JRField; /** * */ public class JRExtraBeanCollectionDataSource implements JRDataSource { /** * */ protected Collection data = null; protected Iterator iterator = null; protected Object currentBean = null; /** * */ public JRExtraBeanCollectionDataSource(Collection beanCollection) { this.data = beanCollection; if (this.data != null) { this.iterator = this.data.iterator(); } } /** * */ public boolean next() throws JRException { boolean hasNext = false; if (this.iterator != null) { hasNext = this.iterator.hasNext(); if (hasNext) { this.currentBean = this.iterator.next(); } } return hasNext; } /** * */ public Object getFieldValue(JRField jrField) throws JRException { Object value = null; if (currentBean != null) { Class beanClass = currentBean.getClass(); String fieldName = jrField.getName(); fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); String methodName = "get" + fieldName; Method method = null; try { method = beanClass.getMethod(methodName, null); } catch (NoSuchMethodException e) { } if (method == null && jrField.getValueClass() == Boolean.class) { try { methodName = "is" + fieldName; method = beanClass.getMethod(methodName, null); } catch (NoSuchMethodException e) { } } if (method == null) { throw new JRException("Property getter method not found in bean for the field : " + fieldName); } else { try { value = method.invoke(currentBean, null); } catch (Exception e) { throw new JRException("Error retrieving field value from bean : " + methodName, e); } } } return value; } /************************************************************************ * getCollectionProperty */ public JRExtraBeanCollectionDataSource getDetailDataSource(String PropertyName) throws JRException { Object value = null; if (currentBean != null) { Class beanClass = currentBean.getClass(); String fieldName = PropertyName; fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); String methodName = "get" + fieldName; Method method = null; try { method = beanClass.getMethod(methodName, null); } catch (NoSuchMethodException e) { } if (method == null) { throw new JRException("Property getter method not found in bean for the field : " + fieldName); } else { try { value = method.invoke(currentBean, null); } catch (Exception e) { throw new JRException("Error retrieving field value from bean : " + methodName, e); } } } if (value instanceof Collection) { return new JRExtraBeanCollectionDataSource((Collection) value); } return null; } } By: Teodor Danciu - teodord RE: Master-detail reports with Collection beans 2003-05-06 00:22 Hi, I'm not sure you need this extra method since you can declare a report field of type java.lang.Object to retrieve the Collection member. You can construct the JRBeanCollectionDataSource for your subreport in the <dataSourceExpression> by casting your Object report field to Collection. But if it works like this for you, just let it be. Thank you, Teodor By: Juan Gil - delphiero RE: Master-detail reports with Collection beans 2003-05-06 07:21 Thanks a lot. I think that it isn't neccesary the new class. Your solution is better than mine.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now