Sobrescrita de conversores

De vez em quando será necessário usar vários conversores para o mesmo tipo.

Nota importante: Mas isso não deveria ser uma questão de localização que pode ser realizada com conversores baseados no locale. Esses conversores podem ler o locale do usuário para converter a data conforme a região.

Existem outras situações, quando você quiser converter a data, uma para a data e outra somente para as horas ... Como nos poderemos resolver isso?

O modelo

O conversor para calendar é ativado por padrão e trata datas curtas (sem horas).

Por isso nos deveríamos ter um problema com o formato de datas somente para horas:

package org.vraptor.example.converter;

import java.util.Calendar;

/**
 * Uma classe que contém informações sobre a data de inicio e a duração.
 * 
 * @author Guilherme Silveira
 */
public class TimeInfo {

        private Calendar startDate;

        private Calendar duration;

        public Calendar getDuration() {
                return duration;
        }

        public void setDuration(Calendar duration) {
                this.duration = duration;
        }

        public Calendar getStartDate() {
                return startDate;
        }

        public void setStartDate(Calendar startDate) {
                this.startDate = startDate;
        }

}

Vamos ver a nossa lógica de negócios ... uma lógica simples que não faz nada:

package org.vraptor.example.converter;

import org.vraptor.annotations.Component;

@Component("converter")
public class ConverterOverridingLogic {

        private TimeInfo info;

        public void overriding(TimeInfo info) {
                //sua lógica de negócios
                this.info = info;
        }

        public TimeInfo getInfo() {
                return this.info;
        }

}

A solução

Então vamos sobrescrever e converter a variável duration ...

Use a anotação @Conversion, que recebe o converter como parâmetro:

        @Conversion(LocaleCalendarTimeConverter.class)
        public void setDuration(Calendar duration) {
                this.duration = duration;
        }

O formulário

Vamos criar o arquivo /converter/overriding.jsp:

<html>
Preencha o formulário abaixo e lembre-se de usar o locale inglês. (padrão web.xml)!<br/>
<form action="converter.overriding.logic">
        Data de incio: <input name="info.startDate"/> (exemplo: <b>10/31/2005</b>)<br/>
        Duração: <input name="info.duration"/> (exemplo: <b>11:05 pm</b>)<br/>
        <input type="submit"/>
</form>
</html>

O resultado e o arquivo views.properties

A página do resultado é converter/overriding.ok.jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
Conversão feita:
        
Data de início : <fmt:formatDate dateStyle="full" type="date" value="${info.startDate.time}"/><br/>
Duraçaõ: <fmt:formatDate timeStyle="full" type="time" value="${info.duration.time}"/><br/>
</html>