import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.FatalBeanException; /** * Bean attribute copy tool class */ public class BeanUtil { private static final Log logger = LogFactory.getLog(BeanUtil.class); /** bean nesting */ private static final String NESTED = "."; /** * Copy bean properties (support nested properties, separated by dots) * * @param source * Source object to copy properties * * @param dest * Destination object to copy properties * * @param includeProperties * List of copied properties * * @author yang_qiao * * @throws InvocationTargetException * * @throws IllegalAccessException * * @throws IllegalArgumentException * * @throws InstantiationException * * @throws IntrospectionException * * @date 2013-12-18 */ public static final void copyIncludeProperties(final Object source, Object dest, final String[] includeProperties) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException { if (includeProperties == null || includeProperties.length == 0) { throw new IllegalArgumentException("The list of attributes to be copied was not passed in"); } if (source == null) { throw new IllegalArgumentException("The source object to be copied is empty"); } if (dest == null) { throw new IllegalArgumentException("The destination object to be copied is empty"); } // log information if (logger.isTraceEnabled()) { logger.trace("[source bean: " + source.getClass().getName() + " ]"); logger.trace("[destination bean: " + dest.getClass().getName() + " ]"); } // copy for (String property : includeProperties) { PropertyDescriptor sourcePropertyDescriptor = null; PropertyDescriptor destPropertyDescriptor = null; if (isSimpleProperty(property)) { // simple property sourcePropertyDescriptor = getProperty(property, source); destPropertyDescriptor = getProperty(property, dest); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException("The target object to be copied does not have this attribute"); } copyProperty (property, source, dest); } else { // nested bean properties Object target = dest; Object realSource = source; String[] nestedProperty = getNestedProperty(property); if (nestedProperty != null && nestedProperty.length > 1) { for (int i = 0; i < nestedProperty.length - 1; i++) { sourcePropertyDescriptor = getProperty( nestedProperty[i], realSource); destPropertyDescriptor = getProperty(nestedProperty[i], target); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException( "This property does not exist in the target object to be copied to"); } Method readMethod = sourcePropertyDescriptor .getReadMethod(); realSource = readMethod.invoke(realSource); readMethod = destPropertyDescriptor.getReadMethod(); Method writeMethod = destPropertyDescriptor .getWriteMethod (); Object value = readMethod.invoke(target); if (value == null) { value = destPropertyDescriptor.getPropertyType() .newInstance(); writeMethod.invoke(target, value); } target = value; } final String prop = nestedProperty[nestedProperty.length - 1]; sourcePropertyDescriptor = getProperty(prop, realSource); destPropertyDescriptor = getProperty(prop, target); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException("The target object to be copied does not have this attribute"); } copyProperty(prop, realSource, target); } } } } /** * Copy bean properties (support nested properties, separated by dots) * * @param source * Source object to copy properties * * @param dest * Destination object to copy properties * * @param includeProperties * List of copied properties * * @throws IntrospectionException * * @throws InvocationTargetException * * @throws IllegalAccessException * * @throws IllegalArgumentException * * @throws InstantiationException * * @throws ClassNotFoundException * * @throws IOException * */ public static void copyProperties(final Object source, final Object dest, final String... excludeProperties) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException, ClassNotFoundException { final Object backupSource = clone(dest); if (source == null) { throw new IllegalArgumentException("The source object to be copied is empty"); } if (dest == null) { throw new IllegalArgumentException("The destination object to be copied is empty"); } org.apache.commons.beanutils.BeanUtils.copyProperties (dest, source); // restore excluded property values revertProperties(backupSource, dest, excludeProperties); } /** * Restore properties from backup object * * @param backup * Backup beans * * @param target * target bean * * @param properties * property list * * @throws InvocationTargetException * * @throws IllegalAccessException * * @throws IllegalArgumentException * * @throws IntrospectionException * * @throws InstantiationException */ private static void revertProperties(final Object backup, Object target, final String... properties) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException, InstantiationException { if (properties == null || properties.length == 0) { return; } if (backup == null) { throw new IllegalArgumentException("Backup object is empty"); } if (target == null) { throw new IllegalArgumentException("The destination object is empty"); } // log information if (logger.isTraceEnabled()) { logger.trace("[source bean: " + backup.getClass().getName() + " ]"); logger.trace("[destination bean: " + target.getClass().getName() + " ]"); } // copy for (String property : properties) { PropertyDescriptor sourcePropertyDescriptor = null; PropertyDescriptor destPropertyDescriptor = null; if (isSimpleProperty(property)) { // simple property sourcePropertyDescriptor = getProperty(property, backup); destPropertyDescriptor = getProperty(property, target); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException("The target object to be copied does not have this attribute"); } copyProperty(property, backup, target); } else { // nested bean properties Object targetObj = target; Object realBackup = backup; String[] nestedProperty = getNestedProperty(property); if (nestedProperty != null && nestedProperty.length > 1) { for (int i = 0; i < nestedProperty.length - 1; i++) { sourcePropertyDescriptor = getProperty( nestedProperty[i], realBackup); destPropertyDescriptor = getProperty(nestedProperty[i], targetObj); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException( "This property does not exist in the target object to be copied to"); } Method readMethod = sourcePropertyDescriptor .getReadMethod(); realBackup = readMethod.invoke(realBackup); if (realBackup == null) { // Determine whether the nested property of the backup object is empty realBackup = sourcePropertyDescriptor .getPropertyType().newInstance(); } Method writeMethod = destPropertyDescriptor .getWriteMethod (); readMethod = destPropertyDescriptor.getReadMethod(); Object value = readMethod.invoke(targetObj); if (value == null) { value = destPropertyDescriptor.getPropertyType() .newInstance(); writeMethod.invoke(targetObj, value); } targetObj = value; } final String prop = nestedProperty[nestedProperty.length - 1]; sourcePropertyDescriptor = getProperty(prop, realBackup); destPropertyDescriptor = getProperty(prop, targetObj); if (sourcePropertyDescriptor == null) { throw new IllegalArgumentException("The source object to be copied does not have this attribute"); } if (destPropertyDescriptor == null) { throw new IllegalArgumentException("The target object to be copied does not have this attribute"); } copyProperty (prop, realBackup, targetObj); } } } } /** * Object clone */ private static Object clone(final Object value) throws IOException, ClassNotFoundException { // Byte array output stream, temporarily stored in memory ByteArrayOutputStream bos = new ByteArrayOutputStream(); // Serialization ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(value); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); // deserialize return ois.readObject(); } /** * Determine whether it is a simple property, yes, return true * * @author yang_qiao * * @date 2013-12-18 */ private static boolean isSimpleProperty(final String property) { return !property.contains(NESTED); } /** * Get the properties of the target bean */ private static PropertyDescriptor getProperty(final String propertyName, final Object target) { if (target == null) { new IllegalArgumentException("The object of the query property is empty"); } if (propertyName == null || "".equals(propertyName)) { new IllegalArgumentException("The query attribute cannot be null"); } PropertyDescriptor propertyDescriptor = null; try { propertyDescriptor = new PropertyDescriptor(propertyName, target.getClass()); } catch (IntrospectionException e) { logger.info("The property does not exist"); return null; } return propertyDescriptor; } /** * Single attribute copy--the original data source and destination data source must have this attribute * * @throws InvocationTargetException * * @throws IllegalAccessException * * @throws IllegalArgumentException * * @throws IntrospectionException */ public static void copyProperty(final String propertyName, final Object source, Object dest) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException { PropertyDescriptor property; property = new PropertyDescriptor(propertyName, source.getClass()); Method getMethod = property.getReadMethod(); Object value = getMethod.invoke(source); property = new PropertyDescriptor(propertyName, dest.getClass()); Method setMethod = property.getWriteMethod(); setMethod.invoke(dest, value); } /** * Get properties of nested beans * * @author yang_qiao * * @date 2013-12-18 */ public static String[] getNestedProperty(final String nestedProperty) { if (nestedProperty == null || "".equals(nestedProperty)) { new IllegalArgumentException("Argument is null"); } return nestedProperty.split("\\" + NESTED); } /** * Ignore null copy property values * @param source * @param target * @throws BeansException */ public static void copyProperties(Object source, Object target) throws BeansException { if (source == null) { throw new IllegalArgumentException("The source object to be copied is empty"); } if (target == null) { throw new IllegalArgumentException("The destination object to be copied is empty"); } Class<?> actualEditable = target.getClass(); PropertyDescriptor[] targetPds = org.springframework.beans.BeanUtils.getPropertyDescriptors(actualEditable); for (PropertyDescriptor targetPd : targetPds) { if (targetPd.getWriteMethod() != null) { PropertyDescriptor sourcePd = org.springframework.beans.BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName()); if (sourcePd != null && sourcePd.getReadMethod() != null) { try { Method readMethod = sourcePd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source); // Here it is judged whether the following value is empty. Of course, some special requirements can also be processed here, such as format conversion during binding, etc. if (value != null) { Method writeMethod = targetPd.getWriteMethod (); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, value); } } catch (Throwable ex) { throw new FatalBeanException("Could not copy properties from source to target", ex); } } } } } }
javabean property copy BeanUtil
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=326394572&siteId=291194637
Recommended
Ranking