By: Maulin Shah - maulinshah
POJOs that contain POJO's
2004-09-01 03:07
i use hibernate and POJO's extensively.
i've started using JR yesterday, so please forgive me if i missed something obvious.
i could not find a way to call pojo's pojo's field, for example. and it seems fields may not have a "." in their name (it breaks FieldFill i guess?)
so i wrote a small utility JRDataSource to handle this. hope it helps someone else! (i banged my head on this problem for a couple hours, and then realized i could solve the problem with this class that i wrote in ten minutes! doh!)
/*
* Created on Aug 31, 2004
*
*/
package org.baylormedicine.ram.reports;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
/**
* @author Maulin Shah
*
* utlitiy class to use with JasperReports to allow for
* more complext beans to be used.
*
* the problem with JasperReports is that the field names
* may not contain dots
*
* I have lots of POJO's that are composed of other POJO's
* and i am used to being able to set (for example with struts layout
* or displaytag for JSP) a field value with one of the composed POJO's values.
*
* so this class takes the field name from JasperReports.
* It parses it on TWO underscores (i guess i could make this a a configuration)
* instead of dots and lets you return as deep a value as you want
*
* i.e. person.name.firstName would have been ideal,
* but instead, in your JasperReports xml you need to write
* person__name__firstName and you'll get the same behavior.
*
*
* enjoy!
*/
public class RAMReportDataSource implements JRDataSource {
private Collection list;
private Iterator iterator;
private Object currentItem;
/**
*
*/
public RAMReportDataSource(Collection c) {
super();
this.list = c;
this.iterator = c.iterator();
}
public RAMReportDataSource(Map map) {
super();
this.list = map.values();
this.iterator = this.list.iterator();
}
/* (non-Javadoc)
* @see net.sf.jasperreports.engine.JRDataSource#next()
*/
public boolean next() throws JRException {
if (iterator == null) return false;
if (iterator.hasNext()) {
currentItem = iterator.next();
return true;
}
return false;
}
/**
* class will look through each item until
* it finds the getter
*/
public Object getFieldValue(JRField name) throws JRException {
String fields[] = name.getName().split("__");
Object currentObject = currentItem;
for (int i=0; i<fields.length; i++) {
String getterName = "get" + fields.substring(0, 1).toUpperCase() + fields.substring(1);
try {
Method getter = currentObject.getClass().getMethod(getterName, null);
currentObject = getter.invoke(currentObject, null);
} catch (NoSuchMethodException e ) {
throw new JRException("could not find getter for " + name.getName(), e);
} catch (Exception e) {
throw new JRException(e);
}
}
if (name.getValueClass().equals(java.lang.String.class))
return currentObject.toString();
return currentObject;
}
}
By: Mykel Alvis - evilarchitect
RE: POJOs that contain POJO's
2004-09-01 06:29
A fine implementation. Another way would be to use the beanutils to transfer your hibernated data classes to maps and use the field names as the keys in the datasource.
By: Maulin Shah - maulinshah
RE: POJOs that contain POJO's
2004-09-02 04:40
okay, the above was a hack, admittedly. and it got ugly very quickly -- hard to type two underscores, when you name a field wrong you have to change it two places -- the field name and the $F{} area (i hate that). so i've improved this a bit.
now i ignore the name of the field in my JRDataSource. i now create a list of field name/descriptions that the report designer is given. he can use any of the names in the list as a field in his $F{} statements. the description is used as the instructions on how to get the data. so i can use dots again, which i am used to typing quite quickly (eg name.firstName), and i have enhanced it so i can even pass multiple fields with the description (sort of a pseudo-EL) and even use a decorator... pretty sweet!.besides, i hate doing the report layout -- so now i just hand the designer a list of field names (that obviously must be somewhat self-explanatory) and then i create all the descriptions as instructions to the datasource on how to get the data.
By: Maulin Shah - maulinshah
RE: POJOs that contain POJO's
2004-09-09 04:58
so now i've been having fun learning tapestry for the last week or so for my front end, and have therefore been introduced to the wonderful world of OGNL.
I think we should create an OGNL-Jasper project to all Jasper users to populate their data with object graphs with a simple standard like OGNL. is their interest in this? Are we sure nothing similar exists?
POJOs that contain POJO's
2004-09-01 03:07
i use hibernate and POJO's extensively.
i've started using JR yesterday, so please forgive me if i missed something obvious.
i could not find a way to call pojo's pojo's field, for example. and it seems fields may not have a "." in their name (it breaks FieldFill i guess?)
so i wrote a small utility JRDataSource to handle this. hope it helps someone else! (i banged my head on this problem for a couple hours, and then realized i could solve the problem with this class that i wrote in ten minutes! doh!)
/*
* Created on Aug 31, 2004
*
*/
package org.baylormedicine.ram.reports;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
/**
* @author Maulin Shah
*
* utlitiy class to use with JasperReports to allow for
* more complext beans to be used.
*
* the problem with JasperReports is that the field names
* may not contain dots
*
* I have lots of POJO's that are composed of other POJO's
* and i am used to being able to set (for example with struts layout
* or displaytag for JSP) a field value with one of the composed POJO's values.
*
* so this class takes the field name from JasperReports.
* It parses it on TWO underscores (i guess i could make this a a configuration)
* instead of dots and lets you return as deep a value as you want
*
* i.e. person.name.firstName would have been ideal,
* but instead, in your JasperReports xml you need to write
* person__name__firstName and you'll get the same behavior.
*
*
* enjoy!
*/
public class RAMReportDataSource implements JRDataSource {
private Collection list;
private Iterator iterator;
private Object currentItem;
/**
*
*/
public RAMReportDataSource(Collection c) {
super();
this.list = c;
this.iterator = c.iterator();
}
public RAMReportDataSource(Map map) {
super();
this.list = map.values();
this.iterator = this.list.iterator();
}
/* (non-Javadoc)
* @see net.sf.jasperreports.engine.JRDataSource#next()
*/
public boolean next() throws JRException {
if (iterator == null) return false;
if (iterator.hasNext()) {
currentItem = iterator.next();
return true;
}
return false;
}
/**
* class will look through each item until
* it finds the getter
*/
public Object getFieldValue(JRField name) throws JRException {
String fields[] = name.getName().split("__");
Object currentObject = currentItem;
for (int i=0; i<fields.length; i++) {
String getterName = "get" + fields.substring(0, 1).toUpperCase() + fields.substring(1);
try {
Method getter = currentObject.getClass().getMethod(getterName, null);
currentObject = getter.invoke(currentObject, null);
} catch (NoSuchMethodException e ) {
throw new JRException("could not find getter for " + name.getName(), e);
} catch (Exception e) {
throw new JRException(e);
}
}
if (name.getValueClass().equals(java.lang.String.class))
return currentObject.toString();
return currentObject;
}
}
By: Mykel Alvis - evilarchitect
RE: POJOs that contain POJO's
2004-09-01 06:29
A fine implementation. Another way would be to use the beanutils to transfer your hibernated data classes to maps and use the field names as the keys in the datasource.
By: Maulin Shah - maulinshah
RE: POJOs that contain POJO's
2004-09-02 04:40
okay, the above was a hack, admittedly. and it got ugly very quickly -- hard to type two underscores, when you name a field wrong you have to change it two places -- the field name and the $F{} area (i hate that). so i've improved this a bit.
now i ignore the name of the field in my JRDataSource. i now create a list of field name/descriptions that the report designer is given. he can use any of the names in the list as a field in his $F{} statements. the description is used as the instructions on how to get the data. so i can use dots again, which i am used to typing quite quickly (eg name.firstName), and i have enhanced it so i can even pass multiple fields with the description (sort of a pseudo-EL) and even use a decorator... pretty sweet!.besides, i hate doing the report layout -- so now i just hand the designer a list of field names (that obviously must be somewhat self-explanatory) and then i create all the descriptions as instructions to the datasource on how to get the data.
By: Maulin Shah - maulinshah
RE: POJOs that contain POJO's
2004-09-09 04:58
so now i've been having fun learning tapestry for the last week or so for my front end, and have therefore been introduced to the wonderful world of OGNL.
I think we should create an OGNL-Jasper project to all Jasper users to populate their data with object graphs with a simple standard like OGNL. is their interest in this? Are we sure nothing similar exists?
0 Answers:
No answers yet