create a common converter for objects from different packages - java

I have 5 webservices, A, B, C, D, and E. Each has autogenerated objects of the exact same structure, but with different names and in different packages.
com.ws.a.carA contains parameters and com.ws.a.wheelA
com.ws.b.carB contains parameters and com.ws.b.wheelB
com.ws.c.carC contains parameters and com.ws.c.wheelC
com.ws.d.carD contains parameters and com.ws.d.wheelD
com.ws.e.carE contains parameters and com.ws.e.wheelE
I want to create one function that can convert each of these objects (and the inner wheel) to a object named
com.model.car,
but I dont wan't many functions like :
com.model.car convert(com.ws.a.objA obj)
com.model.car convert(com.ws.b.objB obj)
...
The problem is, I can't give all the objects a common interface to implement, because I don't want to manually change the autogenerated classes (they are recreated frequently).
I need a way, probably with generics, to create a common function
com.model.car convert(T obj)
that will work for all the car types but I'm not sure how to implement it.

You can use reflection for this. The easiest and cleanest way would probably be to use Apache Common BeanUtils, either PropertyUtils#copyProperties or BeanUtils#copyProperties.
PropertyUtils#copyProperties copies the values from one object to another, where the field names are the same. So with copyProperties(dest, orig), it calls dest.setFoo(orig.getFoo()) for all fields which exist in both objects.
BeanUtils#copyProperties does the same, but you can register converters so that the values get converted from String to Int, if necessary. There are a number of standard converters, but you can register your own, in your case com.ws.a.wheelA to com.model.wheel, or whatever.

You can also check out Dozer

I think you should consider using reflection.

