I want to use Dozer to copy beans that have properties which contain references to static final properties (that are not of primitive type) of another Object.
The concrete example is a class "ObjectA" that has a property "propertyA" which is of type "TypesafeEnum" and which references a static final property of "TypeSafeEnum" object, which is kind of the classical way to use a TypesafeEnumPattern.
"TypesafeEnum" has itself two properties (name and value) which you cannot set and "TypesafeEnum" does not have an empty constructor either, as demanded by the pattern.
If I want to copy "ObjectA" to "ObjectB" (which has a "propertyB" that is also of type "TypesafeEnum", and propertA and properyB are mapped to each other), Dozer wants to create a new instance of "TypesafeEnum" and set name and value, which fails because neither the Constructor, neither the setters for the properties exist.
What is the best way to copy this kind of properties using Dozer?
Thanks a lot for your help!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For the same purpose, we have used custom mappers.
We have defined a unique custom mapper class which can map any enum type to any other...
When a property of type enum is mapped to an other property of type enum, the custom mapper is called. It's code is generic and it uses introspection to call the static methods of the enum classes to obtain the correct value of the destination enum type.
I hope this will help.
Richard.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Will custom converters work since the destination object does not have a no arg constructor? I guess if you have a custom converter for the parent objects and do all of the mapping for their attributes in it you should be fine.
Our next release will tackle the problem of bean creation by having the ability to define your own bean factory. It will not solve the problem of fields not having getter() setter() methods. You would have to set wildcard="false" on the mapping so that fields are not mapped implicitly. In the bean factory you could construct the Enum with values from the source object that we pass into your bean factory.
Custom Converters can be defined between Enum types having no default constructors ;-)
We have a generic custom converter defined as follow (this is with a previous version of Dozer and the convert method has changed but the way it works is the same) :
public class EnumCustomMapper implements CustomConverter {
// Initialisation des tableaux pour viter de les reconstruire chaque appel
private static Class[] noParameterTypes = new Class[] {};
private static Class[] stringParameterType = new Class[] { String.class };
private static Object[] noParameters = new Object[] {};
private static Object[] valueOfParameters = new Object[] { null };
public Object convert(Class destination, Object source) {
Thanks alot for your fast response!
Actually, for this special purpose (mapping of properties that can only have static final values), a custom mapper that returned the source object was just fine.
I did not need to set the wildcard parameter to false.
I think it would be useful to generally be able to specify if a field (that references an object) can be copied only by reference instead of creating a new instance of the referenced object.
I think of something like:
<mapping>
<classA>classA</classA>
<classB>classB</classB>
I've just hit this problem with "value" typed fields which are not part of the standard set recognised by Dozer, ie. java.util.UUID.
A further modification might be to allow custom converters to be checked for before trying to create a bean as they're free to create the resulting object any way they like.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
First of all, thank you for this great tool!
I want to use Dozer to copy beans that have properties which contain references to static final properties (that are not of primitive type) of another Object.
The concrete example is a class "ObjectA" that has a property "propertyA" which is of type "TypesafeEnum" and which references a static final property of "TypeSafeEnum" object, which is kind of the classical way to use a TypesafeEnumPattern.
"TypesafeEnum" has itself two properties (name and value) which you cannot set and "TypesafeEnum" does not have an empty constructor either, as demanded by the pattern.
If I want to copy "ObjectA" to "ObjectB" (which has a "propertyB" that is also of type "TypesafeEnum", and propertA and properyB are mapped to each other), Dozer wants to create a new instance of "TypesafeEnum" and set name and value, which fails because neither the Constructor, neither the setters for the properties exist.
What is the best way to copy this kind of properties using Dozer?
Thanks a lot for your help!
Hi,
For the same purpose, we have used custom mappers.
We have defined a unique custom mapper class which can map any enum type to any other...
When a property of type enum is mapped to an other property of type enum, the custom mapper is called. It's code is generic and it uses introspection to call the static methods of the enum classes to obtain the correct value of the destination enum type.
I hope this will help.
Richard.
Will custom converters work since the destination object does not have a no arg constructor? I guess if you have a custom converter for the parent objects and do all of the mapping for their attributes in it you should be fine.
Our next release will tackle the problem of bean creation by having the ability to define your own bean factory. It will not solve the problem of fields not having getter() setter() methods. You would have to set wildcard="false" on the mapping so that fields are not mapped implicitly. In the bean factory you could construct the Enum with values from the source object that we pass into your bean factory.
This is our propsed solution:
http://sourceforge.net/forum/forum.php?thread_id=1370087&forum_id=452529
Thanks for asking.
Franz
Custom Converters can be defined between Enum types having no default constructors ;-)
We have a generic custom converter defined as follow (this is with a previous version of Dozer and the convert method has changed but the way it works is the same) :
public class EnumCustomMapper implements CustomConverter {
// Initialisation des tableaux pour viter de les reconstruire chaque appel
private static Class[] noParameterTypes = new Class[] {};
private static Class[] stringParameterType = new Class[] { String.class };
private static Object[] noParameters = new Object[] {};
private static Object[] valueOfParameters = new Object[] { null };
public Object convert(Class destination, Object source) {
if (source == null) {
return null;
}
Object returnedObject = null;
try {
Method name = source.getClass().getDeclaredMethod("name", noParameterTypes);
Method valueOf = destination.getDeclaredMethod("valueOf", stringParameterType );
valueOfParameters[0] = name.invoke(source, noParameters );
returnedObject = valueOf.invoke(null, valueOfParameters );
} catch (...) {
}
return returnedObject;
}
public void convert(Object destination, Object source) {
...
}
}
And for each enum mapping, we define the following custom converter in Dozer.xml :
<converter type="fr.covea.troisma.infra.mapping.EnumCustomMapper" >
<classA>EnumA</classA>
<classB>EnumB</classB>
</converter>
Richard.
Hi,
Thanks alot for your fast response!
Actually, for this special purpose (mapping of properties that can only have static final values), a custom mapper that returned the source object was just fine.
I did not need to set the wildcard parameter to false.
I think it would be useful to generally be able to specify if a field (that references an object) can be copied only by reference instead of creating a new instance of the referenced object.
I think of something like:
<mapping>
<classA>classA</classA>
<classB>classB</classB>
<field copyByRef="true">
<A>propertyA</A>
<B>propertyB</B>
</field>
</mapping>
I dont know if this contradicts some ideologies of the project, but it would have been handy in my case.
Best wishes from Switzerland!
Interesting. Let me take this up with the other dozer developers.
Thanks,
Franz
I've just hit this problem with "value" typed fields which are not part of the standard set recognised by Dozer, ie. java.util.UUID.
A further modification might be to allow custom converters to be checked for before trying to create a bean as they're free to create the resulting object any way they like.
Very good suggestion. A combination of our upcoming bean factory and custom converters should solve any/all of these problems.
I'm pretty sure we can move the customconverter code so that we check to see if we have one before destination object creation.
Thanks,
Franz
This has been added for 1.5.6.
Franz