Friday, December 13, 2013

Sapphire 0.7 : Improved Localization for Java

Within Java code, such as an implementation of a service, Sapphire has previously relied on the NLS class copied from Eclipse platform. The developer experience has been improved.

  • The static fields holding localizable text are able to exist in any class, not just a dedicated resource bundle class.

  • Formatting messages using localizable text as a template is more fluid.

    Resources.message.format( x, y )  vs  NLS.bind( Resources.message, x, y )

  • The original text can be specified using an annotation, concentrating text closer to the point of use and avoiding numerous problems associated with maintaining text in discrete resource files. When time comes to do the translation, an annotation processor or a similar build system can be used to extract text into resource files. Only the translated versions of the resource files need to be distributed. The original text will be read from the annotations at runtime.

Before After
public class Validator
{
    public String validate( Integer value, Integer max )
    {
        if( value == null )
        {
            return Resources.mustBeSpecifiedMessage;
        }
        else if( max != null && value.intValue() > max.intValue() )
        {
            return NLS.bind
            (
                Resources.mustNotBeLargerThanMessage, 
                max
            );
        }

        return null;
    }

    private static final class Resources extends NLS 
    {
        public static String mustBeSpecifiedMessage;
        public static String mustNotBeLargerThanMessage;

        static 
        {
            initializeMessages
            (
                Validator.class.getName(),
                Resources.class
            );
        }
    }
}

# Content of Validator.properties file

mustBeSpecifiedMessage = Value must be specified.
mustNotBeLargerThanMessage = Value must not be larger than {0}.
public class Validator
{
    @Text( "Value must be specified." )
    private static LocalizableText mustBeSpecifiedMessage;

    @Text( "Value must not be larger than {0}." )
    private static LocalizableText mustNotBeLargerThanMessage;

    static
    {
        LocalizableText.init( Validator.class );
    }

    public String validate( Integer value, Integer max )
    {
        if( value == null )
        {
            return mustBeSpecifiedMessage.text();
        }
        else if( max != null && value.intValue() > max.intValue() )
        {
            return mustNotBeLargerThanMessage.format( max );
        }

        return null;
    }
}

No comments: