From fa43060230d50ff802a9052b6220e4080d63085b Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 Mar 2002 04:15:49 +0000 Subject: [PATCH] Removed ^M's from file because they were causing line numbers to be reported incorrectly when trying to track down failing test cases. git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/collections/trunk@130637 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/commons/collections/BeanMap.java | 972 +++++++++--------- 1 file changed, 486 insertions(+), 486 deletions(-) diff --git a/src/java/org/apache/commons/collections/BeanMap.java b/src/java/org/apache/commons/collections/BeanMap.java index 334fe7f02..3db62b781 100644 --- a/src/java/org/apache/commons/collections/BeanMap.java +++ b/src/java/org/apache/commons/collections/BeanMap.java @@ -1,486 +1,486 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/BeanMap.java,v 1.4 2002/02/22 07:00:30 mas Exp $ - * $Revision: 1.4 $ - * $Date: 2002/02/22 07:00:30 $ - * - * ==================================================================== - * - * The Apache Software License, Version 1.1 - * - * Copyright (c) 1999-2002 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "The Jakarta Project", "Commons", and "Apache Software - * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.apache.commons.collections; - -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - - -/** An implementation of Map for JavaBeans which uses introspection to - * get and put properties in the bean. - * - * If an exception occurs during attempts to get or set a property then the - * property is considered non existent in the Map - * - * @author James Strachan - */ - -public class BeanMap extends AbstractMap { - - private Object bean; - - private HashMap readMethods = new HashMap(); - private HashMap writeMethods = new HashMap(); - private HashMap types = new HashMap(); - - public static final Object[] NULL_ARGUMENTS = {}; - public static HashMap defaultTransformers = new HashMap(); - - static { - defaultTransformers.put( - Boolean.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Boolean.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Character.TYPE, - new Transformer() { - public Object transform( Object input ) { - return new Character( input.toString().charAt( 0 ) ); - } - } - ); - defaultTransformers.put( - Byte.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Byte.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Short.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Short.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Integer.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Integer.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Long.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Long.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Float.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Float.valueOf( input.toString() ); - } - } - ); - defaultTransformers.put( - Double.TYPE, - new Transformer() { - public Object transform( Object input ) { - return Double.valueOf( input.toString() ); - } - } - ); - } - - - // Constructors - //------------------------------------------------------------------------- - public BeanMap() { - } - - public BeanMap(Object bean) { - this.bean = bean; - initialise(); - } - - // Map interface - //------------------------------------------------------------------------- - - public Object clone() { - Class beanClass = null; - try { - beanClass = bean.getClass(); - Object newBean = beanClass.newInstance(); - Map newMap = new BeanMap( newBean ); - newMap.putAll( this ); - return newMap; - } - catch (Exception e) { - throw new UnsupportedOperationException( "Could not create new instance of class: " + beanClass ); - } - } - - /** - * This method reinitializes the bean map to have default values for the - * bean's properties. This is accomplished by constructing a new instance - * of the bean which th emap uses as its underlying data source. This - * behavior for clear() differs from the Map contract in that - * the mappings are not actually removed from the map (the mappings for a - * BeanMap are fixed). - **/ - public void clear() { - Class beanClass = null; - try { - beanClass = bean.getClass(); - bean = beanClass.newInstance(); - } - catch (Exception e) { - throw new UnsupportedOperationException( "Could not create new instance of class: " + beanClass ); - } - } - - public boolean containsKey(Object name) { - Method method = getReadMethod( name ); - return method != null; - } - - public boolean containsValue(Object value) { - // use default implementation - return super.containsValue( value ); - } - - public Object get(Object name) { - if ( bean != null ) { - Method method = getReadMethod( name ); - if ( method != null ) { - try { - return method.invoke( bean, NULL_ARGUMENTS ); - } - catch ( IllegalAccessException e ) { - logWarn( e ); - } - catch ( IllegalArgumentException e ) { - logWarn( e ); - } - catch ( InvocationTargetException e ) { - logWarn( e ); - } - catch ( NullPointerException e ) { - logWarn( e ); - } - } - } - return null; - } - - public Object put(Object name, Object value) throws IllegalArgumentException, ClassCastException { - if ( bean != null ) { - Object oldValue = get( name ); - Method method = getWriteMethod( name ); - if ( method == null ) { - throw new IllegalArgumentException( "The bean of type: "+ bean.getClass().getName() + " has no property called: " + name ); - } - try { - Object[] arguments = createWriteMethodArguments( method, value ); - method.invoke( bean, arguments ); - - Object newValue = get( name ); - firePropertyChange( name, oldValue, newValue ); - } - catch ( InvocationTargetException e ) { - logInfo( e ); - throw new IllegalArgumentException( e.getMessage() ); - } - catch ( IllegalAccessException e ) { - logInfo( e ); - throw new IllegalArgumentException( e.getMessage() ); - } - return oldValue; - } - return null; - } - - public int size() { - return readMethods.size(); - } - - - public Set keySet() { - return readMethods.keySet(); - } - - public Set entrySet() { - return readMethods.keySet(); - } - - public Collection values() { - ArrayList answer = new ArrayList( readMethods.size() ); - for ( Iterator iter = valueIterator(); iter.hasNext(); ) { - answer.add( iter.next() ); - } - return answer; - } - - - // Helper methods - //------------------------------------------------------------------------- - - public Class getType(String name) { - return (Class) types.get( name ); - } - - public Iterator keyIterator() { - return readMethods.keySet().iterator(); - } - - public Iterator valueIterator() { - final Iterator iter = keyIterator(); - return new Iterator() { - public boolean hasNext() { - return iter.hasNext(); - } - public Object next() { - Object key = iter.next(); - return get( (String) key ); - } - public void remove() { - throw new UnsupportedOperationException( "remove() not supported for BeanMap" ); - } - }; - } - - public Iterator entryIterator() { - final Iterator iter = keyIterator(); - return new Iterator() { - public boolean hasNext() { - return iter.hasNext(); - } - public Object next() { - Object key = iter.next(); - Object value = get( (String) key ); - return new MyMapEntry( BeanMap.this, key, value ); - } - public void remove() { - throw new UnsupportedOperationException( "remove() not supported for BeanMap" ); - } - }; - } - - - // Properties - //------------------------------------------------------------------------- - public Object getBean() { - return bean; - } - - public void setBean( Object newBean ) { - bean = newBean; - reinitialise(); - } - - - // Implementation methods - //------------------------------------------------------------------------- - - protected Method getReadMethod( Object name ) { - return (Method) readMethods.get( name ); - } - - protected Method getWriteMethod( Object name ) { - return (Method) writeMethods.get( name ); - } - - protected void reinitialise() { - readMethods.clear(); - writeMethods.clear(); - types.clear(); - initialise(); - } - - private void initialise() { - Class beanClass = getBean().getClass(); - try { - //BeanInfo beanInfo = Introspector.getBeanInfo( bean, null ); - BeanInfo beanInfo = Introspector.getBeanInfo( beanClass ); - PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); - if ( propertyDescriptors != null ) { - for ( int i = 0; i < propertyDescriptors.length; i++ ) { - PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; - if ( propertyDescriptor != null ) { - String name = propertyDescriptor.getName(); - Method readMethod = propertyDescriptor.getReadMethod(); - Method writeMethod = propertyDescriptor.getWriteMethod(); - Class aType = propertyDescriptor.getPropertyType(); - - if ( readMethod != null ) { - readMethods.put( name, readMethod ); - } - if ( writeMethods != null ) { - writeMethods.put( name, writeMethod ); - } - types.put( name, aType ); - } - } - } - } - catch ( IntrospectionException e ) { - logWarn( e ); - } - } - - protected void firePropertyChange( Object key, Object oldValue, Object newValue ) { - } - - // Implementation classes - //------------------------------------------------------------------------- - protected static class MyMapEntry extends DefaultMapEntry { - private BeanMap owner; - - protected MyMapEntry( BeanMap owner, Object key, Object value ) { - super( key, value ); - this.owner = owner; - } - - public Object setValue(Object value) { - Object key = getKey(); - Object oldValue = owner.get( key ); - - owner.put( key, value ); - Object newValue = owner.get( key ); - super.setValue( newValue ); - return oldValue; - } - } - - protected Object[] createWriteMethodArguments( Method method, Object value ) throws IllegalAccessException, ClassCastException { - try { - if ( value != null ) { - Class[] types = method.getParameterTypes(); - if ( types != null && types.length > 0 ) { - Class paramType = types[0]; - if ( ! paramType.isAssignableFrom( value.getClass() ) ) { - value = convertType( paramType, value ); - } - } - } - Object[] answer = { value }; - return answer; - } - catch ( InvocationTargetException e ) { - logInfo( e ); - throw new IllegalArgumentException( e.getMessage() ); - } - catch ( InstantiationException e ) { - logInfo( e ); - throw new IllegalArgumentException( e.getMessage() ); - } - } - - protected Object convertType( Class newType, Object value ) - throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - - // try call constructor - Class[] types = { value.getClass() }; - try { - Constructor constructor = newType.getConstructor( types ); - Object[] arguments = { value }; - return constructor.newInstance( arguments ); - } - catch ( NoSuchMethodException e ) { - // try using the transformers - Transformer transformer = getTypeTransformer( newType ); - if ( transformer != null ) { - return transformer.transform( value ); - } - return value; - } - } - - protected Transformer getTypeTransformer( Class aType ) { - return (Transformer) defaultTransformers.get( aType ); - } - - protected void logInfo(Exception e) { - // XXXX: should probably use log4j here instead... - System.out.println( "INFO: Exception: " + e ); - } - - protected void logWarn(Exception e) { - // XXXX: should probably use log4j here instead... - System.out.println( "WARN: Exception: " + e ); - e.printStackTrace(); - } -} - - +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/BeanMap.java,v 1.5 2002/03/13 04:15:49 mas Exp $ + * $Revision: 1.5 $ + * $Date: 2002/03/13 04:15:49 $ + * + * ==================================================================== + * + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.commons.collections; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + + +/** An implementation of Map for JavaBeans which uses introspection to + * get and put properties in the bean. + * + * If an exception occurs during attempts to get or set a property then the + * property is considered non existent in the Map + * + * @author James Strachan + */ + +public class BeanMap extends AbstractMap { + + private Object bean; + + private HashMap readMethods = new HashMap(); + private HashMap writeMethods = new HashMap(); + private HashMap types = new HashMap(); + + public static final Object[] NULL_ARGUMENTS = {}; + public static HashMap defaultTransformers = new HashMap(); + + static { + defaultTransformers.put( + Boolean.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Boolean.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Character.TYPE, + new Transformer() { + public Object transform( Object input ) { + return new Character( input.toString().charAt( 0 ) ); + } + } + ); + defaultTransformers.put( + Byte.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Byte.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Short.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Short.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Integer.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Integer.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Long.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Long.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Float.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Float.valueOf( input.toString() ); + } + } + ); + defaultTransformers.put( + Double.TYPE, + new Transformer() { + public Object transform( Object input ) { + return Double.valueOf( input.toString() ); + } + } + ); + } + + + // Constructors + //------------------------------------------------------------------------- + public BeanMap() { + } + + public BeanMap(Object bean) { + this.bean = bean; + initialise(); + } + + // Map interface + //------------------------------------------------------------------------- + + public Object clone() { + Class beanClass = null; + try { + beanClass = bean.getClass(); + Object newBean = beanClass.newInstance(); + Map newMap = new BeanMap( newBean ); + newMap.putAll( this ); + return newMap; + } + catch (Exception e) { + throw new UnsupportedOperationException( "Could not create new instance of class: " + beanClass ); + } + } + + /** + * This method reinitializes the bean map to have default values for the + * bean's properties. This is accomplished by constructing a new instance + * of the bean which th emap uses as its underlying data source. This + * behavior for clear() differs from the Map contract in that + * the mappings are not actually removed from the map (the mappings for a + * BeanMap are fixed). + **/ + public void clear() { + Class beanClass = null; + try { + beanClass = bean.getClass(); + bean = beanClass.newInstance(); + } + catch (Exception e) { + throw new UnsupportedOperationException( "Could not create new instance of class: " + beanClass ); + } + } + + public boolean containsKey(Object name) { + Method method = getReadMethod( name ); + return method != null; + } + + public boolean containsValue(Object value) { + // use default implementation + return super.containsValue( value ); + } + + public Object get(Object name) { + if ( bean != null ) { + Method method = getReadMethod( name ); + if ( method != null ) { + try { + return method.invoke( bean, NULL_ARGUMENTS ); + } + catch ( IllegalAccessException e ) { + logWarn( e ); + } + catch ( IllegalArgumentException e ) { + logWarn( e ); + } + catch ( InvocationTargetException e ) { + logWarn( e ); + } + catch ( NullPointerException e ) { + logWarn( e ); + } + } + } + return null; + } + + public Object put(Object name, Object value) throws IllegalArgumentException, ClassCastException { + if ( bean != null ) { + Object oldValue = get( name ); + Method method = getWriteMethod( name ); + if ( method == null ) { + throw new IllegalArgumentException( "The bean of type: "+ bean.getClass().getName() + " has no property called: " + name ); + } + try { + Object[] arguments = createWriteMethodArguments( method, value ); + method.invoke( bean, arguments ); + + Object newValue = get( name ); + firePropertyChange( name, oldValue, newValue ); + } + catch ( InvocationTargetException e ) { + logInfo( e ); + throw new IllegalArgumentException( e.getMessage() ); + } + catch ( IllegalAccessException e ) { + logInfo( e ); + throw new IllegalArgumentException( e.getMessage() ); + } + return oldValue; + } + return null; + } + + public int size() { + return readMethods.size(); + } + + + public Set keySet() { + return readMethods.keySet(); + } + + public Set entrySet() { + return readMethods.keySet(); + } + + public Collection values() { + ArrayList answer = new ArrayList( readMethods.size() ); + for ( Iterator iter = valueIterator(); iter.hasNext(); ) { + answer.add( iter.next() ); + } + return answer; + } + + + // Helper methods + //------------------------------------------------------------------------- + + public Class getType(String name) { + return (Class) types.get( name ); + } + + public Iterator keyIterator() { + return readMethods.keySet().iterator(); + } + + public Iterator valueIterator() { + final Iterator iter = keyIterator(); + return new Iterator() { + public boolean hasNext() { + return iter.hasNext(); + } + public Object next() { + Object key = iter.next(); + return get( (String) key ); + } + public void remove() { + throw new UnsupportedOperationException( "remove() not supported for BeanMap" ); + } + }; + } + + public Iterator entryIterator() { + final Iterator iter = keyIterator(); + return new Iterator() { + public boolean hasNext() { + return iter.hasNext(); + } + public Object next() { + Object key = iter.next(); + Object value = get( (String) key ); + return new MyMapEntry( BeanMap.this, key, value ); + } + public void remove() { + throw new UnsupportedOperationException( "remove() not supported for BeanMap" ); + } + }; + } + + + // Properties + //------------------------------------------------------------------------- + public Object getBean() { + return bean; + } + + public void setBean( Object newBean ) { + bean = newBean; + reinitialise(); + } + + + // Implementation methods + //------------------------------------------------------------------------- + + protected Method getReadMethod( Object name ) { + return (Method) readMethods.get( name ); + } + + protected Method getWriteMethod( Object name ) { + return (Method) writeMethods.get( name ); + } + + protected void reinitialise() { + readMethods.clear(); + writeMethods.clear(); + types.clear(); + initialise(); + } + + private void initialise() { + Class beanClass = getBean().getClass(); + try { + //BeanInfo beanInfo = Introspector.getBeanInfo( bean, null ); + BeanInfo beanInfo = Introspector.getBeanInfo( beanClass ); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + if ( propertyDescriptors != null ) { + for ( int i = 0; i < propertyDescriptors.length; i++ ) { + PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; + if ( propertyDescriptor != null ) { + String name = propertyDescriptor.getName(); + Method readMethod = propertyDescriptor.getReadMethod(); + Method writeMethod = propertyDescriptor.getWriteMethod(); + Class aType = propertyDescriptor.getPropertyType(); + + if ( readMethod != null ) { + readMethods.put( name, readMethod ); + } + if ( writeMethods != null ) { + writeMethods.put( name, writeMethod ); + } + types.put( name, aType ); + } + } + } + } + catch ( IntrospectionException e ) { + logWarn( e ); + } + } + + protected void firePropertyChange( Object key, Object oldValue, Object newValue ) { + } + + // Implementation classes + //------------------------------------------------------------------------- + protected static class MyMapEntry extends DefaultMapEntry { + private BeanMap owner; + + protected MyMapEntry( BeanMap owner, Object key, Object value ) { + super( key, value ); + this.owner = owner; + } + + public Object setValue(Object value) { + Object key = getKey(); + Object oldValue = owner.get( key ); + + owner.put( key, value ); + Object newValue = owner.get( key ); + super.setValue( newValue ); + return oldValue; + } + } + + protected Object[] createWriteMethodArguments( Method method, Object value ) throws IllegalAccessException, ClassCastException { + try { + if ( value != null ) { + Class[] types = method.getParameterTypes(); + if ( types != null && types.length > 0 ) { + Class paramType = types[0]; + if ( ! paramType.isAssignableFrom( value.getClass() ) ) { + value = convertType( paramType, value ); + } + } + } + Object[] answer = { value }; + return answer; + } + catch ( InvocationTargetException e ) { + logInfo( e ); + throw new IllegalArgumentException( e.getMessage() ); + } + catch ( InstantiationException e ) { + logInfo( e ); + throw new IllegalArgumentException( e.getMessage() ); + } + } + + protected Object convertType( Class newType, Object value ) + throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + + // try call constructor + Class[] types = { value.getClass() }; + try { + Constructor constructor = newType.getConstructor( types ); + Object[] arguments = { value }; + return constructor.newInstance( arguments ); + } + catch ( NoSuchMethodException e ) { + // try using the transformers + Transformer transformer = getTypeTransformer( newType ); + if ( transformer != null ) { + return transformer.transform( value ); + } + return value; + } + } + + protected Transformer getTypeTransformer( Class aType ) { + return (Transformer) defaultTransformers.get( aType ); + } + + protected void logInfo(Exception e) { + // XXXX: should probably use log4j here instead... + System.out.println( "INFO: Exception: " + e ); + } + + protected void logWarn(Exception e) { + // XXXX: should probably use log4j here instead... + System.out.println( "WARN: Exception: " + e ); + e.printStackTrace(); + } +} + +