Cómo hacer data-bindings con Enums en Spring Webflow

30 01 2010

Hace poco trabajando con Spring Webflow me vi en la necesidad de tener que llevar a cabo un data-binding contra un objeto del dominio de tipo Enum y, mira tú por dónde, no existe property ecitor alguno que te realice este binding. Buscando un poco por internet encontré un post en el que se explicaba cómo implementar un property editor para enums, lo cual me solventó la papeleta.

En este post voy a explicar lo que explica este hombre en inglés y para Spring MVC pero en castellano y para Spring Webflow, así como a realizar una modificación que, bajo mi punto de vista, hace que la solución que se propone posea otra alternativa también útil en algunos casos.

En primer lugar, he aquí nuestro enum, cualquier cosa:

package es.joselopezpua.examples;

public  enum EnumSample {
    TO_BE, NOT_TO_BE
}

Ahora escribamos la clase del property editor:

package es.joselopezpua.examples;</code>

import java.beans.PropertyEditorSupport;

/**
* Editor que permite la traducción entre {@link String} y {@link Enum}
*/

@SuppressWarnings("unchecked")
public class EnumEditor extends PropertyEditorSupport {

    /**
    * Esta clase será la clase concreta que se pasará al property editor como enumerado.
    */
    private Class clazz;

    /**
    * Constructor.
    * @param clazz
    */
    public EnumEditor(Class clazz) {
    this.clazz = clazz;
    };

    /**
    * Devuelve el valor del enumerado como texto.
    */
    public String getAsText() {
        return (getValue() == null ? "" : ((Enum) getValue()).toString());
    }

    /**
    * Establece el valor a partir de una cadena de texto.
    */
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(Enum.valueOf(clazz, text));
    }
}

Sólo nos queda registrarla mediante nuestro property editors:

package es.joselopezpua.examples;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;

/**
* PropertyEditors específico para registrar EnumEditor.
*
*/
public class PropertyEditors implements PropertyEditorRegistrar {

    /**
    * Registra nuestro PropertyEditor personalizado.
    */
    public void registerCustomEditors(final PropertyEditorRegistry registry) {
        registry.registerCustomEditor(EnumSample.class, new EnumEditor(EnumSample.class));
    }
}

Y listo, ya podemos hacer binding tranquilamente con nuestros formularios y tipos enum en Spring Webflow. Ahora, si me lo permitís, mi sugerencia.

En primer lugar imaginad que hemos definido nuestro enum con una cadena de texto para cada posible valor, tal que así:

package es.joselopezpua.examples;

    public  enum EnumSample {
        TO_BE("ser"),
        NOT_TO_BE("no ser")
    };

    /**
    * Cadena asociada al enumerado.
    */
    private String label;

    /**
    * Contructor del enumerado.
    *
    * @param stringValue cadena asociada.
    */
    EnumSample(final String stringValue) {
        this.label = stringValue;
    }

    /**
    * @see java.lang.Enum#toString().
    *
    * @return cadena asociada al enumerado.
    */
    @Override
    public String toString() {
        return label;
    }
}

Como véis hemos sobreescrito el método toString() para que devuelva la cadena asociada al enum.

En este punto es posible que nuestro EnumEditor se comporte de dos formas distintas:

  1. Estableciendo y recuperando el valor del enum en función del texto que representa al nombre de la constante. (como se ha descrito hasta ahora).
  2. Estableciendo y recuperando el valor del enum en función del texto que representa la descripción asociada a la constante.

Veamos las modificaciones oportunas para este segundo caso. El método getAsText() no cambia, dado que hemos sobreescrito el método toString() anteriormente. Modificamos el método setAsText(String text), para que establezca como valor el objeto enum apropiado para la cadena de texto que se le pasa, interpretándola como descripción asociada a la constante. Con todo, nuestro nuevo EnumEditor quedaría como sigue:

package es.joselopezpua.examples;

import java.beans.PropertyEditorSupport;

/**
* Editor que permite la traducción entre {@link String} y {@link Enum}, en función del valor de la descripción asociada a la constante del enumerado.
*/

@SuppressWarnings("unchecked")
public class EnumEditor extends PropertyEditorSupport {

    /**
    * Esta clase será la clase concreta que se pasará al property editor como enumerado.
    */
    private Class clazz;

    /**
    * Constructor.
    * @param clazz
    */
    public EnumEditor(Class clazz) {
        this.clazz = clazz;
    };

    /**
    * Devuelve el valor del enumerado como texto.
    */
    public String getAsText() {
        return (getValue() == null ? "" : ((Enum) getValue()).toString());
    }

    /**
    * Establece el valor a partir de una cadena de texto.
    */
    public void setAsText(String text) throws IllegalArgumentException {
        EnumSample enumSamples[] = EnumSample.values();
        boolean enc = false;
        int i = 0;
        while (i &lt; enumSamples.length &amp;&amp; !enc) {
            if (enumSamples[i].toString().equals(text)) {
                enc = true;
            } else {
                i++;
            }
        }
        if (!enc) {
            throw new IllegalArgumenException();
        } else {
            setValue(Enum.valueOf(clazz, enumSamples[i]));
        }
    }
}

Como se puede observar, simplemente comparamos la descripción de todos los posibles valores del enum con la cadena que se recibe; en caso de encontrar un valor cuya descripción sea igual, se establece ese enum como valor, si no, se lanza una excepción.

Esto puede resultar útil cuando nos interesa, por la razón que sea, que el valor del campo del formulario con el que hayamos hecho el binding del enum contenga la descripción y no el valor ordinal.

Espero que os sea de utilidad.

Posts relacionados:

Anuncios

Acciones

Information

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s




A %d blogueros les gusta esto: