BeanMapper: Types-aware Property Mapper for Java (by Phil Sladen)

Introduction

A simple yet powerful way to copy/transform properties from external beans to a local bean, and vice-versa, for convenience and decoupling. Annotations can used to select particular fields to be processed. The main difference between this mapping tool and others is that Field information is required on a target property so that Generic collections are populated/transformed correctly (only class information is required on a source property). Also, array/collection/class transformations are done implicitly.

There are 4 main methods in this tool (2 inbound + 2 outbound):

Each method accepts optional extra argument 'flags' which can be set to bitwise or (|) of FLAG_IGNORE_EMPTY_STRING (empty strings treated as if null, ie. not copied) or FLAG_INCLUDE_SUPERCLASS_ANNOTS (also search super-classes for BeanMapperField annotations).

Plus 3 utility methods:

The 'propertyPath' (equivalent to the 'alias' attribute of the @BeanMapperfield annotation) describes the location of the property in the 'bean' or 'beanClass'.
Performance is excellent. The enclosed JUnit tests can be run in a loop, taking around 30ms for each iteraton, including assertion checking, on a 1.6GHz laptop (debug level WARN).

BeanMapperField annotation

Required on local 'bean' properties to select fields to be mapped by the toBean() or fromBean() methods. Optional when using toBeanField() or fromBeanField() methods. Has optional attribute 'alias'. If 'alias' is not specified then it is assumed that the equivalent property in the 'external' bean has the same name and equivalent object level as the current property. Otherwise, 'alias' can be used to specify a different name and location. Examples:

@BeanMapperField
List<Something> fieldA; // expects property to be called 'fieldA' in 'external' bean

@BeanMapperField(alias="fieldB")
List<Something> fieldA; // expects property to be called 'fieldB' in 'external' bean

@BeanMapperField(alias="subObj1.subObj2[1].fieldC")
List<Something> fieldA; // expects property to be called 'fieldC' in element 1 of array or list subObj2 of subObj1 of 'external' bean

Other optional attributes are 'oneWay' ('in' or 'out') for one way mapping, and 'aliasIn'/'aliasOut' to override 'alias' differently for input/output.
As much as I like annotations, the rest is better covered by implicit type conversion.

Implicit array/collection/class conversions

This works in 2 ways:

BeanMapperConfig.xml is also used to specify concrete types for abstract ones, eg. if BeanMapper has to create a Calendar or List you can tell it to use GregorianCalendar or ArrayList, or something else.

BeanMapperEventListener interface

A mapped bean can implement this interface to have these lifecycle methods called, to do preparation, housekeeping or manual mappings:

Debugging mapping issues

Licencing

This software is provided on the basis of the Academic Free Licence (AFL) v3.0 Please note in particular that absolutely no liability is implied. You must also retain attribution statements in the source code.

Any questions or suggestions?

Please contact me directly at phil@activewebsites.co.uk