Sunday, January 15, 2012

Spring Custom Property Editor - Convert String to Calendar

Continuing on a previous entry:

The previous blog entry was about a custom property editor to convert a string representation of a date to a java.util.Date field. The approach here is a little different, to convert a string representation to a "java.util.Calendar" type, which is a little more complicated.

Say if I have a bean defined this way:

<bean name="project1" class="org.bk.simplygtd.domain.GtdProject" p:name="project1" p:startDate="2010-01-01T12:00:00.000-0800" p:completedDate="2010-01-04T12:08:56.235-0800" p:isDone="true" />


and the class has startDate and completedDate of type java.util.Calendar type.

If no custom property editors are registered this error will be returned when trying to start up the container:

Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'completedDate': no matching editors or conversion strategy found

This is perfectly reasonable as the container does not know how to transform the Calendar string to Calendar type.

The approach that has best worked for me is to actually write a custom property editor and register it with the container.

This is how my property editor looks:

import java.beans.PropertyEditorSupport;
import java.util.Calendar;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.springframework.util.StringUtils;

public class CustomCalendarEditor extends PropertyEditorSupport {
    private final DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime();

    @Override
    public String getAsText() {
        Calendar value = (Calendar) getValue();
        DateTime dateTime = new DateTime(value);
        return (value != null ? dateTime.toString(this.dateTimeFormatter) : "");
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (!StringUtils.hasText(text)) {
            setValue(null);
        } else {
            DateTime dateTime = this.dateTimeFormatter.parseDateTime(text);
            setValue(dateTime.toGregorianCalendar());
        }
    }
}

Note that I have used joda time as bridge between the string representation and java.util.Calendar and have assumed a ISO-8601 format for date.

Now, to register this property editor:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="java.util.Calendar">
                    <bean class="org.bk.simplygtd.spring.CustomCalendarEditor"/>
                </entry>
            </map>
        </property>
    </bean>

That's it, now the conversion between string to Calendar and back should work.

1 comment:

  1. The approach here is a little different, to convert a string representation to a "java.util.Calendar" type, which is a little more complicated.phoenix property management

    ReplyDelete