I have a requirement for example where I am using SuperCSV to read a csv file and map to object.
SuperCSV has a requirement where if the header specifies a field name "firstName" it needs to have setFirstName() method in the class else it throws an exception.
Now if I use Groovy beans then i don't need to declare all these methods just declaring the variables should work fro SuperCSV.
But I was looking for a more dynamic solution where we don't even have to declare those variables.
For example just have an object created on fly and with groovy's dynamic method creation feature SuperCSV will be able to find the setters.
I looked at various options like Expando,ExpandoMetaClass but these did not server my purpose.
Any answer will be appreciated.
Here is the code snippet that worked for me and can be really helpful in reducing lot of code and unnecessary logic:
static def testBeanReader()
{
ICsvBeanReader beanReader = null;
try
{
beanReader = new CsvBeanReader(new FileReader("src/test.csv"),
CsvPreference.STANDARD_PREFERENCE);
}
catch(Exception e)
{
}
final String[] header = VirtualObject.getHeaders();
final CellProcessor[] processors = VirtualObject.getProcessors();
//Class c1 = createNewClass()
//String s = createClass()
def list = ["name", "age"]
def c = (new GroovyShell().evaluate(createClass(list)) as Class)
//println(c.methods.grep {it.name.startsWith("get")})
GroovyObject groovyObject = (GroovyObject)(beanReader.read(c, header, processors))
Object[] args = {};
println(groovyObject.getProperty("name"))
}
static def createClass(def list)
{
String classDeclaration = "\nclass Test {\n"
list.each
{
classDeclaration+="def $it\n"
}
classDeclaration+= """
}
return Test.class
"""
return classDeclaration
}
This for supercsv thing but can be used for a generic java object with few changes in syntax
Can't you use an Groovy shell, to construct these classes dynamically.
It's not secure, but it will create Java compatible class on the fly.
I'm not familiar with SuperCSV, but I think it should use smth like reflexion, when Expando or MetaClass solutions will use Groovy Meta-object protocol.
GroovyShell(or GroovyClassLoader) will be able to create normal class, with working Reflexion.
EDITED: Illustrate dynamic nature of generated class. And that we are creating class source first(as we want, from runtime information, from your CSV headers), and then use it.