Using commons beanutils library you may do this utility class:
public class BeanUtilCopy {
private static BeanUtilsBean beanUtilsBean;
private static ConvertUtilsBean convertUtilsBean = new ConvertUtilsBean();
static {
convertUtilsBean.register(new Converter() { //2
public <T> T convert(Class<T> type, Object value) {
T dest = null;
try {
dest = type.newInstance();
BeanUtils.copyProperties(dest, value);
} catch (Exception e) {
e.printStackTrace();
}
return dest;
}
}, Wheel.class);
beanUtilsBean = new BeanUtilsBean(convertUtilsBean);
}
public static void copyBean(Object dest, Object orig) throws Exception {
beanUtilsBean.copyProperties(dest, orig); //1
}
When (1) beanUtilsBean use the converter (2) to pass the Wheel**X** values to the Wheel in destination bean.
Use sample:
CarB carB = new CarB();
carB.setName("car B name");
carB.setWeight(115);
WheelB wheelB = new WheelB();
wheelB.setName("wheel B name");
wheelB.setType(05);
carB.setWheel(wheelB);
Car car1 = new Car();
BeanUtilCopy.copyBean(car1, carB);
System.out.println(car1.getName());
System.out.println(car1.getWeight());
System.out.println(car1.getWheel().getName());
System.out.println(car1.getWheel().getType());
The output:
car B name
115
wheel B name
5

Related

Transformation of an object into a subclass object without loosing the references to the object

This is my first problem I can't solve by searching. It's a general OOP problem, but the code is in java. Perhaps I miss an essential point?
Assume there is a baseclass and a subclass. An object of the baseclass is in many lists. There is a transformer class with one duty to transform the object into a subclass object. The transformer should not know anything about the lists. But as a result of the transformation the new subclass object should be in all the lists. (replace the former base class object)
Can this be done somehow?
class BaseClass {
//
}
class SubClass extends BaseClass{
//
}
class Transformer{
BaseClass base;
public Transformer(BaseClass base){
this.base = base;
}
public void transform(){
//transforms the Object to a subtype-object
// ???
// (move the references of the old object to the new one)
this.base = new SubClass(); //something like this (but not so!!!)
}
}
class Programm{
private List<BaseClass> list1 = new ArrayList<>();
private List<BaseClass> list2 = new ArrayList<>();
private List<BaseClass> list3 = new ArrayList<>();
//many more Lists
private List<BaseClass> listn = new ArrayList<>();
public void main() {
BaseClass myObject = new BaseClass();
list1.add(myObject);
list2.add(myObject);
list3.add(myObject);
listn.add(myObject);
Transformer transformer = new Transformer(myObject);
transformer.transform();
//required result
// All Lists contain the transformed Object (from Type SubClass)
}
}
What you're trying to do is luckily impossible (imagine if your objects started changing classes in the middle of your code). You can create a subclass object based on a superclass object (if you can sensibly fill in any missing properties), but you can't turn an existing object into its subclass (such that the reference equality would work as you're hoping in your example code, i.e. converting myObject would affect all the lists).
I don't know how you came up with this idea, but somewhere along the way you've gone down the wrong path. If you tell us what you're trying to achieve, we can provide you with a better solution.
Edit:
Since you're doing checkers and you need to crown a piece, you have the simple choice of adding a boolean crowned property to pieces, and writing logic based on that.
In a more complex situation you could for example use the strategy pattern, where you would have a Piece class, and they would have a Type property that specifies the actual type of the piece. This way the object you put in lists (Piece) always stays the same, but if you replace its Type property, it would seem as if the piece magically changes it's type!

Accessing class definition in xtext

I'm trying to write an DSL for doing typesafe conversions from one object to another.
src classA
dst classB
map valueA to valueB with ConverterX
map valueC to valueD with ConverterY
the result should be something like:
class Converter
{
public void convert(ClassA a, ClassB b)
{
a.setValueA(ConverterX.convert(b.getValueB))
b.setValueC(ConverterY.convert(b.getValueD))
}
}
I simply want to generate the code for that, but i'm not able to access the classes I already defined. The reason for that is to be able to use default converters. Only in case I am able to get the type of the parameters, i will be able to choose the implementation for the default converter.
You can stick with JvmTypeReference as Xtext documentation suggests. You can get JvmType from jvmTypeRef.getType() where relevant types are castable to JvmDeclaredType. Here is my helper method to get list of all bean properties (class members) using JvmTypeReference:
public List<String> getFieldNamesForClass(JvmTypeReference jvmTypeRef) {
List<String> result = new ArrayList<String>();
if (jvmTypeRef.getType() instanceof JvmDeclaredType) {
JvmDeclaredType declaredType = (JvmDeclaredType)jvmTypeRef.getType();
for (JvmField field : declaredType.getDeclaredFields()) {
result.add(field.getSimpleName());
}
}
return result;
}
The output is List of Strings, the filed names, but it can be easily changed to return JvmField/JvmMember instances.
Check my DeepCloneDSL on bitbucket.org/espinosa/deepclonedsl
I solved the problem by Using JvmDeclaredType instad of JvmTypeReference. JvmTypeReference doesn't offer access to fields and methods, but JvmDeclaredType does. It is also possible to generate a JvmTypeReference by knowing the QualifiedName that is present in the JvmDeclaredType.

How to create an object in a utility class based on if statement in Java? (Or based on a particular string)

I would have a string that is parsed into an array, as shown here:
class Example extends ParentClass {
private String[] array;
public static Example parseString(String lineToParse) {
array = lineToParse.split("\");
}
public ObjectType1() { // arguments: String, String, String
}
public ObjectType2() { // arguments: String, String, String, double, double
}
}
What I'm wondering is could I do this?
if (array[0].equals("Test")) {
public ObjectType1()
}
Or is there a better way to do this?
I want to create various objects with different arguments each, and the first argument (array[0]) will be applicable to each object, so I was wondering if I could create objects within an if statement like this, or a switch (not sure if that would work either).
I believe a factory method would be useful for you, one that returns instances of classes according to the parameter received:
// ObjectType1, ObjectType2, ObjectType3 inherit from ObjectType
static ObjectType getInstance(String[] array) {
if (array[0].equals("Test"))
return new ObjectType1(array);
else if (array[0].equals("Test2"))
return new ObjectType2(array);
else
return new ObjectType3(array);
}
For the record, actually you can define a class inside a method, this is valid code in Java ... of course, that's hardly a good thing to do:
// ObjectType1, ObjectType2 inherit from ObjectType
public ObjectType example(String[] array) {
if (array[0].equals("Test")) {
class ObjectType1 {
ObjectType1(String[] array) {
}
}
return new ObjectType1(array);
}
else {
class ObjectType2 {
ObjectType2(String[] array) {
}
}
return new ObjectType2(array);
}
}
"Creating" an object means "instantiating it", with new:
ObjectType1 foo = new ObjectType1(...);
You can do that anywhere it's legal to instantiate a class, including in an if statement.
You cannot define classes in arbitrary locations, however.
If you just want to call a method (which should start with a lower-case letter if you want Java developers to understand what you're trying to do), you can call it from anywhere, including inside if statements.
This sounds like you may want to use a [static factory method][1].
[1]: http://en.m.wikipedia.org/wiki/Factory_method_pattern
I guess that you want to dynamically create objects based on a configuration file?
There are lots of ways to achieve this. One simple way is to use reflection to create the objects. Then you do not need any if/switch statements, and if you want to create a new type of object your code does not need to be changed.
Here are some examples for using reflection: Reflection API Code Samples

Strategies for converting collections from one type to another

What is the most efficient way to convert ArrayLists with EO (Entity Object) into ArrayLists of DTO objects or ArrayLists of Ids. Please, keep in mind that every EO may consist of properties which are also EOs, or collections of EOs, which should internally be converted to DTOs, or omitted (depending on the conversion strategy). In general, a lot of boilerplate code.
wish it were as simple as:
collectionOfUsers.toArrayList<UserDTO>();
or..
collectionOfUsers.toArrayList<IEntity>();
// has only an id, therefore it will be converted
// into a collection of objects, having only an id.
of course, this could be nice as well:
collectionOfUsers.toArrayList<Long>()
// does the same thing, returns only a bunch of ids
Of course, someone should hold the mapping strategies as well, for instance a Factory or sth.
any suggestions ?
You could just use a simple interface to simulate conversion.
interface DTOConvertor<X,Y> {
X toDTO(Y y);
}
public static List<X> convertToDTO(Collection<Y> ys, DTOConvertor<X,Y> c) {
List<X> r = new ArrayList<X>(x.size());
for (Y y : ys) {
r.add(c.toDTO(y));
}
return y;
}
Note that this is just the same as a library that implements map functionality.
In terms of efficiency, I guess you will be running into problems because entity objects will (possibly) be fetching from the database. You could make relationships eager to explore whether that made any difference.
You should create a generic method for converting from one type to another. Here is the simple interface for that:
public interface XFormer<T,U> {
public T xform(U item);
}
You would then use that in a generic conversion method:
public static <T, U> List<T> xForm(List<U> original, XFormer<T, U> strategy) {
List<U> ret = new ArrayList<U>(original.size());
for (U item: original) {
ret.add(strategy.xform(item));
}
return ret;
}
One use of this may look like:
List<String> original;
List<Long> xFormed = xForm(original, new XFormer<Long, String>() {
public Long xForm(String s) {
return Long.parseLong(s);
}
});
I use this same strategy in one of my open source projects. Have a look at JodeList on line 166 for an example. It is a bit simplified in my case because it only transforms from Jode to any type, but it should be able to be expanded to converting between any type.
Consider using Apache Commons BeanUitls.populate().
It would populate each equivalent property from a Bean to another.

Dynamically create and cast objects at runtime

Let's say we have 2 classes A and B
public class A{
private int member1;
A() {
member1 = 10;
}
public getMember(){
return member1;
}
}
Class B is also on the same lines except that its member variable is named member2 and gets intitialized to say 20 inside the constructor.
My Requirement :
At runtime , I get a string which contains a className ( could be A or B). I want to dynamically create an object of this class along with invoking the constructor. How can I achieve this . I don't want to use interfaces for common functionality of above classes Morever, later on I set the properties of this raw object using Propery Builder Bean Util class based on a list of columns .
Class clazz = Class.forName("className");
Obj obj = clazz.newInstance();
How I can dynamically convert that obj to className object.
How can I achieve this . I don't want to use interfaces for common functionality of above classes
Then the answer is very simple and you won’t like it: you can’t. You want to modify the static type of the variables which is, by definition, determined at compile time. Changing it at runtime is not possible.
What do you mean with "dynamically convert"? It IS an object of type "className", stored in a variable of type Object. If you want to use it as an object of type A, you have to cast it, and for example store it in a variable of type A.
Class Class has a cast method which at first sight seems to be doing just what you want. So you could try
... = clazz.cast(obj);
but what would be the return type??? It should be either A or B, but you can't declare a variable dynamically...
So I see no other way than the ugly, but tried and true
if (obj instanceof A) {
A a = (A) obj;
...
} else if (obj instanceof B) {
B b = (B) obj;
...
}
Note that if with bean introspection, you can always see the actual dynamic type and internals of the object, so I see not much point trying to get a static reference of the right type to it.

Categories