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

Advertisements

7 Comments »

  1. I try to add your advice and I can not compile my project.

    How do you inject the attributte applicationContext?

    Comment by Ricardo — 26 August 2013 @ 04:30 | Reply

    • Good point, I updated the post to make this clear.

      Comment by raginggoblin — 3 September 2013 @ 15:06 | Reply

  2. Hello!
    I follow your steps but i can’t achive the goal of enums internationalization.

    On application ApplicationConversionServiceFactoryBean class the method createEnumConverter has warning (” is never used locally “).
    Is this problem ?

    Comment by Manousos — 18 December 2013 @ 22:29 | Reply

    • To me this happens when I forgot to open the roo shell from STS. So when you use roo from the command line I suggest to switch to STS and open a roo shell from within. If you however use the roo shell from within STS I do not have a solution for this but it should not have any effect on the application. It is just a compiler warning from your IDE, you should still see the internationalization taking effect when running the application.

      Comment by raginggoblin — 20 December 2013 @ 10:29 | Reply

      • Hello again…

        When i wrote the code, i had open the Roo Shell in STS.
        The other thing that i observe is, in dubug mode this block of code, never runs !
        I can’t understand in which place the “createEnumConverter()” method is called.

        In your project, when you choose “Open Call Hierarchy” in STS, what is the results ?
        In my project, is nothing.

        Comment by Manousos — 20 December 2013 @ 22:06 | Reply

      • I am coming back about the warning (” is never used locally “)…
        i changes the method from private to public and warning disappeared.
        But the enums still’s without translation 😦

        Comment by Manousos — 21 December 2013 @ 16:15 | Reply

        • You are right, I made a mistake in my code. It should be registry.addConverter(createEnumConverter()); The reason why you do not see any calls in STS is because this is handled by the Spring framework.

          Comment by raginggoblin — 26 December 2013 @ 13:11 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: