Dozer: map single field to Set - java

How do you map a single field into a Set in Dozer?
I have a class like:
class FooDTO {
private IdDto bar;
private IdDto baz;
}
class FooDomainObject {
private List<Id> ids;
}
I'd like to map bar and baz into the ids list, but I can't get it to do this.

I found this on the Dozer support list:
http://sourceforge.net/projects/dozer/forums/forum/452530/topic/1557144
Basically, you use this syntax:
<field>
<a>bar</a>
<b>ids[0]</b>
<b-hint>org.foo.Id</b-hint>
</field>
<field>
<a>baz</a>
<b>ids[1]</b>
<b-hint>org.foo.Id</b-hint>
</field>

Is there a way to do sth. like this :
<mapping>
<class-a>SourceObject</class-a>
<class-b>blaObject</class-b>
<field>
<a>sourceObjectSubObject[standardID].fielda</a>
<b>blaDestField</b>
</field>
</mapping>
Where the standardID is a field in the sourceObject,
and the sourceObjectSubObject is a List<sourceObjectSubObject>.

Related

Mapping Page of MyObject to Page of MyObjectDTO

I use camel-dozer for mapping MyObject to MyObjectDTO in my project. Spring repository return Page<MyObject>. I need to mapping Page<MyObject> to Page<MyObjectDTO>. Is exist nice way for this mapping without iteration Page.content and convert for each item?
I mapping single object this way:
dozerBeanMapping.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd">
<mapping>
<class-a>ru.test.MyObject</class-a>
<class-b>ru.test.MyObjectDTO</class-b>
<field>
<a>myField</a>
<b>testField</b>
</field>
</mapping>
</mappings>
RestRoute.java
rest("/search").description("")
.get("/{id}")
.consumes("application/json").to("direct:getMyObjectByID")
from("direct:getMyObjectByID")
.routeId("direct:getMyObjectByID")
.bean("myObjectRepository", "getMyObjectById(${header.id})")
.to("dozer:transformMyObjectDTO?mappingFile=dozerBeanMapping.xml&targetModel=ru.test.MyObjectDTO")
My temporary horrible solution: return immediately list of DTO from Spring Data repository.
#Repository("myObjectRepository")
public interface MyObjectRepository extends CrudRepository<MyObject, Integer> {
#Query(value = "SELECT new ru.test.MyObjectDTO(l.id, l.otherfields)" +
" from MyObject l where l.otherObject=:otherObject")
Page<MyObjectDTO> getAllByOtherObject(#Param("otherObject") OtherObject otherObject, Pageable pageable);
}

Converting j8583 object having one getter with params in Dozer

