Dozer mapping class A -> Class B - dozer

I have a confusion that I am mapping 2 objects via Dozer mapping. So one class A has typeCode and another class B has typeCode(same spelling) and isCashFund
I have written custom converter for typeCode => isCashfund but will it now not populate the typeCode of class B as now it is not one to one mapping.
<mapping>
<class-a>TsmfFund</class-a>
<class-b>Fund</class-b>
<field type="one-way">
<a>priceTypeSet.description</a>
<b>priceTypeSetDescription</b>
</field>
<field>
<a>currencyCode</a>
<b>currency</b>
</field>
<field type="one-way" custom-converter="FundTypeConverter">
<a>typeCode</a>
<b>cashFund</b>
</field>
</mapping>

Related

Writing Flat file using beanio (beanio.org) . pojo's have parent class

I need to sort pojo of different data type like Student,employee,patient using age and store it into array. Then write it to flat file using beanio.
By json i am sending request which can have array of student,employee and patient .I have 3 pojo at java side like student,employee,patient to store data from json request.
i am able to merge and then sort all array of objects like student,employee,patient into single array of class which is base class of student,employee,patient like Human. Human class i have to make so i can sort all 3 child class using Comparator by property age.
class SortbyAge implements Comparator<Human>
{
// Used for sorting in ascending order of
// age
public int compare(Human a, Human b)
{
return a.getAge() - b.getAge();
}
}
By here everything is fine .
I am able to sort data depending on age and store it into Human Array.
problem is when i am writing sorted data to flat file using beanio .
**when i am writing data to Flat file i am getting exception below exception
org.beanio.BeanWriterException: Bean identification failed: no record or group mapping for bean class 'class [Lcom.amex.ibm.model.Human;' at the current position**
i have written all 4 tags into xml file like below.
<record name="student" class="com.amex.ibm.model.Student" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="employee" class="com.amex.ibm.model.Employee" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="patient" class="com.amex.ibm.model.Patient" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="human" class="com.amex.ibm.model.Human" occurs="0+" maxLength="unbounded">
<field name="age" length="3"/>
</record>
How to define Parent class mapping in bean IO??
The problem you are seeing is that BeanIO doesn't know how to map an array of type Human You need to pass each of the individual objects to BeanIO to write it out to your file. Try this, by looping over your array and then pass each of the objects to BeanIO.
Change
b.write(listFinalArray);
to
for (int i = 0; i < listFinalArray.length; i++) {
b.write(listFinalArray[i]);
}
or less typing:
for (final Human human : listFinalArray) {
b.write(human);
}

Indexed getter only in Dozer

I'm struggling with a mapping in Dozer. The basic structure of my classes is this:
class Foo {
private String someString;
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
}
and the interesting part:
class Bar {
// note that no field is declared
public String[0] getSomeBarString() {
// This returns an array where the acctually desired string is a index 0
}
public void setSomeBarString(String someString) {
// stores the string otherwise
}
}
Compensating the absence of a field and the differently named getter/setter methods was quite easy:
<mapping>
<class-a>Foo</class-a>
<class-b>Bar</class-b>
<field>
<a>someString</a>
<b get-method="getSomeBarString" set-method="setSomeBarString">someBarString</b>
</field>
</mapping>
From my understanding I could even omitt get-method and set-method as there is no field access by default.
My problem is that the getter is indexed and the setter isn't. I've already read about indexed property mapping but it does it both ways. Is there a way to make only one direction indexed? E.g. would get-method="getSomeBarString[0]" work?
After a night of sleep I got an idea myself. I just define two one way mappings and make one of them indexed. It also turns out indexing is defined the same way (after the property name) even if you declare a different get-method or set-method.
<mapping type="one-way">
<class-a>Foo</class-a>
<class-b>Bar</class-b>
<field>
<a>someString</a>
<b set-method="setSomeBarString">someBarString</b>
</field>
</mapping>
<mapping type="one-way">
<class-a>Bar</class-a>
<class-b>Foo</class-b>
<field>
<a get-method="getSomeBarString">someBarString[0]</a>
<b>someString</b>
</field>
</mapping>

Dozer mapping of Property of a Object in the list to another list with hints

I have the following scenario of Mapping
Class Contact {
List<SimpleCode> marketSectorList;
}
Class SimpleCode {
protected String code;
protected String label;
}
Class ContactTarget {
List<String> marketSectors;
}
The following map is not working
<mapping>
<class-a>Contact</class-a>
<class-b>ContactTarget</class-b>
<field>
<a>marketSectorList</a>
<b>marketSectors</b>
<b-hint>java.lang.String</b-hint>
</field>
The mapping is not working. Please note that I can not change the classes and I would like to solve by using hints not by custom mappers
You could try to create a mapping from SimpleCode to java.lang.String so dozer knows how to map those objects. Something similar to this:
<mapping>
<class-a>SimpleCode</class-a>
<class-b>java.lang.String</class-b>
<field>
<a>code</a>
<b>this</b>
</field>
</mapping>
I hope it helps.

Dozer - how to map base classes only

I have ClassA, ClassB, ClassC where:
ClassB extends ClassA
ClassC extends ClassA
I wanted to map only ClassA in my dozer configuration and wrote this:
<mapping wildcard="false">
<class-a>ClassA</class-a>
<class-b>ClassA</class-b>
<field custom-converter="MyConverter">
<a>value</a>
<b>value</b>
</field>
</mapping>
However, when I do mapper.map(instB, instB) the custom converter from ClassA never gets called.
Thank you!

Custom Class for JasperReports field

I would like to create a report with a custom class as follows:
public class Class1 {
String cl1_f1;
String cl1_f2;
}
public class Class2 {
String cl2_f1;
String cl2_f2;
Class1 cl1_ob1;
}
Now I pass Class2 in the report through fields and JRBeanCollectionDataSource.
<subDataset name="myitems">
<field name="cl2_f1" class="java.lang.String"/>
<field name="cl2_f2" class="java.lang.String"/>
**<field name="cl1_ob1" class="Class2"/>**
</subDataset>
For the third parameter, I would like to mention one of its fields. For example: cl1_ob1.cl1_f1.
How can I accomplish this?
In the Jasper report design, the field will be defined as below:
<field name="cl1_ob1" class="Class1">
<fieldDescription><![CDATA[cl1_ob1]]></fieldDescription>
</field>
And the 2 variables of Class1 can be accessed by calling the getter method (if there is one) or you can use the variable directly, depending on it's access privileges. For Example, $F{cl1_ob1}.getCl1_f1() can be used as a text-field expression, as shown below:
<textField>
<reportElement x="36" y="26" width="235" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{cl1_ob1}.getCl1_f1()]]></textFieldExpression>
</textField>