📄 beanutil.java
字号:
/* * WebWork, Web Application Framework * * Distributable under Apache license. * See terms of license at opensource.org */package webwork.util;import webwork.action.IllegalArgumentAware;import webwork.action.ValidationEditorSupport;import webwork.util.editor.*;import java.beans.*;import java.lang.reflect.Method;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Array;import java.util.*;import java.text.DateFormat;import java.math.BigDecimal;import java.sql.Timestamp;import org.apache.commons.logging.*;/** * JavaBean utility methods * * @author Rickard 謆erg (rickard@middleware-company.com) * @author Matt Baldree (matt@smallleap.com) * @version $Revision: 1.39 $ */public final class BeanUtil{ // Static ------------------------------------------------------- // Class -> PropertyDescriptor[] map static Map propertyDescriptors = new WeakHashMap(); // The map is cloned when it is updated so we do not have to use Hashtable static Map propertyEditors = new HashMap(); static Map objectMap = new WeakHashMap(); static final Log log = LogFactory.getLog(BeanUtil.class); static { PropertyEditorManager.registerEditor(Integer.class, IntegerObjectEditor.class); PropertyEditorManager.registerEditor(Integer[].class, IntegerObjectEditor.class); PropertyEditorManager.registerEditor(int.class, IntegerEditor.class); PropertyEditorManager.registerEditor(int[].class, IntegerEditor.class); PropertyEditorManager.registerEditor(Double.class, DoubleObjectEditor.class); PropertyEditorManager.registerEditor(Double[].class, DoubleObjectEditor.class); PropertyEditorManager.registerEditor(double.class, DoubleEditor.class); PropertyEditorManager.registerEditor(double[].class, DoubleEditor.class); PropertyEditorManager.registerEditor(Byte.class, ByteObjectEditor.class); PropertyEditorManager.registerEditor(Byte[].class, ByteObjectEditor.class); PropertyEditorManager.registerEditor(byte.class, ByteEditor.class); PropertyEditorManager.registerEditor(byte[].class, ByteEditor.class); PropertyEditorManager.registerEditor(Short.class, ShortObjectEditor.class); PropertyEditorManager.registerEditor(Short[].class, ShortObjectEditor.class); PropertyEditorManager.registerEditor(short.class, ShortEditor.class); PropertyEditorManager.registerEditor(short[].class, ShortEditor.class); PropertyEditorManager.registerEditor(Long.class, LongObjectEditor.class); PropertyEditorManager.registerEditor(Long[].class, LongObjectEditor.class); PropertyEditorManager.registerEditor(long.class, LongEditor.class); PropertyEditorManager.registerEditor(long[].class, LongEditor.class); PropertyEditorManager.registerEditor(Float.class, FloatObjectEditor.class); PropertyEditorManager.registerEditor(Float[].class, FloatObjectEditor.class); PropertyEditorManager.registerEditor(float.class, FloatEditor.class); PropertyEditorManager.registerEditor(float[].class, FloatEditor.class); PropertyEditorManager.registerEditor(Boolean.class, BooleanObjectEditor.class); PropertyEditorManager.registerEditor(Boolean[].class, BooleanObjectEditor.class); PropertyEditorManager.registerEditor(boolean.class, BooleanEditor.class); PropertyEditorManager.registerEditor(boolean[].class, BooleanEditor.class); PropertyEditorManager.registerEditor(String.class, StringEditor.class); PropertyEditorManager.registerEditor(String[].class, StringEditor.class); PropertyEditorManager.registerEditor(BigDecimal.class, BigDecimalEditor.class); PropertyEditorManager.registerEditor(BigDecimal[].class, BigDecimalEditor.class); PropertyEditorManager.registerEditor(Date.class, DateEditor.class); PropertyEditorManager.registerEditor(Date[].class, DateEditor.class); PropertyEditorManager.registerEditor(Timestamp.class, TimestampEditor.class); PropertyEditorManager.registerEditor(Timestamp[].class, TimestampEditor.class); PropertyEditorManager.registerEditor(DateFormat.class, DateFormatEditor.class); } /** * Copy JavaBean property values from one object to another. * * @param from the source object * @param to the destination object * @exception IllegalArgumentException thrown if the copy fails for some reason */ public static void copy(Object from, Object to) throws IllegalArgumentException { copy(from, to, true); } /** * Copy JavaBean property values from one object to another. * * @param from the source object * @param to the destination object * @param includeNull whether null values are copied or not * @exception IllegalArgumentException thrown if the copy fails for some reason */ public static void copy(Object from, Object to, boolean includeNull) throws IllegalArgumentException { try { Object[] readParameters = new Object[0]; Object[] writeParameters = new Object[1]; PropertyDescriptor[] propertiesFrom = getPropertyDescriptors(from.getClass()); // Get the field map of the destination object once Map fieldMap = getFieldMapForClass(to.getClass()); for (int i = 0; i < propertiesFrom.length; i++) { PropertyDescriptor pdFrom = propertiesFrom[i]; // Look up the destination descriptor in the fieldMap PropertyDescriptor pdTo = (PropertyDescriptor) fieldMap.get(pdFrom.getName()); if (pdTo != null) { Method readMethod = pdFrom.getReadMethod(); Method writeMethod = pdTo.getWriteMethod(); if (writeMethod != null && readMethod != null) { writeParameters[0] = pdFrom.getReadMethod().invoke(from, readParameters); if (!(!includeNull && writeParameters[0] == null)) pdTo.getWriteMethod().invoke(to, writeParameters); } } } } catch (Exception e) { log.warn("Bean copy failed:"+e, e); throw new IllegalArgumentException("Bean copy failed:" + e); } } /** * Set JavaBean property values on an object with values taken from a map. * * If the values in the map are of type String or String[] they may be converted * to the actual property type by the use of property editors. * * @param from map of values * @param to the destination object * @exception IllegalArgumentException */ public static void setProperties(Map from, Object to) throws IllegalArgumentException { String key = null; try { Iterator keys = from.keySet().iterator(); Map fieldMap = null; // Get the fieldMap of the destination object once if (keys.hasNext()) fieldMap = getFieldMapForClass(to.getClass()); while (keys.hasNext()) { key = (String) keys.next(); try { setProperty(key, from.get(key), to, fieldMap); } catch (IllegalArgumentException e) { // Handle IEA's on actions specially if (to instanceof IllegalArgumentAware) { ((IllegalArgumentAware) to).addIllegalArgumentException(key, e); } else { throw e; } } } } catch (Throwable e) { log.warn("Could not set parameter \"" + key + "\":" + e, e); throw new IllegalArgumentException("Could not set parameter \"" + key + "\":" + e); } } /** * Set a single JavaBean property value on an object. * * If the values in the map are of type String or String[] they may be converted * to the actual property type by the use of property editors. * * @param propertyName String representing the property or subproperty * @param val the value to set * @param obj the object to set the property on. * @exception IllegalArgumentException */ static public void setProperty(String propertyName, Object val, Object obj) throws IllegalArgumentException { if (obj == null) { throw new IllegalArgumentException("The target object for property '" + propertyName + "'. The target object needs to be initialized to a non-null value in order to set this property."); } Map fieldMap = getFieldMapForClass(obj.getClass()); setProperty(propertyName, val, obj, fieldMap); } /** * Set a single JavaBean property value on an object. * * If the values in the map are of type String or String[] they may be converted * to the actual property type by the use of property editors. * * @param propertyName String representing the property or subproperty * @param val the value to set * @param obj the object to set the property on. * @param fieldMap Map with the PropertyDescriptors of the obj * @exception IllegalArgumentException */ static protected void setProperty(String propertyName, Object val, Object obj, Map fieldMap) throws IllegalArgumentException { Query query = Query.getQuery(propertyName); QuerySegment[] segments = query.getSegments(); Object curObject = obj; Map curFieldMap; int totalNumberOfSegments = findTheActualNumberOfSegments(segments); for (int i = 0; i < totalNumberOfSegments; ++i) { if (curObject == null) { throw new IllegalArgumentException("The target object for property '" + propertyName + "'. The target object needs to be initialized to a non-null value in order to set this property."); } QuerySegment curSegment = segments[i]; PropertyDescriptor descriptor; // Is the current object the same as the original one? // If not, get the field map for the new object if (curObject != obj) { curFieldMap = getFieldMapForClass(curObject.getClass()); } else { curFieldMap = fieldMap; } // Lookup the descriptor in the curFieldMap descriptor = (PropertyDescriptor) curFieldMap.get(curSegment.getId()); if (descriptor == null && curSegment.getType() != QuerySegment.COLLECTION) { return; } else if (curSegment.getType() == QuerySegment.COLLECTION) { String key = curSegment.getId(); // Map if (Map.class.isAssignableFrom(curObject.getClass())) { curObject = ((Map) curObject).get(key); } // Resource Bundle else if (ResourceBundle.class.isAssignableFrom(curObject.getClass())) { curObject = ((ResourceBundle) curObject).getObject(key.toString()); } // Array else if (curObject.getClass().isArray()) { curObject = ((Object[]) curObject)[Integer.parseInt(key)]; } // List else if (List.class.isAssignableFrom(curObject.getClass())) { curObject = ((List) curObject).get(Integer.parseInt(key)); } // Collection else if (Collection.class.isAssignableFrom(curObject.getClass())) { // Not very efficient, but at least it works curObject = ((Collection) curObject).toArray()[Integer.parseInt(key)]; } } else if (curSegment.getType() == QuerySegment.PROPERTY) //regular properties { try { if (descriptor instanceof IndexedPropertyDescriptor) { throw new IllegalArgumentException("Attempting to set a indexed field " + curSegment.getId() + " as an non-indexed field"); } //if here then we are setting the property directly if ((i + 1) == totalNumberOfSegments) { setValue(curObject, descriptor, val); return; } //if here then read a property to continue on... else { Method m = descriptor.getReadMethod(); if (m == null) { throw new IllegalArgumentException("Read Method " + descriptor.getName() + " for " + curObject.getClass().getName() + " was not found"); } curObject = m.invoke(curObject, new Object[0]); } } catch (IllegalArgumentException iae) { throw iae; } catch (Exception e) { log.warn("Error executing read method for " + descriptor.getName() + " on " + curObject.getClass().getName(), e); throw new IllegalArgumentException("Error executing read method for " + descriptor.getName() + " on " + curObject.getClass().getName()); } } //indexed properties else if (curSegment.getType() == QuerySegment.METHOD) { Integer index = getIndexedPropertyIndex(curSegment); try { //if here then we are setting an indexed property directly if ((i + 1) == totalNumberOfSegments) { if (descriptor instanceof IndexedPropertyDescriptor) { setIndexedValue(curObject, (IndexedPropertyDescriptor) descriptor, val, index); return; } else { throw new IllegalArgumentException("Attempting to set non-indexed field \"" + curSegment.getId() + "\" as an indexed field"); } } //if here then get next object in the chain else { if (descriptor instanceof IndexedPropertyDescriptor) { Method m = ((IndexedPropertyDescriptor) descriptor).getIndexedReadMethod(); if (m == null) { throw new IllegalArgumentException("Indexed Read Method " + descriptor.getName() + " for " + curObject.getClass().getName() + " was not found"); } curObject = m.invoke(curObject, new Object[]{index}); } else { throw new IllegalArgumentException("Attempting to access non-indexed field \"" + curSegment.getId() + "\" as an indexed field"); } } } catch (IllegalArgumentException iae) { throw iae;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -