Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2002-2008 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.util.List;
 import java.util.Map;
 import java.util.Set;
 
 
Default BeanWrapper implementation that should be sufficient for all typical use cases. Caches introspection results for efficiency.

Note: Auto-registers default property editors from the org.springframework.beans.propertyeditors package, which apply in addition to the JDK's standard PropertyEditors. Applications can call the PropertyEditorRegistrySupport.registerCustomEditor(java.lang.Class,java.beans.PropertyEditor) method to register an editor for a particular instance (i.e. they are not shared across the application). See the base class PropertyEditorRegistrySupport for details.

BeanWrapperImpl will convert collection and array values to the corresponding target collections or arrays, if necessary. Custom property editors that deal with collections or arrays can either be written via PropertyEditor's setValue, or against a comma-delimited String via setAsText, as String arrays are converted in such a format if the array itself is not assignable.

NOTE: As of Spring 2.5, this is - for almost all purposes - an internal class. It is just public in order to allow for access from other framework packages. For standard application access purposes, use the PropertyAccessorFactory.forBeanPropertyAccess(java.lang.Object) factory method instead.

 
 public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWrapper {

We'll create a lot of these objects, so we don't want a new logger every time.
 
 	private static final Log logger = LogFactory.getLog(BeanWrapperImpl.class);


The wrapped object
 
 	private Object object;
 
 	private String nestedPath = "";
 
 	private Object rootObject;
 
Cached introspections results for this object, to prevent encountering the cost of JavaBeans introspection every time.
 
Map with cached nested BeanWrappers: nested path -> BeanWrapper instance.
Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards. Registers default editors.

	public BeanWrapperImpl() {
		this(true);
	}

Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.

Parameters:
registerDefaultEditors whether to register default editors (can be suppressed if the BeanWrapper won't need any type conversion)
See also:
setWrappedInstance(java.lang.Object)
	public BeanWrapperImpl(boolean registerDefaultEditors) {
		if (registerDefaultEditors) {
		}
	}

Create new BeanWrapperImpl for the given object.

Parameters:
object object wrapped by this BeanWrapper
	public BeanWrapperImpl(Object object) {
	}

Create new BeanWrapperImpl, wrapping a new instance of the specified class.

Parameters:
clazz class to instantiate and wrap
	public BeanWrapperImpl(Class clazz) {
	}

Create new BeanWrapperImpl for the given object, registering a nested path that the object is in.

Parameters:
object object wrapped by this BeanWrapper
nestedPath the nested path of the object
rootObject the root object at the top of the path
	public BeanWrapperImpl(Object objectString nestedPathObject rootObject) {
		setWrappedInstance(objectnestedPathrootObject);
	}

Create new BeanWrapperImpl for the given object, registering a nested path that the object is in.

Parameters:
object object wrapped by this BeanWrapper
nestedPath the nested path of the object
superBw the containing BeanWrapper (must not be null)
	private BeanWrapperImpl(Object objectString nestedPathBeanWrapperImpl superBw) {
		setWrappedInstance(objectnestedPathsuperBw.getWrappedInstance());
	}
	//---------------------------------------------------------------------
	// Implementation of BeanWrapper interface
	//---------------------------------------------------------------------
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.

Parameters:
object the new target object
	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.

Parameters:
object the new target object
nestedPath the nested path of the object
rootObject the root object at the top of the path
	public void setWrappedInstance(Object objectString nestedPathObject rootObject) {
		Assert.notNull(object"Bean object must not be null");
		this. = object;
		this. = (nestedPath != null ? nestedPath : "");
		this. = (!"".equals(this.) ? rootObject : object);
		this. = null;
		this. = new TypeConverterDelegate(thisobject);
	}
	public final Object getWrappedInstance() {
		return this.;
	}
	public final Class getWrappedClass() {
		return (this. != null ? this..getClass() : null);
	}

Return the nested path of the object wrapped by this BeanWrapper.
	public final String getNestedPath() {
		return this.;
	}

Return the root object at the top of the path of this BeanWrapper.

See also:
getNestedPath()
	public final Object getRootInstance() {
		return this.;
	}

Return the class of the root object at the top of the path of this BeanWrapper.

See also:
getNestedPath()
	public final Class getRootClass() {
		return (this. != null ? this..getClass() : null);
	}

Set the class to introspect. Needs to be called when the target object changes.

Parameters:
clazz the class to introspect
	protected void setIntrospectionClass(Class clazz) {
		if (this. != null &&
		}
	}

Obtain a lazily initializted CachedIntrospectionResults instance for the wrapped object.
		Assert.state(this. != null"BeanWrapper does not hold a bean instance");
		if (this. == null) {
			this. = CachedIntrospectionResults.forClass(getWrappedClass());
		}
	}
	}
		if (pd == null) {
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"No property '" + propertyName + "' found");
		}
		return pd;
	}

