0
votes

I am trying to provide an opportunity to inject an arbitrary enum given injection point and string value (that is obtained in Produces method)

Arbitrary means if I have enum My and enum Your I would like to inject both of them or any other one with the same producer method.

So I tried several approaches: 1.

@Produces
@MyConfigAnnotation
Enum getArbitraryEnum(InjectionPoint point) {
    ...
    // get string representation, 
    // instantiate enum using point
    return Enum.valueOf((Class<Enum>)injectionPoint.getAnnotated().getClass(), enumValue);
}

2. I changed return type to Object.

In both cases I receive the next exception Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type TestEnum with qualifiers @X at injection point [BackedAnnotatedField] @Inject @X pathToMyField.testEnum2

So is there any way to create a Produces method that will be able to produce an arbitrary enum.

1
Can you provide more of your producer method? What container are you running?John Ament
@JohnAment I have added the way I am trying to instantiate enum. But this hardly matters as it seems that the app does not come into method. Regarding container, I am using Jboss Weld, or did you mean something different?Anjenson

1 Answers

-1
votes

You will need to have unique combinations of instance and qualifier, since without the qualifier, weld does not know which producer to call.

There is a way achieving dynamic enum binding, I found it in the comments of this article: http://www.ocpsoft.org/java/how-to-inject-enum-values-into-cdi-beans/

public class InjectedObject {
   private MyEnum e1;
   private MyEnum e2;
   private MyEnum e3;

   @Inject
   public InjectedObject(@Config("ONE") MyEnum e1, @Config("TWO") MyEnum e2,     @Config("THREE") MyEnum e3)   {
      this.e1 = e1;
      this.e2 = e2;
      this.e3 = e3;
   }


   /**
    * A producer is required in order to {@link Inject} an Enum
    */
   @Produces
   @Config
   public static MyEnum getEnum(InjectionPoint ip) {
       String name = null;

       /**
        * Iterate over all Qualifiers of the Injection Point to find our configuration and save the config value
        */
       for(Annotation a : ip.getQualifiers()) {
           if(a instanceof Config) {
               name = ((Config) a).value();
           }
       }

       /**
        * Iterate over all enum values to match them against our configuration value
        */
       for(MyEnum me : MyEnum.values()) {
           if(me.toString().equals(name)) {
               return me;
           }
       }

      return null;
   }

    /**
    * Our enum
    */
   public enum MyEnum {      ONE, TWO, FOO   }

   @Qualifier
   @Target({ TYPE, METHOD, PARAMETER, FIELD })
   @Retention(RUNTIME)
   @Documented
   public @interface Config {
       @Nonbinding String value() default "";
   }
}

The interesting part is of course the custom Qualifier with the nonbinding value, causing CDI to choose the right producer method.

That all being said ... since you need an extra qualifier that somehow contains the name of the enum you want to inject ... why inject at all?