3.17. Wrapping a Bean with a Map

Problem

You need to expose a bean’s properties as a Map, and operate on the bean properties as if they were entries in a Map.

Solution

Wrap any bean in a BeanMap . This Map implementation uses introspection to provide access to bean properties as if they were key/value pairs in a map. This code wraps a Person bean with BeanMap, iterating through every key and accessing bean properties with get( ):

import java.util.*;
import org.apache.commons.collections.BeanMap;

Person person = new Person( );
person.setName( "Jim" );
person.setAge( new Integer( 28 ) );
person.setOccupation( "Developer" );

Map beanMap = new BeanMap( person );

Set keys = beanMap.keySet( );
Iterator keyIterator = keys.iterator( );
while( keyIterator.hasNext( ) ) {
   String propertyName = (String) keyIterator.next( );

   System.out.println( "Property: " + propertyName +
                       ", Value: " + beanMap.get( propertyName ) +
                       ", Type: " + beanMap.getType( propertyName ).
                       toString( ) );
}

The Person bean has the following properties: age, name, and occupation; an instance of this bean is created and passed to the constructor of BeanMap. The following output is created by iterating over the key set of beanMap:

Property: Age, Value: 28, Type: java.lang.String
Property: Name, Value: Jim, Type: java.lang.Integer
Property: Occupation, Value: Developer, Type: java.lang.String

Discussion

The previous example demonstrates the use of PropertyUtils.describe( ) to create a Map containing bean properties. BeanMap not only exposes bean properties with a Map interface, it wraps a bean instance, allowing you to alter the contents of the underlying bean via put(). In addition to implementing the Map interface, BeanMap provides a number of additional methods for obtaining Method objects and the types of bean properties. Table 3-1 describes a few of these methods.

Table 3-1. Methods provided by BeanMap

Method

Description

clear( )

Constructs a new instance of a bean using the no-argument constructor of the class that corresponds to getBean( ).getClass()

clone( )

If possible, creates another instance of BeanMap, wrapping a copy of the wrapped bean

getBean( )

Returns the bean wrapped by this BeanMap

setBean(Object bean)

Causes an instance of BeanMap to wrap the supplied bean

getType(String name)

Retrieves the type of the specified bean property

getReadMethod(String name)

Retrieves a Method object for the read method (or getter) of the specified property

getWriteMethod(String name)

Retrieves a Method object for the write method (or setter) of the specified property

Example 3-6 demonstrates the use of the methods listed above to manipulate and alter properties of a Person bean. Remember, when you alter a BeanMap, you are modifying the underlying bean.

Example 3-6. BeanMap methods getBean( ), setBean( ), getType( ), getReadMethod( ), and getWriteMethod( )

package com.discursive.jccook.collections;

import java.lang.reflect.Method;

import org.apache.commons.collections.BeanMap;

public class BeanMapExample {
    public static void main(String[] args) throws Exception {
        BeanMapExample example = new BeanMapExample( );
        example.start( );
    }

    public void start( ) throws Exception {

        // Create a Person bean
        Person person = new Person( );
        person.setName( "Todd" );
        person.setAge( new Integer( 45 ) );
        person.setOccupation( "Record Collector" );

        // Wrap person with a Map 
        BeanMap map = new BeanMap( person );

        // Set the age to 24 using a Method from this map
                          Method method = map.getWriteMethod( "age" );
                          method.invoke( person, new Integer(24) );        

                          // Set the name to "John" using map.put
                          map.put( "name", "John" );

        // Create a Person bean
        Person person2 = new Person( );
        person2.setName( "Cindy" );
        person2.setAge( new Integer( 39 ) );
        person2.setOccupation( "Transcriptionist" );

        // Make the BeanMap operate on another bean
                          map.setBean( person2 );

                          // Get the type of the Age property
                          Class type = map.getType( "age" );
    }
}

See Also

BeanMap provides a convenient shortcut for accessing and manipulating beans, providing the same abilities that are provided by PropertyUtils. For more information about accessing and manipulating bean properties with PropertyUtils, see Recipe 3.8 and Recipe 3.13.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.173.238