Dozer - map class field to a flat representation - dozer

I've been googling and trying different dozer configuration options but so far couldn't find a simple solution...
Problem is as follow:
class A {
String test;
B test2;
}
class B {
String test3;
String test4;
}
class C {
String test;
String test3;
String test4;
}
Now I would like to map all of the fields from A (including B) to a flat representation in C.
Is it possible to map it using just configuration? The problem is that I need to map B in many different classes and I don't want to write a mapping like this for each of them:
<mapping>
<class-a>A</class-a>
<class-b>C</class-b>
<field>
<a>test2.test3</a>
<b>test3</b>
</field>
<field>
<a>test2.test4</a>
<b>test4</b>
</field>
</mapping>
Would appreciate a solution for that :)

The trick is to use mapping IDs and "this". You need to define caseB only once and can reuse it.
<mapping map-id="caseB">
<class-a>B</class-a>
<class-b>C</class-b>
<field>
<a>test3</a>
<b>test3</b>
</field>
<field>
<a>test4</a>
<b>test4</b>
</field>
</mapping>
<mapping>
<class-a>A</class-a>
<class-b>C</class-b>
<field map-id="caseB">
<a>test2</a>
<b>this</b>
</field>
</mapping>

found on dozer faq :
Can I map one field into another field that is nested n layers deep in the destination object?
Yes. Dozer supports dot notation for nested fields. As with other dozer field mappings, these are bi-directional.
<field>
<a>someNestedObj.someOtherNestedObj.someField</a>
<b>someOtherField</b>
</field>
dozer FAQ

Related

Value list smart filter bar field of smart table not present despite being configured

I'm having trouble creating a value list for a field in the smart filter bar of a smart table.
I have an entity set ApplicationsOverviewItemSet with the following entity type definition in SEGW:
The smart table has to display this entity set's data. In its smart filter bar I'd like there to be a value list for the statute property. I defined another entity set called ApplicationStatuteSet with this SEGW entity type definition:
This entity set should be a list of possible statute values and their descriptions. I implemented its GET method in the extended data provider class, making sure to support all pagination query options ($top, $skip and $inlinecount). A basic GET query of the entity set now returns the following data in JSON format:
{
"d": {
"results": [
{
"__metadata": {
"id": "https://WEBWSD.<my company>:443/sap/opu/odata/sap/ZC_AD_SCHOLAR_SRV/ApplicationStatuteSet('007')",
"uri": "https://WEBWSD.<my company>:443/sap/opu/odata/sap/ZC_AD_SCHOLAR_SRV/ApplicationStatuteSet('007')",
"type": "ZC_AD_SCHOLAR_SRV.ApplicationStatute"
},
"STATUTE": "007",
"DESCR": "Visiting scholar"
},
{
"__metadata": {
"id": "https://WEBWSD.<my company>:443/sap/opu/odata/sap/ZC_AD_SCHOLAR_SRV/ApplicationStatuteSet('014')",
"uri": "https://WEBWSD.<my company>:443/sap/opu/odata/sap/ZC_AD_SCHOLAR_SRV/ApplicationStatuteSet('014')",
"type": "ZC_AD_SCHOLAR_SRV.ApplicationStatute"
},
"STATUTE": "014",
"DESCR": "International scholar"
}
]
}
}
I adjusted the extended model provider class to generate the following annotation in the service metadata document designating the ApplicationStatute entity as a value list provider for statute fields:
<Annotations Target="ZC_AD_SCHOLAR_SRV.ApplicationStatute" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<Annotation Term="com.sap.vocabularies.Common.v1.ValueList">
<Record>
<PropertyValue Property="Label" String="Statutes"/>
<PropertyValue Property="CollectionPath" String="ApplicationStatuteSet"/>
<PropertyValue Property="SearchSupported" Bool="true"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="statute"/>
<PropertyValue Property="ValueListProperty" String="STATUTE"/>
</Record>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly">
<PropertyValue Property="ValueListProperty" String="DESCR"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
I regenerated and reactivated all runtime service artifacts.
In the UI5 front-end view declaration, I explicitly set the preventInitialDataFetchInValueHelpDialog
attribute of the statute field's ControlConfiguration element to false.
AFAIK, this is all one has to do to create a value list for a field.
Howver, if I press F4 in the Statute field of the smart filter bar I only get the following pop-up:
The select from list tab is missing and there is no value list to be seen …
An example of what I'd like to achieve is the value list that pops up when you press F4 in the Company Code field of the first SAPUI5 smart table sample app:
Does anyone know what I'm doing wrong or overlooking in creating the value list for the field?
Thanks in advance for all the help,
Joshua
We found the problem. The annotation target has to refer to the field in the entity to which you want to couple a value list. In my case it had to be "ApplicationsOverviewItem/statute".

