Una vez que tengamos definido el translator, Tapestry buscará el adecuado según el tipo de objeto a traducir y lo usará según sea necesario sin necesidad de que tengamos que hacer nada más. Vamos a ver un ejemplo, supongamos que en un campo de un formulario necesitamos mostrar una fecha con un determinado formato. En nuestras clases trabajaremos con objetos de tipo Date. El usuario deberá introducir la fecha con formato «dd/MM/yyyy».
... import org.apache.tapestry5.internal.translator.AbstractTranslator; import org.apache.tapestry5.services.FormSupport; import com.evandti.ticketbis.domain.CodigoDescuento; import com.evandti.ticketbis.misc.Utilidades; import com.evandti.ticketbis.tapestry.services.TicketbisService; public class DateTranslator extends AbstractTranslator<Date> { private String patron; public DateTranslator(String patron) { super("date", Date.class, "date-format-exception"); this.patron = patron; } @Override public String toClient(Date value) { if (value == null) { return null; } return new SimpleDateFormat(patron).format(value); } @Override public Date parseClient(Field field, String clientValue, String message) throws ValidationException { if (clientValue == null) { return null; } try { return new SimpleDateFormat(patron).parse(clientValue); } catch (ParseException e) { throw new ValidationException(message); } } @Override public void render(Field field, String message, MarkupWriter writer, FormSupport formSupport) { } }
Estamos extendiendo una clase del paquete org.apache.tapestry5.internal que es algo no recomendado pero la utilizamos por sencillez y para no tener que implementar nosotros lo que hace el propio AbstractTranslator. Para que Tapestry lo utilice deberemos hacer una contribución en el módulo de nuestra aplicación donde básicamente decimos que para una determinada clase se utilice un determinado Translator.
/* AppModule.java */ public static void contributeTranslatorSource(MappedConfigurationconfiguration) { configuration.add(Date.class, new DateTranslator("dd/MM/yyyy")); }
A partir de este momento podríamos tener en archivo .tml de una página o componente lo siguiente y en la propiedad fecha del componente o página tendríamos un objeto de tipo Date olvidándonos por completo de la traducción.
<t:label for="fecha"/>: <t:textfield t:id="fecha" value="fecha" size="12" label="Fecha"/>
Hay otra interfaz que hacen algo similar a los Translators, es la interfaz ValueEncoder pero la diferencia entre las dos está en que en los translators puede ser necesaria algún tipo de validación por nuestra parte ya que son datos que introduce el usuario y en los encoders no ya que no son datos que introduce el usuario. Esto se ve claramente en los parámetros de los componentes TextField, Hidden y Select, el primero utiliza un Translator y los dos últimos un ValueEndoder.
Tapestry ya proporciona un ValueEncoder para las entidades de nuestro dominio si utilizamos Hibernate, la clase es HibernateEntityValueEncoder. Para terminar, indicar Tapestry también proporciona un ValueEncoder por defecto para los tipos Enum.
Referencia:
Documentación sobre Apache Tapesty