views:

400

answers:

2

I'm developing functionality that can operate on concrete data beans returned via Hibernate, or DynaBeans returned by using Jakarta Commons/BeanUtils' RowSetDynaClass (which wraps a JDBC result set). RowSetDynaClass by default forces all bean property names to lower case, and I need to convert all my concrete beans from Hibernate to DynaBeans using WrapDynaBean. The default lower casing by RowSetDynaClass seems like a good idea, however I may not know ahead of time how the property names of the concrete beans will be cased; due to Hibernate configuration, they need not be cased identically to their corresponding table column names.

Is there built in functionality for forcing property names to lower case using BeanUtils? I can't find it documented other than for RowSetDynaClass. In lieu of something built in to BeanUtils, can anybody suggest the best way to acheive this myself?

+1  A: 

I'm not aware of an easy way of doing that. Potentialy you can make your own implemenation of Resolver interface.

But otherwise I would suggest using some other converting framework like Smooks (http://www.smooks.org/) or Dozer (http://dozer.sourceforge.net).

Dozer have an ability to specify wildcard matches for properties. Smooks is more transformation oriented, so, you will have to explicitly specify all field mappings.

Though, both of them have IDE plugins, that may help generating mappnigs easier and in more controlled way.

Superfilin
Was aware of Dozer but not Smooks but I don't have the authority to introduce new libraries, both my superiors are gone for the holiday, and they want it yesterday ;) I will post an answer/solution I've devised without straying from BeanUtils.
George Jempty
Just a suggestion: you could probably publish your solution as an answer to the question, but not as an edit to the question :)
Superfilin
Well I've usually published my solutions to my own questions as answers before but I'm conflicted because then it might seem like I'm just "bumping" my question up. So I did it as an edit this time.
George Jempty
But you don't get points for either editing your question or posting an answer. So, I don't think you it looks like you're "bumping" something, especialy if your question/answer get votes/comments from others. But anyway it's upto you :)
Superfilin
good points
George Jempty
+1  A: 

Here's a quick/dirty method I've devised in the meantime for converting the DynaBeans to a Map where the (String) keys are coerced to lower case:

private Map asLowerCaseIndexedMap(DynaBean bean) {
    Map lowerCaseIndexedMap = new HashMap();
    DynaProperty[] dynaProperties = bean.getDynaClass().getDynaProperties();

    for (int i=0, n=dynaProperties.length; i<n; i++) {
        String propertyName = dynaProperties[i].getName();
        lowerCaseIndexedMap.put(propertyName.toLowerCase(), bean.get(propertyName));
    }

    return lowerCaseIndexedMap;
}

Unfortunately this has forced me to jump through other hoops. Whereas I had been dealing with the beans thusly:

public void header(List<DynaBean> headerColumns) throws WriteException {
    for (DynaBean column : headerColumns) {
        int col = (Integer)column.get("columnNumber");
        int width = (Integer)column.get("columnWidth");

    //etcetera

Now I have to do so in this manner:

public void header(List<DynaBean> headerColumns) throws WriteException {
    for (DynaBean column : headerColumns) {
        /*
         * RowSetDynaClass returns beans with lower case properties by default
         * but this is not guaranteed if beans are coming from Hibernate.
         * 
         * Converting from the bean to a map however loses DynaBeans' inherent
         * type conversions, which in turn entails the converting back and forth
         * from String, to BigDecimal, to int as seen below
         */
        Map columnMap = asLowerCaseIndexedMap(column);

        int col = (new BigDecimal(columnMap.get("columnnbr").toString())).intValue();
        int width = (new BigDecimal(columnMap.get("columnwdth").toString())).intValue();
George Jempty