Mybatis collection with multiple columns

I have a table which has three foreign keys to items. These corresponding objects I want in a list property. I have the following collection mapping
<collection property="items" column="{item1Id, item2Id, item3Id}">
<association property="exampleNestedItem" column="{id, ###itemId###}" select="com.example.mapper.getItem" />
</collection>
I need the current value at ###itemId###. How can I reference the columns "item1Id", "item2Id" and "item3Id" for this Parameter?
I ended up with a very easy solution. In my case I know that there will always be 3 elements in that list. So I added a setter for each element in the model class like this
public void setElement1(Element element) {
elements.add(element);
}
...
and I added an association for each element
<association property="element1" column="element1Id" select="com.example.mapper.getItemWithId"/>
...
It will for sure not scale for many elements, but for my case it fits!

Jasper report Boolean

I have a Boolean property in the domain object; so can be false, true or N/A if is null. I don't how could be the best option to represent it
<field name="isOSX" class="java.lang.Boolean">
<fieldDescription><![CDATA[device.isOSX]]></fieldDescription>
</field>
Usually you can use that boolean value to print a text o draw a image, using for example the properties:
**Text field expression** in Text Fields
or
**Print When expression** in some other report elements.

Tips for mapping data structure String[ ] [ ] into model class

i need your help and tips for mapping data with dozer.
Following situation is existent:
getting String [ ] [ ] from a service layer.
first [ ] represents rows
second [ ] represents columns
fyi : This data depends on request parameter "table".
// exemplary service call
String[] [] result = service.getData (String table);
String[] [] result = service.getData (Enum table);
Depending on parameter table, another destination entity has to be used.
example :
String[][] for parameter "table_a" should use destination object "com.foo.TableA"
String[][] for parameter "table_b" should use destination object "com.bar.TableB"
The Service layer can not be changed. The layer always returns this data struture as result.
My problem is that i have no good starting point for this situation.
I have to iterate over the first [] and then depends on parameter table , a mapping has to be done.
// useful way?
List<com.foo.TableA> mappedResult = new ArrayList<com.foo.TableA>();
for (int i = 0; i < result.size ; i++) {
String[] rowData = result[i];
mappedResult.add(mapper.map(rowData; com.foo.TableA.class));
}
// mapping.xml
<mappings>
<mapping>
<class-a>how to configure String[] ? </class-a>
<class-b> com.foo.TableA </class-b>
<field>
<a>src[0] </a> // 1st column
<b>column_id</b>
</field>
<mapping>
</mappings>
Any hints are welcome!
Thank you in advance
For accessing data from the String-array, i have used a wrapper
public class RowDataWrapper {
private final row[];
public RowDataWrapper (String[] row) {
this.row=row;
}
}
and its usage within mapping.xml
<mappings>
<mapping>
<class-a>foo.bar.RowDataWrapper</class-a>
<class-b>com.foo.TableA</class-b>
<field>
<a>row[0] </a> // 1st column
<b>column_id</b>
</field>
<mapping>
</mappings>

How to access a DTO attribute when DTO is inside a hashmap in DOZER mapping file

I have a UserDTO which has userID field. The HashMap has this DTO as value for key User_Details.
I want to use DOZER mapping to set the userID attribute from HashMap->User_Details->userId to attribute UserDisplayDTO->userId.
How can I do this in Dozer XML mapping?
<mapping map-id="testMapping">
<class-a>java.util.HashMap</class-a>
<class-b>com.common.dto.UserDisplayDTO</class-b>
<field>
<a key="User_Details">this</a>
<b>userId</b>
</field>
</mapping>
You have to define a custom converter for this. Atm, dozer xml mapping doesn't support a keybased hashmap lookup.
So for your case, you need something like
<field custom-converter="com.your.custom.converter.UserIdConverter">
<a>hashmapfield</a>
<b>userId</b>
</field>
In the UserIdConverter implementation, you would have to retrieve the value from the hashmap and return it (null checking etc. omitted for the sake of clarity):
#Override
public Long convertTo(HashMap map, Long userId) {
UserDTO dto = (UserDTO)map.get("User_Details");
return dto.getUserId();
}