Dozer custom converter - passing the whole object as field 'A' - java

I'd like to map a CustomConverter in dozer but I'd like to pass the whole current object as the source. All of the examples in the dozer CustomConverter documentation pass a field of the input object as the source and not the whole object.
I'd like to do something like this:
<mapping>
<class-a>foo.bar.InputObject</class-a>
<class-b>foo.bar.OutputObject</class-b>
<field custom-converter="foo.bar.MyConverter">
<a>this</a> <!-- how do I access the whole value and not just a field? -->
<b>custom</b>
</field>
<field>
<a>anotherField</a>
<b>anotherField</b>
</field>
</mapping>
And
public class MyConverter extends DozerConverter<InputObject, String> {
...
public String convertTo(InputObject input, String custom) {
// do some transformation
}
}
CustomConverter docs here:
http://dozer.sourceforge.net/documentation/customconverter.html

Try implementing the CustomConverter instead of DozerConverter and try passing it as:
<field custom-converter="my.custom.converter">
<a>this</a>
<b>myfield</b>
</field>

If you use the field mapping you want to identify the attribute by using "key":
<field custom-converter="de.xyz.custom.MyConverter">
<a key="variablename">this</a>
<b>targetvariablename</b>
</field>
You can then proceed to implement the converter. You will be given the Object containing the field "variablename" as source. If for example you do not have a setter for a list value (like I had for whatever reason...) you are now able to manipulate the source object the way you need to.

Related

how to send string constant to a field value using dozer mapping?

'<mapping map-id="vehicle Info">
<class-a>vehicle Info</class-a>
<class-b>uninsured</class-b>
<field>
<a>CONSTANT_CAR</a>
<b>car.value</b>
</field>
</mapping>'
I'm trying to send the constant value of "CONSTANT_CAR" into the field of "car.value" which is located inside the vehicle
Can someone please guide me how can I pass the constant value to a setter which is located in the destination class.
You should be able to access the constant by setting the 'is-accessible="true"' for the constant field. So, your mapping could look something like this:
<mapping map-id="vehicle-info">
<class-a>path.to.VehicleInfo</class-a>
<class-b>path.to.Uninsured</class-b>
<field>
<a is-accessible="true">CONSTANT_CAR</a>
<b>car.value</b>
</field>
</mapping>
Make sure when naming the classes in the <class-a> and <class-b> tags you put the full path to the class.
I just tested with some sample code and it mapped the constant as expected. Let me know if it works for you!

Mapping with DOZER without method set

I am trying to convert two classes that have an attribute of type java.util.List, but one of the classes does not have a method "set*" only the method "get*" like this:
<mapping>
<class-a>com.mycompany.bean.SocioPj</class-a>
<class-b>com.mycompany.jaxb.SocioPjXml</class-b>
<field>
<a set-method="getListaSocios().add">listaSocios</a>
<b>listaSocios</b>
<a-hint>com.mycompany.bean.SocioPf,com.mycompany.bean.SocioPj</a-hint>
<b-hint>com.mycompany.jaxb.SocioPfXml,com.mycompany.jaxb.SocioPjXml</b-hint>
</field>
</mapping>
The example above the class: SocioPj doesn´t have a method setListSocios() when I tried to convert I catch this error:
[Time:2015-03-24 11:29:08,055][Level:ERROR][Thread:http-bio-8080-exec-10][OnboardingCCMFulfillmentImpl] org.dozer.MappingException: java.lang.ClassNotFoundException: /add
Has anyone faced this problem?
You can tell Dozer to directly access the field without calling the getter/setter (Even if the field is private):
<field>
<a is-accessible="true">listaSocios</a>
<b>listaSocios</b>
</field>

Call custom converter after default in dozer

Does Dozer could call custom converter after default?
I want to create something like chain. At first I want to call default converter to make most of convertion work and only after that call custom converter to populate complex fields?
EDIT
by default when I create custom converter I need to override two methods. Each of this method has 2 arguments source object and target object. But when we call convertTo method second argument(target object) equals to null. So may be I need to specify something in mapping file to make dozer process default converter before custom?
Sorry for bad english
After look into source code I understand that this probably imposible. Instead of this dozer library propose using custom-converters at field level like this:
<mapping wildcard="false" >
<class-a>package.A</class-a>
<class-b>package.B</class-b>
<field>
<a>id</a>
<b>id</b>
</field>
<field custom-converter="test.AtoBNameFieldCustomConverter">
<a>name</a>
<b>name</b>
</field>
</mapping>
May be this help someone.