I have an IsoMessage object (https://github.com/chochos/j8583/blob/master/src/main/java/com/solab/iso8583/IsoMessage.java) that has an internal array which I can only access through a getField(int) method.
public class IsoMessage {
#SuppressWarnings("rawtypes")
private IsoValue[] fields = new IsoValue[129];
.........
.........
.........
/** Returns the IsoValue for the specified field. First real field is 2. */
#SuppressWarnings("unchecked")
public <T> IsoValue<T> getField(int field) {
return fields[field];
}
I need to read all the attributes stored on the fields array, by calling getField(param Number), and move them to a new object that has a Map, and want to achieve this using dozer.
the object that I need to translate to:
public class TransactionInstance implements Serializable {
private static final long serialVersionUID = 3429335891821913088L;
private String transactionName;
private Map<String, String> parameters;
I was experimenting with this dozer configuration hoping to get the field 1 from my isoMessage object
<mapping map-id="a">
<class-a>com.solab.iso8583.IsoMessage</class-a>
<class-b>j8583.example.TransactionInstance</class-b>
<field>
<a get-method="getField" key="1">field</a>
<b map-set-method="put">parameters</b>
</field>
</mapping>
But I'm stuck at getting the value from the original object with this exception:
Exception in thread "main" org.dozer.MappingException: No read or write method found for field (field) in class (class com.solab.iso8583.IsoMessage)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.determinePropertyType(GetterSetterPropertyDescriptor.java:319)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.getPropertyType(GetterSetterPropertyDescriptor.java:76)
at org.dozer.fieldmap.MapFieldMap.determineActualPropertyType(MapFieldMap.java:170)
at org.dozer.fieldmap.MapFieldMap.getSrcFieldValue(MapFieldMap.java:95)
I was checking this post https://github.com/DozerMapper/dozer/issues/111 and How to pass `this` to Dozer field mapping? bus still stuck in the same place, also I was wondering if I can achieve this by using the API so I can tell dynamically which fields I want to get from the original bean
I'm not familiar with Dozer, but field 1 is the bitmap. getField(1) returns null.
I finally foud the rigth mapping using the capability that dozer has to access the internal objects directly (http://dozer.sourceforge.net/documentation/custommethods.html).
<mapping>
<class-a is-accessible="true">com.solab.iso8583.IsoMessage</class-a>
<class-b>j8583.example.TransactionInstance</class-b>
<field>
<a>fields[3]</a>
<b set-method="addParameter" map-set-method="addParameter" key="field3">parameters
</b>
</field>
</mapping>

How to get first element of a List in JasperReports?

I have an object with a list of nested objects. I want to get just the first element of the list and show one of it's properties.
Example:
public class Person {
List<Phone> phones;
}
public class Phone {
String type;
String number;
}
Here I only want to get the persons first phone (phones.get(0) in java), and show the phone.numer attribute.
I started as follows, which work, BUT shows ANY phone numbers:
<field name="phones" class="java.util.List"/>
<jr:list printOrder="Vertical">
<datasetRun subDataset="Dataset1">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{phones})]]></dataSourceExpression>
</datasetRun>
<jr:listContents>
<textField>
<textFieldExpression><![CDATA[$F{number}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
I also tried the following approach:
<field name="phones" class="java.util.List" />
<field name="phoneFirst" class="my.package.Phone">
<fieldDescription><![CDATA[$F{phones}.get(0)]]></fieldDescription>
</field>
<field name="phoneFirstNumber" class="java.lang.String">
<fieldDescription><![CDATA[$F{phoneFirst}.getNumber()]]></fieldDescription>
</field>
Result:
net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : $F{phones}.get(0)
So, how can I tell JasperReports to just take the first element of the collection?
I would do this in Java:
public class Person {
List<Phone> phones;
...
public Phone getFirstPhone() {
if(this.phones != null) {
return this.phones.get(0);
}
return null;
}
...
}
and then something like this in the JRXML:
<field name="firstPhoneNumber" class="java.lang.String">
<fieldDescription><![CDATA[$F{firstPhone}.getNumber()]</fieldDescription>
</field>

Dozer: Map a field to function output

I am using Dozer to do object Mapping. Everything works reaaly well just that I'm not able to map this particular thing.
<mapping>
<class-a>User</class-a>
<class-b>UAUserBean</class-b>
<field>
<a>RightLst.Right</a>
<b>Rights</b>
<a-hint>Right</a-hint>
<b-hint>UARightBean</b-hint>
</field>
<field>
<a>RightLst.NumInLst</a>
<b>Rights.length</b>
</field>
</mapping>
//here RightLst is an object of a class and numInLst (int prop)
//rights is an array of objects
what i want to do is
lUser.getRightLst().setNumInLst(uaUserBean.getRights().length);
Any suggestions??
Thanks in advance.
User{
protected RightLst rightLst;
}
RightLst{
protected Integer numInLst;
protected Collection right = new ArrayList();
}
public class UAUserBean{
private UARightBean[] rights;
}
When you do this:
...
<b>rights.length</b>
</field>
Dozer will try to access the first position of the rights array and call the getter for the length property on an instance of UARightBean (which is the type of the array), obviously the length property doesn't exist in UARightBean and Dozer will throw an Exception.
I suggest to create a getter method in UAUserBean to return the length of the rights property, it would look like this:
class UAUserBean {
...
public int getRightsLength() {
return rights != null ? rights.length : 0;
}
}
Mapping file:
<class-a>User</class-a>
<class-b>UAUserBean</class-b>
<field>
<a>rightLst.numInLst</a>
<b>rightsLength</b>
</field>
If you can't modify UAUserBean, your last option would be a custom converter from UARightBean[] to Integer, but it would look ugly.

Java/JAXB: Unmarshall XML elements with same name but different attribute values to different class members

I am trying to parse XML that has several "Fields" elements to different class members according to one of their attributes.
Here is the XML:
<Series>
<Fields type="SelectedFields" operation="SUM">
<Field name="Remaining" />
<Field name="Invested" />
</Field>
<Fields type="FirstSelectedFields" operation="SUM">
<Field name="Estimated" />
</Field>
</Series>
And here is the java class it should be mapped to:
public class APMSeries {
private List<Field> selectedFields;
private List<Field> firstSelectedFields;
}
Can anyone tell me how can I set the Fields element with attribute type="SelectedFields" to the selectedFields member and the Fields element with the attribute type="FirstSelectedFields" to the firstSelectedFields member?
public class APMSeries {
#XmlElementWrapper(name="SelectedFields")
private List<Field> selectedFields;
#XmlElementWrapper(name="FirstSelectedFields")
private List<Field> firstSelectedFields;
}

Categories

Resources