dimanche 7 juin 2015

CDI: @Inject, qualifiers, @Produces, differen implementation

I would like to have CD @Produces method that based on some condition is producing suitable implementation of ZipCodeChecker implementation. It is properly instantiated implementation of CountryZipCodeChecker which is used by CountryZipCodeValidator to validate zip code suitable to address set in Address entity. I have made something like this:

   public class CountryZipCodeValidator implements ConstraintValidator<CountryZipCode, Address> {

    private static final Logger logger = Logger.getLogger(CountryZipCodeValidator.class.getName());

    @Inject
    private Instance<ZipCodeChecker> checkerInstance;

    @Override
    public void initialize(CountryZipCode constraintAnnotation) {

    }

    @Override
    public boolean isValid(Address value, ConstraintValidatorContext context) {

        logger.log(Level.INFO, "Validating zip code format for typed country.");

        if(value.getZipCode() == null || value.getCountry() == null)
            return true;

        // selecting ZipCodeChecker instance specific to country name set in Address object
        ZipCodeChecker checker = checkerInstance.select(new CountryQualifierLiteral(value.getCountry())).get();

        return checker.isFormatValid(value.getZipCode());
     }
   }

and ZipCodeCheckerFactory which @Produces suitable ZipCodeChecker

    public class ZipCodeCheckerFactory {

    @Inject
    CountryZipCodeChecker countryZipCodeChecker;

    @Produces
    public ZipCodeChecker createZipCodeChecker(InjectionPoint injectionPoint) {

        // retrieving country name from injection point to return country specific checker instance
        Country countryQualifier = injectionPoint.getAnnotated().getAnnotation(Country.class);
        String countryName = countryQualifier.value();

        countryZipCodeChecker.setCountryName(countryName);

        return countryZipCodeChecker;
    }

}

here is snippet of CountryZipCodeChecker:

public class CountryZipCodeChecker implements ZipCodeChecker { /*...*/}

here is ZipCodeChecker interface:

    public interface ZipCodeChecker {

    public boolean isFormatValid(String zipCode);
}

and qualifier implementation:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER,})
public @interface Country {

    @Nonbinding String value() default "United States";
}

and I get such an error and NullPointer exception when trying to call on @Injected zipCodeChecker.isValid() method:

 org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.weld.exceptions.IllegalArgumentException : WELD-001302: Duplicate qualifiers:  [@pl.salonea.qualifiers.Country(value=United States)] [Proxied because : Original exception not deserilizable, ClassNotFoundException]
    at org.jboss.weld.resolution.ResolvableBuilder.checkQualifier(ResolvableBuilder.java:210)
    at org.jboss.weld.resolution.ResolvableBuilder.addQualifier(ResolvableBuilder.java:177)
    at org.jboss.weld.resolution.ResolvableBuilder.addQualifiers(ResolvableBuilder.java:200)

Aucun commentaire:

Enregistrer un commentaire