Seu pr�prio conversor

Como voc� j� sabe, VRaptor inclue alguns conversores b�sicos. Eles servem para as tarefas mais comuns, como convers�o para String, Double ou Calendar.

Mas existem outros casos quando voc� quiser preencher o seu modelo com um objeto, para qual n�o existe um conversor ainda. Para essa tarefa voc� deve escrever o seu pr�pio conversor.

Por exemplo, imagina se voc� quer instantiar um objeto categoria com uma sub categoria e VRaptor tem que preenche-la automaticamente quando a requisi��o foi enviada.

Ent�o o seu modelo poderia ser:

public class Category {
        
        private Integer id;
        private String name;
        private Category subCategory;   
        //getters e setters
}

Na sua camada de apresenta��o usa um simples formul�rio com uma caixa de sele��o para o id da sub categoria.

Como VRaptor sabe como criar o objeto subCategory? Ele n�o faz idea e joga uma ConversionException. Se voc� quiser VRaptor para instantiar a subCategory, voc� deveria providenciar o seu pr�pio conversor.

Como criar o seu pr�prio conversor

Existem 3 passos para escrever o seu conversor:

Primeiro, criar uma classe que implementa org.vraptor.converter.Converter:

public class CategoryConverter implements Converter {
}

Agora, adiciona o m�todo public Class<?>[] getSupportedTypes(); � classe. Esse m�todo retorna um array de tipos que o conversor conhece e sabe tratar:

public class CategoryConverter implements Converter {

        public Class<?>[] getSupportedTypes() {
                return new Class[] { Category.class };
        }

}

E por �ltimo, voc� deve escrever o m�todo de convers�o:

        /**
         * Converts a value to an specific type
         * 
         * @param value
         *            current value
         * @param type
         *            desired type
         * @return the converted value
         * @throws ConversionException
         *             some convertion problem hapenned
         */
        public Object convert(String value, Class<?> type, LogicRequest request)
                        throws ConversionException;

Se acontecesse uma exce��o (ConversionException) durante a convers�o, ela ser� jogada e dada para cont�iner de servlet.

Se voc� n�o quiser criar nenhuma exce��o, simplesmente retorne um valor padr�o, nulo ou similar.

Por exemplo:

public Object convert(String categoryId, Class<?> type, LogicRequest request)
                throws ConversionException {
                
                Category category = new Category();
                try {
                        category.setId(Integer.parseInt(categoryId));                   
                } catch (NumberFormatException e) {
                        category = null;
                }
                return category;
}

Como instalar o conversor

Se voc� quiser registrar um conversor que n�o foi instalado por padr�o, use o arquivo vraptor.xml.

Depois ele estar� dispon�vel para o sistema inteiro (veja tamb�m o outro tutorial como sobrescrever os conversores b�sicos):

<vraptor>

        <converter>org.vraptor.examples.converter.CategoryConverter </converter>
        
</vraptor>

Se um tipo pode ser convertido por dois conversores diferentes, utiliza-se o �ltimo registrado.

Inst�ncia do conversor

Quando o conversor � registrado, o Vraptor cria uma inst�ncia espec�fica. Nenhuma outra jamais ser� criada. Por isso � importante que voc� nunca deixe vari�veis para ler ou escrever no conversor.

Isso tamb�m significa que uma �nica inst�ncia do seu conversor deve ser seguro para threads: dois threads podem e chamar�o o m�todo do seu conversor ao mesmo tempo.

Nota: A anota��o @Conversion descreve conversores que ser�o criados quando necess�rios. Esses conversores podem ficar no cache nas vers�es no futuro .... a regra b�sica �: Jamais deixe vari�veis para leitura ou escrita nas suas classes de conversor.