Internal version of getPropertyDescriptor(java.lang.String): Returns null if not found rather than throwing an exception.

Parameters:
propertyName the property to obtain the descriptor for
Returns:
the property descriptor for the specified property, or null if not found
Throws:
BeansException in case of introspection failure
		Assert.notNull(propertyName"Property name must not be null");
		return nestedBw.getCachedIntrospectionResults().getPropertyDescriptor(getFinalPath(nestedBwpropertyName));
	}
	public Class getPropertyType(String propertyNamethrows BeansException {
		try {
			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;
				}
			}
		}
			// Consider as not determinable.
		}
		return null;
	}
	public boolean isReadableProperty(String propertyName) {
		try {
			if (pd != null) {
				if (pd.getReadMethod() != null) {
					return true;
				}
			}
			else {
				// Maybe an indexed/mapped property...
				getPropertyValue(propertyName);
				return true;
			}
		}
			// Cannot be evaluated, so can't be readable.
		}
		return false;
	}
	public boolean isWritableProperty(String propertyName) {
		try {
			if (pd != null) {
				if (pd.getWriteMethod() != null) {
					return true;
				}
			}
			else {
				// Maybe an indexed/mapped property...
				getPropertyValue(propertyName);
				return true;
			}
		}
			// Cannot be evaluated, so can't be writable.
		}
		return false;
	}

Deprecated:
in favor of convertIfNecessary
See also:
AbstractPropertyAccessor.convertIfNecessary(java.lang.Object,java.lang.Class)
	public Object doTypeConversionIfNecessary(Object valueClass requiredTypethrows TypeMismatchException {
		return convertIfNecessary(valuerequiredTypenull);
	}
			Object valueClass requiredTypeMethodParameter methodParamthrows TypeMismatchException {
		try {
			return this..convertIfNecessary(valuerequiredTypemethodParam);
		}
			throw new TypeMismatchException(valuerequiredTypeex);
		}
	}

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.

Parameters:
value the value to convert
propertyName the target property (note that nested or indexed properties are not supported here)
Returns:
the new value, possibly the result of type conversion
Throws:
TypeMismatchException if type conversion failed
	public Object convertForProperty(Object valueString propertyNamethrows TypeMismatchException {
		if (pd == null) {
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"No property '" + propertyName + "' found");
		}
		try {
			return this..convertIfNecessary(nullvaluepd);
		}
					new PropertyChangeEvent(this.this. + propertyNamenullvalue);
			throw new TypeMismatchException(pcepd.getPropertyType(), ex);
		}
	}
	//---------------------------------------------------------------------
	// Implementation methods
	//---------------------------------------------------------------------
Get the last component of the path. Also works if not nested.

Parameters:
bw BeanWrapper to work on
nestedPath property path we know is nested
Returns:
last component of the path (the property on the target bean)
	private String getFinalPath(BeanWrapper bwString nestedPath) {
		if (bw == this) {
			return nestedPath;
		}
		return nestedPath.substring(PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(nestedPath) + 1);
	}

Recursively navigate to return a BeanWrapper for the nested property path.

Parameters:
propertyPath property property path, which may be nested
Returns:
a BeanWrapper for the target bean
		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;
		}
	}

Retrieve a BeanWrapper for the given nested property. Create a new one if not found in the cache.

Note: Caching nested BeanWrappers is necessary now, to keep registered custom editors for nested properties.

