Search code examples
grailsgroovyenumsinternationalizationmixins

How to get the target class of a groovy mixin?


I'm trying to do the following in Grails:

class I18nEnum implements MessageSourceResolvable {
    public Object[] getArguments() { [] as Object[] }
    public String[] getCodes() { [ this.class.canonicalName+'.'+name() ] }
    public String getDefaultMessage() { "?-" + name() }
}

and then use this class like this:

class MyDomainClass {
    @Mixin(I18nEnum)
    public static enum MaritalStatus {
        SINGLE, MARRIED
    }
    MaritalStatus maritalStatus
}

Then MyDomainClass is used with scaffolding to generate an HTML select field, and to have the options translatable in messages.properties like this:

my.package.MyDomainClass.MaritalStatus.SINGLE  = Single
my.package.MyDomainClass.MaritalStatus.MARRIED = Married

But I cannot find a way to get the name of the target class (my.package.MyDomainClass.MaritalStatus), and instead I get the name of the mixin class (my.package.I18nEnum@1dd658e9)

How can I get the target class of a groovy mixin?

Is there a way to do something like this?

    public String[] getCodes() { [ this.targetClass.canonicalName+'.'+name() ] }

Or like this?

    public String[] getCodes() { [ this.mixinTargetClass.canonicalName+'.'+name() ] }

Note: For the moment the only way that I made this enum internationalization feature to work was by just copy-pasting this for every enum class defined in the application:

public static enum MaritalStatus implements MessageSourceResolvable {
    SINGLE, MARRIED
    public Object[] getArguments() { [] as Object[] }
    public String[] getCodes() { [ this.class.canonicalName+'.'+name() ] }
    public String getDefaultMessage() { name() }
}
MaritalStatus maritalStatus

But I would like to not repeat the same code for every enum, but instead just mixin the required methods implementing MessageSourceResolvable.


Solution

  • Mixins do not work with enums. May be it will be useful for you:

    class Mix {
        def enumClazz
        Mix(def clz) { enumClazz = clz }
        def getCode() { println "---> ${enumClazz.name()}"}
    }
    
    
    enum MaritalStatus {
        SINGLE, MARRIED    
    
        @Delegate Mix mixClz = new Mix(this)
    }
    
    MaritalStatus.MARRIED.code