package pl.net.bluesoft.util.lang; import org.apache.commons.beanutils.PropertyUtils; import java.beans.PropertyDescriptor; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; public class Classes { private static final Logger logger = Logger.getLogger(Classes.class.getName()); public static List<Field> getDeclaredFields(Class clazz) { List<Field> fields = new ArrayList<Field>(); while (clazz != Object.class && clazz != null) { for (Field f : clazz.getDeclaredFields()) { if (!Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers())) { fields.add(f); } } clazz = clazz.getSuperclass(); } return fields; } public static Field findDeclaredField(Class clazz, String fieldName) { for (Field field : getDeclaredFields(clazz)) { if (field.getName().equals(fieldName)) { return field; } } return null; } public static <A extends Annotation> List<Field> getFieldsWithAnnotation(Class clazz, Class<A> annotation) { List<Field> fields = new ArrayList<Field>(); while (clazz != Object.class && clazz != null) { for (Field f : clazz.getDeclaredFields()) { if (f.isAnnotationPresent(annotation)) { fields.add(f); } } clazz = clazz.getSuperclass(); } return fields; } public static <A extends Annotation> A getClassAnnotation(Class clazz, Class<A> annotation) { while (clazz != Object.class && clazz != null) { if (clazz.isAnnotationPresent(annotation)) { return (A) clazz.getAnnotation(annotation); } clazz = clazz.getSuperclass(); } return null; } public static void setFieldValue(Object instance, Field field, Object value) throws Exception { PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(instance, field.getName()); Method m = pd != null ? PropertyUtils.getWriteMethod(pd) : null; if (m == null) { boolean accessible = field.isAccessible(); if (!accessible) { field.setAccessible(true); } field.set(instance, value); if (!accessible) { field.setAccessible(false); } } else { m.invoke(instance, value); } } public static void setFieldValue(Object instance, String fieldName, Object value) throws Exception { PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(instance, fieldName); Method m = pd != null ? PropertyUtils.getWriteMethod(pd) : null; if (m == null) { Field field = findDeclaredField(instance.getClass(), fieldName); if (field == null) { throw new RuntimeException("Cannot find field named " + fieldName); } boolean accessible = field.isAccessible(); if (!accessible) { field.setAccessible(true); } field.set(instance, value); if (!accessible) { field.setAccessible(false); } } else { m.invoke(instance, value); } } public static Object invokeMethod(Method method, Object target, Object... args) { try { return method.invoke(target, args); } catch (Exception ex) { throw new RuntimeException("Unable to invoke method", ex); } } public static Properties loadProperties(Class clazz, String path) { Properties p = new Properties(); try { p.load(clazz.getResourceAsStream(path)); } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage(), e); throw new RuntimeException(e); } return p; } public static <T> T newInstance(Class<T> clazz) { try { Constructor constr = clazz.getConstructor(); return (T)constr.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } public static void setProperty(Object object, String property, Object value) { if (property == null) { return; } try { PropertyUtils.setProperty(object, property, value); } catch (Exception e) { throw new RuntimeException(e); } } public static Object getProperty(Object object, String property) { if (property == null) { return null; } try { return PropertyUtils.getProperty(object, property); } catch (Exception e) { throw new RuntimeException(e); } } public static void copyProperties(Object dest, Object src) { try { PropertyUtils.copyProperties(dest, src); } catch (Exception e) { throw new RuntimeException(e); } } public static void copyProperties(Object dest, Object src, String[] skippedProperties) { Map<String, Object> oldValues = new HashMap<String, Object>(); if (skippedProperties != null) { for (String property : skippedProperties) { oldValues.put(property, getProperty(dest, property)); } } Classes.copyProperties(dest, src); if (skippedProperties != null) { for (String property : skippedProperties) { setProperty(dest, property, oldValues.get(property)); } } } }