implementation that should be sufficient
for all typical use cases. Caches introspection results for efficiency.
| Method from org.springframework.beans.BeanWrapperImpl Detail: |
public Object convertForProperty(Object value,
String propertyName) throws TypeMismatchException {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
if (pd == null) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"No property '" + propertyName + "' found");
}
try {
return this.typeConverterDelegate.convertIfNecessary(null, value, pd);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, value);
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
}
}
Convert the given value for the specified property to the latter's type.
This method is only intended for optimizations in a BeanFactory.
Use the convertIfNecessary methods for programmatic conversion. |
public Object convertIfNecessary(Object value,
Class requiredType,
MethodParameter methodParam) throws TypeMismatchException {
try {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchException(value, requiredType, ex);
}
}
|
public Object doTypeConversionIfNecessary(Object value,
Class requiredType) throws TypeMismatchException {
return convertIfNecessary(value, requiredType, null);
} Deprecated! in - favor of convertIfNecessary
|
protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath) {
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
// Handle nested properties recursively.
if (pos > -1) {
String nestedProperty = propertyPath.substring(0, pos);
String nestedPath = propertyPath.substring(pos + 1);
BeanWrapperImpl nestedBw = getNestedBeanWrapper(nestedProperty);
return nestedBw.getBeanWrapperForPropertyPath(nestedPath);
}
else {
return this;
}
}
Recursively navigate to return a BeanWrapper for the nested property path. |
public final String getNestedPath() {
return this.nestedPath;
}
Return the nested path of the object wrapped by this BeanWrapper. |
public PropertyDescriptor getPropertyDescriptor(String propertyName) throws BeansException {
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
if (pd == null) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"No property '" + propertyName + "' found");
}
return pd;
}
|
protected PropertyDescriptor getPropertyDescriptorInternal(String propertyName) throws BeansException {
Assert.notNull(propertyName, "Property name must not be null");
BeanWrapperImpl nestedBw = getBeanWrapperForPropertyPath(propertyName);
return nestedBw.getCachedIntrospectionResults().getPropertyDescriptor(getFinalPath(nestedBw, propertyName));
}
|
public PropertyDescriptor[] getPropertyDescriptors() {
return getCachedIntrospectionResults().getBeanInfo().getPropertyDescriptors();
}
|
public Class getPropertyType(String propertyName) throws BeansException {
try {
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
if (pd != null) {
return pd.getPropertyType();
}
else {
// Maybe an indexed/mapped property...
Object value = getPropertyValue(propertyName);
if (value != null) {
return value.getClass();
}
// Check to see if there is a custom editor,
// which might give an indication on the desired target type.
Class editorType = guessPropertyTypeFromEditors(propertyName);
if (editorType != null) {
return editorType;
}
}
}
catch (InvalidPropertyException ex) {
// Consider as not determinable.
}
return null;
}
|
public Object getPropertyValue(String propertyName) throws BeansException {
BeanWrapperImpl nestedBw = getBeanWrapperForPropertyPath(propertyName);
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
return nestedBw.getPropertyValue(tokens);
}
|
public final Class getRootClass() {
return (this.rootObject != null ? this.rootObject.getClass() : null);
}
Return the class of the root object at the top of the path of this BeanWrapper. |
public final Object getRootInstance() {
return this.rootObject;
}
Return the root object at the top of the path of this BeanWrapper. |
public final Class getWrappedClass() {
return (this.object != null ? this.object.getClass() : null);
}
|
public final Object getWrappedInstance() {
return this.object;
}
|
public boolean isReadableProperty(String propertyName) {
try {
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
if (pd != null) {
if (pd.getReadMethod() != null) {
return true;
}
}
else {
// Maybe an indexed/mapped property...
getPropertyValue(propertyName);
return true;
}
}
catch (InvalidPropertyException ex) {
// Cannot be evaluated, so can't be readable.
}
return false;
}
|
public boolean isWritableProperty(String propertyName) {
try {
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
if (pd != null) {
if (pd.getWriteMethod() != null) {
return true;
}
}
else {
// Maybe an indexed/mapped property...
getPropertyValue(propertyName);
return true;
}
}
catch (InvalidPropertyException ex) {
// Cannot be evaluated, so can't be writable.
}
return false;
}
|
protected BeanWrapperImpl newNestedBeanWrapper(Object object,
String nestedPath) {
return new BeanWrapperImpl(object, nestedPath, this);
}
Create a new nested BeanWrapper instance.
Default implementation creates a BeanWrapperImpl instance.
Can be overridden in subclasses to create a BeanWrapperImpl subclass. |
protected void setIntrospectionClass(Class clazz) {
if (this.cachedIntrospectionResults != null &&
!clazz.equals(this.cachedIntrospectionResults.getBeanClass())) {
this.cachedIntrospectionResults = null;
}
}
Set the class to introspect.
Needs to be called when the target object changes. |
public void setPropertyValue(PropertyValue pv) throws BeansException {
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null) {
String propertyName = pv.getName();
BeanWrapperImpl nestedBw = null;
try {
nestedBw = getBeanWrapperForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
if (nestedBw == this) {
pv.getOriginalPropertyValue().resolvedTokens = tokens;
}
nestedBw.setPropertyValue(tokens, pv);
}
else {
setPropertyValue(tokens, pv);
}
}
|
public void setPropertyValue(String propertyName,
Object value) throws BeansException {
BeanWrapperImpl nestedBw = null;
try {
nestedBw = getBeanWrapperForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value));
}
|
public void setWrappedInstance(Object object) {
setWrappedInstance(object, "", null);
}
Switch the target object, replacing the cached introspection results only
if the class of the new object is different to that of the replaced object. |
public void setWrappedInstance(Object object,
String nestedPath,
Object rootObject) {
Assert.notNull(object, "Bean object must not be null");
this.object = object;
this.nestedPath = (nestedPath != null ? nestedPath : "");
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : object);
this.nestedBeanWrappers = null;
this.typeConverterDelegate = new TypeConverterDelegate(this, object);
setIntrospectionClass(object.getClass());
}
Switch the target object, replacing the cached introspection results only
if the class of the new object is different to that of the replaced object. |
public String toString() {
StringBuffer sb = new StringBuffer(getClass().getName());
if (this.object != null) {
sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.object)).append("]");
}
else {
sb.append(": no wrapped object set");
}
return sb.toString();
}
|