0

I have the Enum:

public enum EmployeeErrorCode {
    DELETE_SUCCESS,

    //... Other enumerators

    @Override
    public String toString(){
        ApplicationContext ctx = ContextLoader
                                         .getCurrentWebApplicationContext();
        MessageSource messageSource = (MessageSource) ctx
                                         .getBean("messageSource"); //How to avoid this?
        switch (this) {
        case DELETE_SUCCESS:
            return messageSource.getMessage("deleteEmployee.success", 
                                          null, LocaleContextHolder.getLocale());

        //... Other cases

        default:
            return null;
        }
    }
}

In the toString nethod I specified the messages for any Enumerator, but I used getBean method to programmatically get the appropriate bean. How can I avoid that?

I tried to inject the bean via

@Autowired
MessageSource messageSource;

but it didn't work. In fact, messageSource was just null. Is there a way to do that corretly at all?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 1
    Just implement `MessageSourceResolvable` which will make your enum passable to a `MessageSource`. That way anything that gets the enum can simply do `messageSource.getMessage(enumValue, LocaleContextHolder.getLocale())` or if you use it in a JSP you can just pass the enum to the message tag which will take care of everything. Doing it in the `toString` is imho a very bad idea (the `MessageSourceResolvable` is slighty less bad) imho enums should be small and contain as little logic as possible you have tied your whole domain to Spring in either way. – M. Deinum Jan 11 '15 at 15:50
  • @M.Deinum Interesting note, thank you. I realise why doing that within toString is not good. Why do you think to implement the `MessageSourceResolvable` is a bad idea? – St.Antario Jan 11 '15 at 15:59
  • It is a little better but as stated it depends on whether or not you are willing to have your own domain depend on a framework (spring in this case). – M. Deinum Jan 12 '15 at 06:38

1 Answers1

1

If MessageSource is a bean that opens a properties file, then for example if your properties file is called Messages.properties, then you can use

ResourceBundle bundle = ResourceBundle.getBundle("Messages", LocaleContextHolder.getLocale());
String message = bundle.getString("deleteEmployee.success");

EDIT: Another possible method is to inject the MessageSource into your enums (idea from my solution at Java Generics and Enum, loss of template parameters ), like so:

public enum EmployeeErrorCode {
    DELETE_SUCCESS {
        @Override
        public String toString() {
             return messageSource.getMessage("deleteEmployee.success", null, LocaleContextHolder.getLocale());
        }
    },
    //... Other enumerators

    private MessageSource messageSource;

    static class EnumInitializer {
        @Autowired
        private MessageSource messageSource;

        @PostConstruct
        public void init() {
            for(EmployeeErrorCode errorCode : EmployeeErrorCode.values() {
                errorCode.messageSource = getMessageSource();
            }
        }

        public MessageSource getMessageSource() {
            return messageSource;
        }
    }
}

But I think the other one is a bit cleaner.

Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428