Raging Goblin

18 April 2013

Spring Roo 6: Representation of enums and internationalization

Filed under: Java,Spring Roo — Raging Goblin @ 20:34
Tags: , ,

Today a short post about the representation of enums in Spring Roo and internationalization. First, we are going to add an enum (Gender) to our application:

enum type --class ~.domain.Gender
enum constant --name MALE 
enum constant --name FEMALE
focus --class ~.domain.LogUser
field enum --type ~.domain.Gender --fieldName gender

This will also add the Gender to the user management. The problem with this is the representation, which is ugly and most certainly not usable in a multi language application:
Ugly enum representation.
To change this we install an extra formatter in the ApplicationConversionServiceFactoryBean. Many examples on the web create a dedicated formatter for each enum, but in a real application you will have many enums. It is therefore much easier to install just one formatter for all enums:

package raging.goblin.roo.web;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.roo.addon.web.mvc.controller.converter.RooConversionService;

@RooConversionService
public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean implements ApplicationContextAware {

	private ApplicationContext applicationContext;

	@Override
	protected void installFormatters(FormatterRegistry registry) {
		super.installFormatters(registry);
		registry.addConverter(createEnumConverter());
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	private Converter<Enum<?>, String> createEnumConverter() {
		return new Converter<Enum<?>, String>() {

			@Override
			public String convert(Enum<?> value) {
				String output = value.toString();
				try {
					output = applicationContext.getMessage(value.toString(), null, LocaleContextHolder.getLocale());
				} catch (NoSuchMessageException e) {
					System.err.println("No message resource found for " + value + " add this to the resource bundle");
				}
				return output;
			}
		};
	}
}

Note that the ApplicationConversionServiceFactoryBean implements the ApplicationContextAware interface. Spring will take care of injecting the the ApplicationContext for you.

Add the following lines to ‘~/logbook/src/main/webapp/WEB-INF/i18n/application.properties‘:

#enums
MALE=Male
FEMALE=Female

The result:
Nice enum representation

This also facilitates internationalization of enums. Installing i18n in Spring Roo is quite easy. The command ‘web mvc install language –code nl‘ e.g. adds all necessities to display the user interface in dutch. Of course Roo cannot provide translations for all specific messages and entities, so you will have to add them yourself in ‘~/logbook/src/main/webapp/WEB-INF/i18n/messages_nl.properties‘ and ‘~/logbook/src/main/webapp/WEB-INF/i18n/application_nl.properties‘. In the latter you can provide translations for your enum values, which will make your application fully international:
Dutch enum representation

Blog at WordPress.com.