Dozer - Mapping Collections

I have the a scenario that is similar to the following two classes:
public class Person {
private String name;
private Set<Person> familyMembers;
//constructors & getters and setters
}
The Person class is my source class. I'm trying to use Dover to map this class to the following target classes:
public class PersonPrime {
private String personName;
private FamilyMembers familyMembers;
//constructors & getters and setters
}
public class FamilyMembers {
private List<PersonPrime> familyMembers;
//constructors & getters and setters
}
The target classes in my actual scenario are generated by JAXB (using XSDs which I have created). The XSDs were prescribed and I can't really change them, therefore the target classes cannot be changed. I currently am able to map the primitives in my mappings XML file but I cannot maps the collection.
Any idea how I can use Dozer to map an object of Person to an object of type PersonPrime?
By default JaxB does not generate setters for the collections within the "FamilyMembers" type. This will result in a null pointer exeception deep within the guts of Dozer (org.dozer.util.ReflectionUtils.java:323 in Dozer 5.4.0) when Dozer tries to call the non-existent setter. To avoid this, you need to set is-accessible true on the collection field, which will cause it to set the familyMembers.familyMembers field directly. Thus, the following modified mapping who should work:
<mapping>
<class-a>Person</class-a>
<class-b>PersonPrime</class-b>
<field>
<a>name</a>
<b>personName</b>
</field>
<field>
<a>familyMembers</a>
<b is-accessible="true">familyMembers.familyMembers</b>
</field>
</mapping>
The following mapping works.
<mapping>
<class-a>Person</class-a>
<class-b>PersonPrime</class-b>
<field>
<a>name</a>
<b>personName</b>
</field>
<field>
<a>familyMembers</a>
<b>familyMembers.familyMembers</b>
</field>
</mapping>

Mapping deep properties with intermediate collections in dozer

Suppose I have the following classes
public class Baz {
private List<Foo> foos = new ArrayList<Foo>();
}
public class Foo {
private String string;
}
public class Target {
private List<String> fooStrings = new ArrayList<String>();
}
Is there any mapping I can use to, given a Baz, map it to the target class and get a list of the strings contained within the foo's in Baz? The following mapping does not work
<mapping>
<class-a>Baz</class-a>
<class-b>Target</class-b>
<field>
<a>foos.string</a>
<b>fooStrings</b>
</field>
</mapping>
Because string is not a property of foos (which is of type List). I would have thought Dozer would be clever enough to, if it encountered a collection in a deep mapping, and the target was also a collection, to be able to break the deep property name into two and iterate across the collection to get the child part of the deep mapping from the collection members. Apparently not. Is there a solution short of making a feature request of Dozer?
You could always write your own CustomConverter.
It makes sense why Dozer isn't able to handle this as you expect since at runtime it has no type information about the List foos and can't guarantee that every Object in the list is actually a Foo.
I think, you can write such a mapping
<mapping>
<class-a>Baz</class-a>
<class-b>Target</class-b>
<field>
<a>foos</a>
<b>fooStrings</b>
</field>
</mapping>
<custom-converters>
<converter type="CustomFooConverter">
<class-a>
Foo
</class-a>
<class-b>
String
</class-b>
</converter>
</custom-converters>
And implement CustomFooConverter to get string field of foo and return it as a String.
I think you can post a feature request to support mapping to primitives as
<mapping>
<class-a>Foo</class-a>
<class-b>String</class-b>
<field>
<a>string</a>
</field>
</mapping>
into Dozer GitHub
I think you can do it without custom converter.
Override the toString() method of Foo class like below:
#Override
public String toString(){
return this.getString(); //assuming string property has a getter method. if not,write this.string
And now the follwing mapping:
<mapping>
<class-a>fully qualified name of Baz(with package name)</class-a>
<class-b>same for Target</class-b>
<field>
<a>foos</a>
<b>fooStrings</b>
<a-hint>foo</a-hint>
<b-hint>java.lang.String</b-hint>
</field>
</mapping>

Categories

Resources