I have a simple Java POJO that I would copy properties to another instance of same POJO class.
I know I can do that with BeanUtils.copyProperties() but I would like
I had the same problem when developing an app for Google App Engine, where I couldn't use BeanUtils due to commons Logging restrictions. Anyway, I came up with this solution and worked just fine for me.
public static void copyProperties(Object fromObj, Object toObj) {
Class<? extends Object> fromClass = fromObj.getClass();
Class<? extends Object> toClass = toObj.getClass();
try {
BeanInfo fromBean = Introspector.getBeanInfo(fromClass);
BeanInfo toBean = Introspector.getBeanInfo(toClass);
PropertyDescriptor[] toPd = toBean.getPropertyDescriptors();
List<PropertyDescriptor> fromPd = Arrays.asList(fromBean
.getPropertyDescriptors());
for (PropertyDescriptor propertyDescriptor : toPd) {
propertyDescriptor.getDisplayName();
PropertyDescriptor pd = fromPd.get(fromPd
.indexOf(propertyDescriptor));
if (pd.getDisplayName().equals(
propertyDescriptor.getDisplayName())
&& !pd.getDisplayName().equals("class")) {
if(propertyDescriptor.getWriteMethod() != null)
propertyDescriptor.getWriteMethod().invoke(toObj, pd.getReadMethod().invoke(fromObj, null));
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
Any enhancements or recomendations are really welcome.
There is no simple way to do it. Introspector and the Java beans libraries are monolithic - BeanUtils is a simple wrapper around this and works well. Not having libraries just to not have libraries is a bad idea in general - there's a reason it's commons to begin with - common functionality that should exist with Java, but doesn't.
Have a look at the JavaBeans API, in particular the Introspector class. You can use the BeanInfo metadata to get and set properties. It is a good idea to read up on the JavaBeans specification if you haven't already. It also helps to have a passing familiarity with the reflection API.
Another alternative is MapStruct which generates mapping code at build time, resulting in type-safe mappings which don't require any dependencies at runtime (Disclaimer: I'm the author of MapStruct).
You can achieve it using Java Reflection API.
public static <T> void copy(T target, T source) throws Exception {
Class<?> clazz = source.getClass();
for (Field field : clazz.getDeclaredFields()) {
if (Modifier.isPrivate(field.getModifiers()))
field.setAccessible(true);
Object value = field.get(source);
field.set(target, value);
}
}
I guess if you look at the source code of BeanUtils, it will show you how to do this without actually using BeanUtils.
If you simply want to create a copy of a POJO (not quite the same thing as copying the properties from one POJO to another), you could change the source bean to implement the clone() method and the Cloneable interface.