View Javadoc
1   package org.oxerr.commons.ws.rs.bean;
2   
3   import java.beans.PropertyDescriptor;
4   import java.lang.annotation.Annotation;
5   import java.lang.reflect.Field;
6   import java.lang.reflect.InvocationTargetException;
7   import java.util.Arrays;
8   import java.util.HashSet;
9   import java.util.List;
10  import java.util.Set;
11  import java.util.stream.Collectors;
12  
13  import org.springframework.beans.BeanWrapper;
14  import org.springframework.beans.BeanWrapperImpl;
15  
16  public final class BeanUtils {
17  
18  	private BeanUtils() {
19  	}
20  
21  	public static <T> T patch(T dest, Object orig) {
22  		if (dest == null || orig == null) {
23  			return dest;
24  		}
25  
26  		try {
27  			NullAwareBeanUtilsBean.getInstance().copyProperties(dest, orig);
28  		} catch (IllegalAccessException | InvocationTargetException e) {
29  			throw new IllegalArgumentException(e);
30  		}
31  
32  		return dest;
33  	}
34  
35  	public static <T> T patch(T dest, Object orig, String... properties) {
36  		if (dest == null || orig == null) {
37  			return dest;
38  		}
39  
40  		final BeanWrapper destBeanWrapper = new BeanWrapperImpl(dest);
41  		final BeanWrapper origBeanWrapper = new BeanWrapperImpl(orig);
42  
43  		for (final String property : properties) {
44  			final Object value = origBeanWrapper.getPropertyValue(property);
45  			if (value != null) {
46  				destBeanWrapper.setPropertyValue(property, value);
47  			}
48  		}
49  
50  		return dest;
51  	}
52  
53  	public static <T> T patchExclude(T dest, Object orig,
54  			String... excludedProperties) {
55  		if (dest == null || orig == null) {
56  			return dest;
57  		}
58  
59  		final List<String> excludedPropertyList = Arrays.asList(excludedProperties);
60  
61  		final BeanWrapper destBeanWrapper = new BeanWrapperImpl(dest);
62  		final BeanWrapper origBeanWrapper = new BeanWrapperImpl(orig);
63  
64  		for (final PropertyDescriptor pd : destBeanWrapper.getPropertyDescriptors()) {
65  			if (pd.getWriteMethod() != null && !excludedPropertyList.contains(pd.getName())) {
66  				final Object value = origBeanWrapper.getPropertyValue(pd.getName());
67  				if (value != null) {
68  					destBeanWrapper.setPropertyValue(pd.getName(), value);
69  				}
70  			}
71  		}
72  
73  		return dest;
74  	}
75  
76  	public static <T> T patchExclude(T dest, Object orig,
77  			Set<Class<? extends Annotation>> excludedAnnotationTypes) {
78  		if (dest == null || orig == null) {
79  			return dest;
80  		}
81  
82  		final BeanWrapper destBeanWrapper = new BeanWrapperImpl(dest);
83  		final BeanWrapper origBeanWrapper = new BeanWrapperImpl(orig);
84  
85  		for (final PropertyDescriptor pd : destBeanWrapper.getPropertyDescriptors()) {
86  			if (pd.getWriteMethod() != null) {
87  				final Set<Annotation> annotations = new HashSet<>();
88  				annotations.addAll(Arrays.asList(pd.getReadMethod().getAnnotations()));
89  				annotations.addAll(Arrays.asList(pd.getWriteMethod().getAnnotations()));
90  				try {
91  					Field field = dest.getClass().getDeclaredField(pd.getName());
92  					annotations.addAll(Arrays.asList(field.getAnnotations()));
93  				} catch (NoSuchFieldException | SecurityException e) {
94  				}
95  
96  				final List<Class<? extends Annotation>> annotationTypes = annotations
97  					.stream().map(Annotation::annotationType)
98  					.collect(Collectors.toList());
99  				annotationTypes.retainAll(excludedAnnotationTypes);
100 
101 				if (annotationTypes.isEmpty()) {
102 					final Object value = origBeanWrapper.getPropertyValue(pd.getName());
103 					if (value != null) {
104 						destBeanWrapper.setPropertyValue(pd.getName(), value);
105 					}
106 				}
107 			}
108 		}
109 
110 		return dest;
111 	}
112 
113 	@SuppressWarnings("unchecked")
114 	public static <T> T patchExclude(T dest, Object orig,
115 			Class<?>... excludedAnnotationTypes) {
116 		patchExclude(dest, orig,
117 			Arrays.asList(excludedAnnotationTypes).stream()
118 				.map(e -> (Class<? extends Annotation>) e)
119 				.collect(Collectors.toSet()));
120 		return dest;
121 	}
122 
123 	public static <T> T copyProperties(T dest, Object orig, String... properties) {
124 		if (dest == null || orig == null) {
125 			return dest;
126 		}
127 
128 		final BeanWrapper destBeanWrapper = new BeanWrapperImpl(dest);
129 		final BeanWrapper origBeanWrapper = new BeanWrapperImpl(orig);
130 		for (final String property : properties) {
131 			final Object value = origBeanWrapper.getPropertyValue(property);
132 			destBeanWrapper.setPropertyValue(property, value);
133 		}
134 		return dest;
135 	}
136 
137 }