Parameters:
nestedProperty property to create the BeanWrapper for
Returns:
the BeanWrapper instance, either cached or newly created
	private BeanWrapperImpl getNestedBeanWrapper(String nestedProperty) {
		if (this. == null) {
			this. = new HashMap();
		}
		// Get value of bean property.
		PropertyTokenHolder tokens = getPropertyNameTokens(nestedProperty);
		String canonicalName = tokens.canonicalName;
		Object propertyValue = getPropertyValue(tokens);
		if (propertyValue == null) {
			throw new NullValueInNestedPathException(getRootClass(), this. + canonicalName);
		}
		// Lookup cached sub-BeanWrapper, create new one if not found.
		BeanWrapperImpl nestedBw = (BeanWrapperImplthis..get(canonicalName);
		if (nestedBw == null || nestedBw.getWrappedInstance() != propertyValue) {
				.trace("Creating new nested BeanWrapper for property '" + canonicalName + "'");
			}
			nestedBw = newNestedBeanWrapper(propertyValuethis. + canonicalName + );
			// Inherit all type-specific PropertyEditors.
			copyCustomEditorsTo(nestedBwcanonicalName);
			this..put(canonicalNamenestedBw);
		}
		else {
				.trace("Using cached nested BeanWrapper for property '" + canonicalName + "'");
			}
		}
		return nestedBw;
	}

Create a new nested BeanWrapper instance.

Default implementation creates a BeanWrapperImpl instance. Can be overridden in subclasses to create a BeanWrapperImpl subclass.

Parameters:
object object wrapped by this BeanWrapper
nestedPath the nested path of the object
Returns:
the nested BeanWrapper instance
	protected BeanWrapperImpl newNestedBeanWrapper(Object objectString nestedPath) {
		return new BeanWrapperImpl(objectnestedPaththis);
	}

Parse the given property name into the corresponding property name tokens.

