Index: C:/Working/Workspaces/Misc/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java =================================================================== --- C:/Working/Workspaces/Misc/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java (revision 1207) +++ C:/Working/Workspaces/Misc/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java (working copy) @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; -import java.util.Iterator; +import java.util.ArrayList; /** * Pure Java ObjectFactory that instantiates objects using standard Java @@ -22,7 +26,6 @@ // private final Map serializedDataCache = Collections.synchronizedMap(new HashMap()); // - protected PropertyDictionary propertyDictionary = new PropertyDictionary(); protected static final Object[] NO_PARAMS = new Object[0]; @@ -77,43 +80,49 @@ // } public void visitSerializableProperties(Object object, Visitor visitor) { - for (Iterator iterator = propertyDictionary.serializablePropertiesFor(object.getClass()); iterator - .hasNext();) { - BeanProperty property = (BeanProperty) iterator.next(); + PropertyDescriptor[] propertyDescriptors = getSerializableProperties(object); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor property = propertyDescriptors[i]; try { - Object value = property.get(object); - visitor.visit(property.getName(), property.getType(), value); + Object value = property.getReadMethod().invoke(object, new Object[0]); + visitor.visit(property.getName(), property.getPropertyType(), value); } catch (IllegalArgumentException e) { - throw new ObjectAccessException("Could not get property " + property.getClass() + throw new ObjectAccessException("Could not get property " + object.getClass() + "." + property.getName(), e); } catch (IllegalAccessException e) { - throw new ObjectAccessException("Could not get property " + property.getClass() + throw new ObjectAccessException("Could not get property " + object.getClass() + "." + property.getName(), e); - } + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not get property " + object.getClass() + + "." + property.getName(), e); + } } } public void writeProperty(Object object, String propertyName, Object value) { - BeanProperty property = propertyDictionary.property(object.getClass(), propertyName); + PropertyDescriptor property = getProperty(propertyName, object.getClass()); try { - property.set(object, value); + property.getWriteMethod().invoke(object, new Object[] {value}); } catch (IllegalArgumentException e) { throw new ObjectAccessException("Could not set property " + object.getClass() + "." + property.getName(), e); } catch (IllegalAccessException e) { throw new ObjectAccessException("Could not set property " + object.getClass() + "." + property.getName(), e); - } + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not set property " + object.getClass() + "." + + property.getName(), e); + } } public Class getPropertyType(Object object, String name) { - return propertyDictionary.property(object.getClass(), name).getType(); + return getProperty(name, object.getClass()).getPropertyType(); } public boolean propertyDefinedInClass(String name, Class type) { - return propertyDictionary.property(type, name) != null; + return getProperty(name, type) != null; } - + /** * Returns true if the Bean provider can instantiate the specified class */ @@ -135,6 +144,48 @@ return null; } + private PropertyDescriptor[] getSerializableProperties(Object object) { + BeanInfo beanInfo = getBeanInfo(object.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + ArrayList result = new ArrayList(propertyDescriptors.length); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) { + result.add(descriptor); + } + } + return (PropertyDescriptor[])result.toArray(new PropertyDescriptor[result.size()]); + } + + private BeanInfo getBeanInfo(Class type) { + BeanInfo beanInfo; + try { + beanInfo = Introspector.getBeanInfo(type, Object.class); + } catch (IntrospectionException e) { + throw new ObjectAccessException("", e); + } + return beanInfo; + } + + public boolean propertyWriteable(String name, Class type) { + PropertyDescriptor property = getProperty(name, type); + return property.getWriteMethod() != null; + } + + private PropertyDescriptor getProperty(String name, Class type) { + BeanInfo bi = getBeanInfo(type); + PropertyDescriptor[] propertyDescriptors = bi.getPropertyDescriptors(); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + if (descriptor.getName().equals(name)) { + return descriptor; + } + } + return null; + + } + + interface Visitor { void visit(String name, Class type, Object value); }