brite, a MVC Framework for jQuery

Java: BeanUtils Enum Support - generic Enum converter

July 6th, 2009 by jeremychone

By default, apache commons BeanUtils does not support string value to their targeted Enum. You can write a converter for each enum, but this quickly become unmanageable.

Here is a quick fix to automatically convert the string value to the targeted enum.

BeanUtilsBean beanUtilsBean = new BeanUtilsBean(new ConvertUtilsBean(){
            @Override
            public Object convert(String value, Class clazz) {
                  if (clazz.isEnum()){
                       return Enum.valueOf(clazz, value);
                  }else{
                       return super.convert(value, clazz);
                  }
           }
        });

Now, you can call beanUtilsBean.populate(bean,map) even for enum values.

4 Responses to “Java: BeanUtils Enum Support - generic Enum converter”

  1. greg Says:

    Thanks for this ! So far, I was using the static BeanUtils.convert() method, and all I could do was ConvertUtil.register(…, String.class) - overriding the default String converter with a custom converter that would essentially do the same as above if the target was an enum. I hated the all-static nature of this (if I register the converter at some point during the lifetime of my application, the behaviour basically changes globally and randomly) and the ugliness of it (replacing the default String2String converter!?)

    An intermediate approach might be to use the non-static methods like here, the default ConvertUtilsBean implementation, but register the default String converter on a “controlled” instance of it.

  2. greg Says:

    While writing the above, I came up with a possibly slightly more elegant and performant version. It should avoid checking for class.isEnum for each and every conversion.

    class EnumAwareConvertUtilsBean extends ConvertUtilsBean {
        private final EnumConverter enumConverter = new EnumConverter();
    
        public Converter lookup(Class clazz) {
            final Converter converter = super.lookup(clazz);
            // no specific converter for this class, so it's neither a String, (which has a default converter),
            // nor any known object that has a custom converter for it. It might be an enum !
            if (converter == null && clazz.isEnum()) {
                return enumConverter;
            } else {
                return converter;
            }
        }
    
        private class EnumConverter implements Converter {
            public Object convert(Class type, Object value) {
                return Enum.valueOf(type, (String) value);
            }
        }
    }
    
  3. jeremychone Says:

    @greg, tx for your comments. I like your proposal. (I also fixed your layout).

  4. steff Says:

    Another way is to overrider register and lookup methods:

    @Override
    public void register(Converter converter, Class aClass) {
    if (aClass.equals(Enum.class)){
    enumConverter = converter;
    }
    super.register(converter, aClass);

    }

    @Override
    public Converter lookup(Class aClass) {

    if (aClass.isEnum() && enumConverter != null){
    return enumConverter;
    }
    return super.lookup(aClass);
    }

    In that scenario you are free to implement and regiseter more complex converters.

Leave a Reply