Parameters:
propertyName the property name to parse
Returns:
representation of the parsed property tokens
		String actualName = null;
		List keys = new ArrayList(2);
		int searchIndex = 0;
		while (searchIndex != -1) {
			int keyStart = propertyName.indexOf(searchIndex);
			searchIndex = -1;
			if (keyStart != -1) {
				int keyEnd = propertyName.indexOf(keyStart + .length());
				if (keyEnd != -1) {
					if (actualName == null) {
						actualName = propertyName.substring(0, keyStart);
					}
					String key = propertyName.substring(keyStart + .length(), keyEnd);
					if ((key.startsWith("'") && key.endsWith("'")) || (key.startsWith("\"") && key.endsWith("\""))) {
						key = key.substring(1, key.length() - 1);
					}
					keys.add(key);
					searchIndex = keyEnd + .length();
				}
			}
		}
		tokens.actualName = (actualName != null ? actualName : propertyName);
		tokens.canonicalName = tokens.actualName;
		if (!keys.isEmpty()) {
			tokens.canonicalName +=
			tokens.keys = StringUtils.toStringArray(keys);
		}
		return tokens;
	}
	//---------------------------------------------------------------------
	// Implementation of PropertyAccessor interface
	//---------------------------------------------------------------------
	public Object getPropertyValue(String propertyNamethrows BeansException {
		PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBwpropertyName));
		return nestedBw.getPropertyValue(tokens);
	}
		String propertyName = tokens.canonicalName;
		String actualName = tokens.actualName;
		if (pd == null || pd.getReadMethod() == null) {
			throw new NotReadablePropertyException(getRootClass(), this. + propertyName);
		}
		Method readMethod = pd.getReadMethod();
		try {
			if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
				readMethod.setAccessible(true);
			}
			Object value = readMethod.invoke(this., (Object[]) null);
			if (tokens.keys != null) {
				// apply indexes and map keys
				for (int i = 0; i < tokens.keys.lengthi++) {
					String key = tokens.keys[i];
					if (value == null) {
						throw new NullValueInNestedPathException(getRootClass(), this. + propertyName,
								"Cannot access indexed value of property referenced in indexed " +
								"property path '" + propertyName + "': returned null");
					}
					else if (value.getClass().isArray()) {
						value = Array.get(value, Integer.parseInt(key));
					}
					else if (value instanceof List) {
						List list = (Listvalue;
						value = list.get(Integer.parseInt(key));
					}
					else if (value instanceof Set) {
						// Apply index to Iterator in case of a Set.
						Set set = (Setvalue;
						int index = Integer.parseInt(key);
						if (index < 0 || index >= set.size()) {
							throw new InvalidPropertyException(getRootClass(), this. + propertyName,
									"Cannot get element with index " + index + " from Set of size " +
									set.size() + ", accessed using property path '" + propertyName + "'");
						}
						Iterator it = set.iterator();
						for (int j = 0; it.hasNext(); j++) {
							Object elem = it.next();
							if (j == index) {
								value = elem;
								break;
							}
						}
					}
					else if (value instanceof Map) {
						Map map = (Mapvalue;
						Class mapKeyType = null;
						if (JdkVersion.isAtLeastJava15()) {
							mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
						}
						// IMPORTANT: Do not pass full property name in here - property editors
						// must not kick in for map keys but rather only for map values.
						Object convertedMapKey = this..convertIfNecessary(keymapKeyType);
						// Pass full property name and old value in here, since we want full
						// conversion ability for map values.
						value = map.get(convertedMapKey);
					}
					else {
						throw new InvalidPropertyException(getRootClass(), this. + propertyName,
								"Property referenced in indexed property path '" + propertyName +
								"' is neither an array nor a List nor a Set nor a Map; returned value was [" + value + "]");
					}
				}
			}
			return value;
		}
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"Getter for property '" + actualName + "' threw exception"ex);
		}
		catch (IllegalAccessException ex) {
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"Illegal attempt to get property '" + actualName + "' threw exception"ex);
		}
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"Index of out of bounds in property path '" + propertyName + "'"ex);
		}
		catch (NumberFormatException ex) {
			throw new InvalidPropertyException(getRootClass(), this. + propertyName,
					"Invalid index in property path '" + propertyName + "'"ex);
		}
	}
	public void setPropertyValue(String propertyNameObject valuethrows BeansException {
		BeanWrapperImpl nestedBw = null;
		try {
			nestedBw = getBeanWrapperForPropertyPath(propertyName);
		}
			throw new NotWritablePropertyException(getRootClass(), this. + propertyName,
					"Nested property in path '" + propertyName + "' does not exist"ex);
		}
		PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBwpropertyName));
		nestedBw.setPropertyValue(tokensnew PropertyValue(propertyNamevalue));
	}
	public void setPropertyValue(PropertyValue pvthrows BeansException {
		PropertyTokenHolder tokens = (PropertyTokenHolderpv.resolvedTokens;
		if (tokens == null) {
			String propertyName = pv.getName();
			BeanWrapperImpl nestedBw = null;
			try {
				nestedBw = getBeanWrapperForPropertyPath(propertyName);
			}
				throw new NotWritablePropertyException(getRootClass(), this. + propertyName,
						"Nested property in path '" + propertyName + "' does not exist"ex);
			}
			tokens = getPropertyNameTokens(getFinalPath(nestedBwpropertyName));
			if (nestedBw == this) {
			}
			nestedBw.setPropertyValue(tokenspv);
		}
		else {
			setPropertyValue(tokenspv);
		}
	}
	private void setPropertyValue(PropertyTokenHolder tokensPropertyValue pvthrows BeansException {
		String propertyName = tokens.canonicalName;
		String actualName = tokens.actualName;
		if (tokens.keys != null) {
			// Apply indexes and map keys: fetch value for all keys but the last one.
			PropertyTokenHolder getterTokens = new PropertyTokenHolder();
			getterTokens.canonicalName = tokens.canonicalName;
			getterTokens.actualName = tokens.actualName;
			getterTokens.keys = new String[tokens.keys.length - 1];
			System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
			Object propValue = null;
			try {
				propValue = getPropertyValue(getterTokens);
			}
				throw new NotWritablePropertyException(getRootClass(), this. + propertyName,
						"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "'"ex);
			}
			// Set value for last key.
			String key = tokens.keys[tokens.keys.length - 1];
			if (propValue == null) {
				throw new NullValueInNestedPathException(getRootClass(), this. + propertyName,
						"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "': returned null");
			}
			else if (propValue.getClass().isArray()) {
				Class requiredType = propValue.getClass().getComponentType();
				int arrayIndex = Integer.parseInt(key);
				Object oldValue = null;
				try {
						oldValue = Array.get(propValuearrayIndex);
					}
							propertyNameoldValuepv.getValue(), requiredType);
					Array.set(propValue, Integer.parseInt(key), convertedValue);
				}
							new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
					throw new TypeMismatchException(pcerequiredTypeex);
				}
					throw new InvalidPropertyException(getRootClass(), this. + propertyName,
							"Invalid array index in property path '" + propertyName + "'"ex);
				}
			}
			else if (propValue instanceof List) {
				Class requiredType = null;
				if (JdkVersion.isAtLeastJava15()) {
					requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
							pd.getReadMethod(), tokens.keys.length);
				}
				List list = (ListpropValue;
				int index = Integer.parseInt(key);
				Object oldValue = null;
				if (isExtractOldValueForEditor() && index < list.size()) {
					oldValue = list.get(index);
				}
				try {
							propertyNameoldValuepv.getValue(), requiredType);
					if (index < list.size()) {
						list.set(indexconvertedValue);
					}
					else if (index >= list.size()) {
						for (int i = list.size(); i < indexi++) {
							try {
								list.add(null);
							}
							catch (NullPointerException ex) {
								throw new InvalidPropertyException(getRootClass(), this. + propertyName,
										"Cannot set element with index " + index + " in List of size " +
										list.size() + ", accessed using property path '" + propertyName +
										"': List does not support filling up gaps with null elements");
							}
						}
						list.add(convertedValue);
					}
				}
							new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
					throw new TypeMismatchException(pcerequiredTypeex);
				}
			}
			else if (propValue instanceof Map) {
				Class mapKeyType = null;
				Class mapValueType = null;
				if (JdkVersion.isAtLeastJava15()) {
					mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
							pd.getReadMethod(), tokens.keys.length);
					mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
							pd.getReadMethod(), tokens.keys.length);
				}
				Map map = (MappropValue;
				Object convertedMapKey = null;
				Object convertedMapValue = null;
				try {
					// IMPORTANT: Do not pass full property name in here - property editors
					// must not kick in for map keys but rather only for map values.
					convertedMapKey = this..convertIfNecessary(keymapKeyType);
				}
							new PropertyChangeEvent(this.this. + propertyNamenullpv.getValue());
					throw new TypeMismatchException(pcemapKeyTypeex);
				}
				Object oldValue = null;
					oldValue = map.get(convertedMapKey);
				}
				try {
					// Pass full property name and old value in here, since we want full
					// conversion ability for map values.
					convertedMapValue = this..convertIfNecessary(
							propertyNameoldValuepv.getValue(), mapValueTypenull,
							new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
				}
							new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
					throw new TypeMismatchException(pcemapValueTypeex);
				}
				map.put(convertedMapKeyconvertedMapValue);
			}
			else {
				throw new InvalidPropertyException(getRootClass(), this. + propertyName,
						"Property referenced in indexed property path '" + propertyName +
						"' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
			}
		}
		else {
			PropertyDescriptor pd = pv.resolvedDescriptor;
			if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.)) {
				if (pd == null || pd.getWriteMethod() == null) {
					PropertyMatches matches = PropertyMatches.forProperty(propertyNamegetRootClass());
							getRootClass(), this. + propertyName,
							matches.buildErrorMessage(), matches.getPossibleMatches());
				}
			}
			Object oldValue = null;
			try {
				Object originalValue = pv.getValue();
				Object valueToApply = originalValue;
				if (!..equals(pv.conversionNecessary)) {
					if (pv.isConverted()) {
						valueToApply = pv.getConvertedValue();
					}
					else {
						if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
							Method readMethod = pd.getReadMethod();
							if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
								readMethod.setAccessible(true);
							}
							try {
								oldValue = readMethod.invoke(this.new Object[0]);
							}
							catch (Exception ex) {
									.debug("Could not read previous value of property '" +
											this. + propertyName + "'"ex);
								}
							}
						}
						valueToApply = this..convertIfNecessary(oldValueoriginalValuepd);
					}
					pv.getOriginalPropertyValue(). = Boolean.valueOf(valueToApply != originalValue);
				}
				Method writeMethod = pd.getWriteMethod();
				if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
					writeMethod.setAccessible(true);
				}
				writeMethod.invoke(this.new Object[] {valueToApply});
			}
				PropertyChangeEvent propertyChangeEvent =
						new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
				if (ex.getTargetException() instanceof ClassCastException) {
					throw new TypeMismatchException(propertyChangeEventpd.getPropertyType(), ex.getTargetException());
				}
				else {
					throw new MethodInvocationException(propertyChangeEventex.getTargetException());
				}
			}
						new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
				throw new TypeMismatchException(pcepd.getPropertyType(), ex);
			}
			catch (IllegalAccessException ex) {
						new PropertyChangeEvent(this.this. + propertyNameoldValuepv.getValue());
				throw new MethodInvocationException(pceex);
			}
		}
	}
	public String toString() {
		if (this. != null) {
			sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.)).append("]");
		}
		else {
			sb.append(": no wrapped object set");
		}
		return sb.toString();
	}
	//---------------------------------------------------------------------
	// Inner class for internal use
	//---------------------------------------------------------------------
	private static class PropertyTokenHolder {
		public String[] keys;
	}
New to GrepCode? Check out our FAQ X