Issue: SPR-12185master
parent
03e51d6de9
commit
d1c720c07b
1 changed files with 174 additions and 0 deletions
@ -0,0 +1,174 @@ |
||||
/* |
||||
* Copyright 2002-2014 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.beans; |
||||
|
||||
import java.beans.IntrospectionException; |
||||
import java.beans.PropertyDescriptor; |
||||
import java.lang.reflect.Method; |
||||
import java.util.Enumeration; |
||||
|
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Common delegate methods for Spring's internal {@link PropertyDescriptor} implementations. |
||||
* |
||||
* @author Chris Beams |
||||
* @author Juergen Hoeller |
||||
*/ |
||||
class PropertyDescriptorUtils { |
||||
|
||||
/** |
||||
* See {@link java.beans.FeatureDescriptor}. |
||||
*/ |
||||
public static void copyNonMethodProperties(PropertyDescriptor source, PropertyDescriptor target) |
||||
throws IntrospectionException { |
||||
|
||||
target.setExpert(source.isExpert()); |
||||
target.setHidden(source.isHidden()); |
||||
target.setPreferred(source.isPreferred()); |
||||
target.setName(source.getName()); |
||||
target.setShortDescription(source.getShortDescription()); |
||||
target.setDisplayName(source.getDisplayName()); |
||||
|
||||
// Copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
|
||||
Enumeration<String> keys = source.attributeNames(); |
||||
while (keys.hasMoreElements()) { |
||||
String key = keys.nextElement(); |
||||
target.setValue(key, source.getValue(key)); |
||||
} |
||||
|
||||
// See java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
|
||||
target.setPropertyEditorClass(source.getPropertyEditorClass()); |
||||
target.setBound(source.isBound()); |
||||
target.setConstrained(source.isConstrained()); |
||||
} |
||||
|
||||
/** |
||||
* See {@link java.beans.PropertyDescriptor#findPropertyType}. |
||||
*/ |
||||
public static Class<?> findPropertyType(Method readMethod, Method writeMethod) throws IntrospectionException { |
||||
Class<?> propertyType = null; |
||||
|
||||
if (readMethod != null) { |
||||
Class<?>[] params = readMethod.getParameterTypes(); |
||||
if (params.length != 0) { |
||||
throw new IntrospectionException("Bad read method arg count: " + readMethod); |
||||
} |
||||
propertyType = readMethod.getReturnType(); |
||||
if (propertyType == Void.TYPE) { |
||||
throw new IntrospectionException("Read method returns void: " + readMethod); |
||||
} |
||||
} |
||||
|
||||
if (writeMethod != null) { |
||||
Class<?> params[] = writeMethod.getParameterTypes(); |
||||
if (params.length != 1) { |
||||
throw new IntrospectionException("Bad write method arg count: " + writeMethod); |
||||
} |
||||
if (propertyType != null) { |
||||
if (propertyType.isAssignableFrom(params[0])) { |
||||
// Write method's property type potentially more specific
|
||||
propertyType = params[0]; |
||||
} |
||||
else if (params[0].isAssignableFrom(propertyType)) { |
||||
// Proceed with read method's property type
|
||||
} |
||||
else { |
||||
throw new IntrospectionException( |
||||
"Type mismatch between read and write methods: " + readMethod + " - " + writeMethod); |
||||
} |
||||
} |
||||
else { |
||||
propertyType = params[0]; |
||||
} |
||||
} |
||||
|
||||
return propertyType; |
||||
} |
||||
|
||||
/** |
||||
* See {@link java.beans.IndexedPropertyDescriptor#findIndexedPropertyType}. |
||||
*/ |
||||
public static Class<?> findIndexedPropertyType(String name, Class<?> propertyType, |
||||
Method indexedReadMethod, Method indexedWriteMethod) throws IntrospectionException { |
||||
|
||||
Class<?> indexedPropertyType = null; |
||||
|
||||
if (indexedReadMethod != null) { |
||||
Class<?> params[] = indexedReadMethod.getParameterTypes(); |
||||
if (params.length != 1) { |
||||
throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod); |
||||
} |
||||
if (params[0] != Integer.TYPE) { |
||||
throw new IntrospectionException("Non int index to indexed read method: " + indexedReadMethod); |
||||
} |
||||
indexedPropertyType = indexedReadMethod.getReturnType(); |
||||
if (indexedPropertyType == Void.TYPE) { |
||||
throw new IntrospectionException("Indexed read method returns void: " + indexedReadMethod); |
||||
} |
||||
} |
||||
|
||||
if (indexedWriteMethod != null) { |
||||
Class<?> params[] = indexedWriteMethod.getParameterTypes(); |
||||
if (params.length != 2) { |
||||
throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod); |
||||
} |
||||
if (params[0] != Integer.TYPE) { |
||||
throw new IntrospectionException("Non int index to indexed write method: " + indexedWriteMethod); |
||||
} |
||||
if (indexedPropertyType != null) { |
||||
if (indexedPropertyType.isAssignableFrom(params[1])) { |
||||
// Write method's property type potentially more specific
|
||||
indexedPropertyType = params[1]; |
||||
} |
||||
else if (params[1].isAssignableFrom(indexedPropertyType)) { |
||||
// Proceed with read method's property type
|
||||
} |
||||
else { |
||||
throw new IntrospectionException("Type mismatch between indexed read and write methods: " + |
||||
indexedReadMethod + " - " + indexedWriteMethod); |
||||
} |
||||
} |
||||
else { |
||||
indexedPropertyType = params[1]; |
||||
} |
||||
} |
||||
|
||||
if (propertyType != null && (!propertyType.isArray() || |
||||
propertyType.getComponentType() != indexedPropertyType)) { |
||||
throw new IntrospectionException("Type mismatch between indexed and non-indexed methods: " + |
||||
indexedReadMethod + " - " + indexedWriteMethod); |
||||
} |
||||
|
||||
return indexedPropertyType; |
||||
} |
||||
|
||||
/** |
||||
* Compare the given {@code PropertyDescriptors} and return {@code true} if |
||||
* they are equivalent, i.e. their read method, write method, property type, |
||||
* property editor and flags are equivalent. |
||||
* @see java.beans.PropertyDescriptor#equals(Object) |
||||
*/ |
||||
public static boolean equals(PropertyDescriptor pd, PropertyDescriptor otherPd) { |
||||
return (ObjectUtils.nullSafeEquals(pd.getReadMethod(), otherPd.getReadMethod()) && |
||||
ObjectUtils.nullSafeEquals(pd.getWriteMethod(), otherPd.getWriteMethod()) && |
||||
ObjectUtils.nullSafeEquals(pd.getPropertyType(), otherPd.getPropertyType()) && |
||||
ObjectUtils.nullSafeEquals(pd.getPropertyEditorClass(), otherPd.getPropertyEditorClass()) && |
||||
pd.isBound() == otherPd.isBound() && pd.isConstrained() == otherPd.isConstrained()); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue