📄 beanwrapperimpl.java
字号:
null, newValue);
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
}
else {
throw new MethodInvocationException(ex.getTargetException(), propertyChangeEvent);
}
}
catch (IllegalAccessException ex) {
throw new FatalBeanException("Illegal attempt to set property [" + value + "] threw exception", ex);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this.object, this.nestedPath + propertyName,
null, newValue);
throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex);
}
}
}
public void setPropertyValue(PropertyValue pv) throws BeansException {
setPropertyValue(pv.getName(), pv.getValue());
}
/**
* Bulk update from a Map.
* Bulk updates from PropertyValues are more powerful: this method is
* provided for convenience.
* @param map map containing properties to set, as name-value pairs.
* The map may include nested properties.
* @throws BeansException if there's a fatal, low-level exception
*/
public void setPropertyValues(Map map) throws BeansException {
setPropertyValues(new MutablePropertyValues(map));
}
public void setPropertyValues(PropertyValues pvs) throws BeansException {
setPropertyValues(pvs, false);
}
public void setPropertyValues(PropertyValues propertyValues, boolean ignoreUnknown) throws BeansException {
List propertyAccessExceptions = new ArrayList();
PropertyValue[] pvs = propertyValues.getPropertyValues();
for (int i = 0; i < pvs.length; i++) {
try {
// This method may throw ReflectionException, which won't be caught
// here, if there is a critical failure such as no matching field.
// We can attempt to deal only with less serious exceptions.
setPropertyValue(pvs[i]);
}
// fatal ReflectionExceptions will just be rethrown
catch (NotWritablePropertyException ex) {
if (!ignoreUnknown) {
throw ex;
}
// otherwise, just ignore it and continue...
}
catch (TypeMismatchException ex) {
propertyAccessExceptions.add(ex);
}
catch (MethodInvocationException ex) {
propertyAccessExceptions.add(ex);
}
}
// if we encountered individual exceptions, throw the composite exception
if (!propertyAccessExceptions.isEmpty()) {
Object[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
throw new PropertyAccessExceptionsException(this, (PropertyAccessException[]) paeArray);
}
}
private PropertyChangeEvent createPropertyChangeEvent(String propertyName, Object oldValue, Object newValue)
throws BeansException {
return new PropertyChangeEvent((this.object != null ? this.object : "constructor"),
(propertyName != null ? this.nestedPath + propertyName : null),
oldValue, newValue);
}
/**
* Convert the value to the required type (if necessary from a String).
* Conversions from String to any type use the setAsText() method of
* the PropertyEditor class. Note that a PropertyEditor must be registered
* for this class for this to work. This is a standard Java Beans API.
* A number of property editors are automatically registered by this class.
* @param newValue proposed change value.
* @param requiredType type we must convert to
* @throws BeansException if there is an internal error
* @return new value, possibly the result of type convertion
*/
public Object doTypeConversionIfNecessary(Object newValue, Class requiredType) throws BeansException {
return doTypeConversionIfNecessary(null, null, null, newValue, requiredType);
}
/**
* Convert the value to the required type (if necessary from a String),
* for the specified property.
* @param propertyName name of the property
* @param oldValue previous value, if available (may be null)
* @param newValue proposed change value.
* @param requiredType type we must convert to
* @throws BeansException if there is an internal error
* @return new value, possibly the result of type convertion
*/
protected Object doTypeConversionIfNecessary(String propertyName, String fullPropertyName,
Object oldValue, Object newValue,
Class requiredType) throws BeansException {
if (newValue != null) {
if (requiredType != null && requiredType.isArray()) {
// convert individual elements to array elements
Class componentType = requiredType.getComponentType();
if (newValue instanceof List) {
List list = (List) newValue;
Object result = Array.newInstance(componentType, list.size());
for (int i = 0; i < list.size(); i++) {
Object value = doTypeConversionIfNecessary(propertyName, propertyName + "[" + i + "]",
null, list.get(i), componentType);
Array.set(result, i, value);
}
return result;
}
else if (newValue instanceof Object[]) {
Object[] array = (Object[]) newValue;
Object result = Array.newInstance(componentType, array.length);
for (int i = 0; i < array.length; i++) {
Object value = doTypeConversionIfNecessary(propertyName, propertyName + "[" + i + "]",
null, array[i], componentType);
Array.set(result, i, value);
}
return result;
}
}
// custom editor for this type?
PropertyEditor pe = findCustomEditor(requiredType, fullPropertyName);
// value not of required type?
if (pe != null || (requiredType != null && !requiredType.isAssignableFrom(newValue.getClass()))) {
if (newValue instanceof String[]) {
if (logger.isDebugEnabled()) {
logger.debug("Converting String array to comma-delimited String [" + newValue + "]");
}
newValue = StringUtils.arrayToCommaDelimitedString((String[]) newValue);
}
if (newValue instanceof String) {
if (pe == null) {
// no custom editor -> check BeanWrapper's default editors
pe = findDefaultEditor(requiredType);
if (pe == null) {
// no BeanWrapper default editor -> check standard JavaBean editors
pe = PropertyEditorManager.findEditor(requiredType);
}
}
if (pe != null) {
// use PropertyEditor's setAsText in case of a String value
if (logger.isDebugEnabled()) {
logger.debug("Converting String to [" + requiredType + "] using property editor [" + pe + "]");
}
try {
pe.setAsText((String) newValue);
newValue = pe.getValue();
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchException(createPropertyChangeEvent(fullPropertyName, oldValue, newValue),
requiredType, ex);
}
}
else {
throw new TypeMismatchException(createPropertyChangeEvent(fullPropertyName, oldValue, newValue),
requiredType);
}
}
else if (pe != null) {
// Not a String -> use PropertyEditor's setValue.
// With standard PropertyEditors, this will return the very same object;
// we just want to allow special PropertyEditors to override setValue
// for type conversion from non-String values to the required type.
try {
pe.setValue(newValue);
newValue = pe.getValue();
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchException(createPropertyChangeEvent(fullPropertyName, oldValue, newValue),
requiredType, ex);
}
}
}
if (requiredType != null && requiredType.isArray() && !newValue.getClass().isArray()) {
Class componentType = requiredType.getComponentType();
Object result = Array.newInstance(componentType, 1) ;
Object val = doTypeConversionIfNecessary(propertyName, propertyName + "[0]",
null, newValue, componentType);
Array.set(result, 0, val) ;
return result;
}
}
return newValue;
}
private PropertyEditor findDefaultEditor(Class type) {
Class editorClass = (Class) defaultEditors.get(type);
if (editorClass != null) {
return (PropertyEditor) BeanUtils.instantiateClass(editorClass);
}
else {
return null;
}
}
public PropertyDescriptor[] getPropertyDescriptors() {
return this.cachedIntrospectionResults.getBeanInfo().getPropertyDescriptors();
}
public PropertyDescriptor getPropertyDescriptor(String propertyName) throws BeansException {
if (propertyName == null) {
throw new FatalBeanException("Can't find property descriptor for null property");
}
if (isNestedProperty(propertyName)) {
BeanWrapper nestedBw = getBeanWrapperForPropertyPath(propertyName);
return nestedBw.getPropertyDescriptor(getFinalPath(propertyName));
}
return this.cachedIntrospectionResults.getPropertyDescriptor(propertyName);
}
public Class getPropertyType(String propertyName) throws BeansException {
Class type = null;
try {
type = getPropertyDescriptor(propertyName).getPropertyType();
}
catch (BeansException ex) {
// probably an indexed or mapped element
Object value = getPropertyValue(propertyName);
if (value != null) {
type = value.getClass();
}
}
return type;
}
public boolean isReadableProperty(String propertyName) {
// This is a programming error, although asking for a property
// that doesn't exist is not
if (propertyName == null) {
throw new FatalBeanException("Can't find readability status for null property");
}
try {
return getPropertyDescriptor(propertyName).getReadMethod() != null;
}
catch (BeansException ex) {
// doesn't exist, so can't be readable
return false;
}
}
public boolean isWritableProperty(String propertyName) {
// This is a programming error, although asking for a property
// that doesn't exist is not.
if (propertyName == null) {
throw new FatalBeanException("Can't find writability status for null property");
}
try {
return getPropertyDescriptor(propertyName).getWriteMethod() != null;
}
catch (BeansException ex) {
// doesn't exist, so can't be writable
return false;
}
}
//---------------------------------------------------------------------
// Diagnostics
//---------------------------------------------------------------------
/**
* This method is expensive! Only call for diagnostics and debugging reasons,
* not in production.
* @return a string describing the state of this object
*/
public String toString() {
StringBuffer sb = new StringBuffer();
try {
sb.append("BeanWrapperImpl:"
+ " wrapping class [" + getWrappedInstance().getClass().getName() + "]; ");
PropertyDescriptor pds[] = getPropertyDescriptors();
if (pds != null) {
for (int i = 0; i < pds.length; i++) {
Object val = getPropertyValue(pds[i].getName());
String valStr = (val != null) ? val.toString() : "null";
sb.append(pds[i].getName() + "={" + valStr + "}");
}
}
}
catch (Exception ex) {
sb.append("exception encountered: " + ex);
}
return sb.toString();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -