[cdi-dev] [JBoss JIRA] (CDI-584) Clarification needed on Set mutability returned by SPI

Antoine Sabot-Durand (JIRA) issues at jboss.org
Fri Feb 19 09:24:00 EST 2016


    [ https://issues.jboss.org/browse/CDI-584?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13165772#comment-13165772 ] 

Antoine Sabot-Durand edited comment on CDI-584 at 2/19/16 9:23 AM:
-------------------------------------------------------------------

To that I could answer, "what's the use of ProcessBean if you can't do anything about the bean tied to the event" ;) ?
But I have an example. I was asked to build a prototype extension to create an injection point when a given annotation ({{@CacheContext}}) is found on a field. Here's the portable code I had to wrote to create the feature :
* An AnnotatedType [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectingAnnotatedType.java]
* An AnnotatedField [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectingAnnotatedField.java]
* and the [Extension|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectExtension.java]

Extension code is small but {{AnnotatedType}} and {{AnnotatedField}} impls are verbose and the whole is cumbersome to read and maintain (3 classes and 178 lines of code)

If we only target OWB, the extension code is:

{code}
package org.cdisandbox.autoinject.Extension;

import org.cdisandbox.autoinject.CacheContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.*;
import java.util.HashSet;
import java.util.Set;

/**
 * Extension looking for the @CacheContext annotation to transform it in an InjectionPoint
 */
public class AutoInjectExtension implements Extension {

    private Set<AnnotatedType<?>> atWithCacheContext = new HashSet<>();

    /**
     * This Observer captures all AnnotatedType containing @CacheContext
     */
    public void CreateInjectionPoint(@Observes @WithAnnotations(CacheContext.class) ProcessAnnotatedType<?> pat) {
        atWithCacheContext.add(pat.getAnnotatedType());
    }

    /**
     * This observer add an injection point in all bean having @Cachecontext annotaion on some field
     */
    public <T> void CheckBeansForCacheContext(@Observes ProcessManagedBean<T> pmb, BeanManager bm) {
        AnnotatedType<T> beanAT = pmb.getAnnotatedBeanClass();
        if(atWithCacheContext.contains(beanAT)) {
            Bean<T> bean = pmb.getBean();
            Set<InjectionPoint> ips = new HashSet(bean.getInjectionPoints());
            for (AnnotatedField<? super T> f : beanAT.getFields()) {
                if(f.isAnnotationPresent(CacheContext.class)) {
                    ips.add(bm.createInjectionPoint(f));
                }
            }
        }
    }
}
{code}

One class, 42 lines.



was (Author: antoinesabot-durand):
To that I could answer, "what's the use of ProcessBean if you can't do anything about the bean tied to the event" ;) ?
But I have an example. I was asked to build a prototype extension to create an injection point when a given annotation ({{@CacheContext}}) is found on a field. Here's the portable code I had to wrote to create the feature :
* An AnnotatedType [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectingAnnotatedType.java]
* An AnnotatedField [implementation|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectingAnnotatedField.java]
* and the [Extension|https://github.com/antoinesd/CDI-Sandbox/blob/fb18eb718ab93f68dcef6b934d70589b789d251b/auto-inject/src/main/java/org/cdisandbox/autoinject/Extension/AutoInjectExtension.java]

Extension code is small but {{AnnotatedType}} and {{AnnotatedField }} are verbose and the whole is cumbersome to read and maintain (3 classes and 178 lines of code)

If we only target OWB, the extension code is:

{code}
package org.cdisandbox.autoinject.Extension;

import org.cdisandbox.autoinject.CacheContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.*;
import java.util.HashSet;
import java.util.Set;

/**
 * Extension looking for the @CacheContext annotation to transform it in an InjectionPoint
 */
public class AutoInjectExtension implements Extension {

    private Set<AnnotatedType<?>> atWithCacheContext = new HashSet<>();

    /**
     * This Observer captures all AnnotatedType containing @CacheContext
     */
    public void CreateInjectionPoint(@Observes @WithAnnotations(CacheContext.class) ProcessAnnotatedType<?> pat) {
        atWithCacheContext.add(pat.getAnnotatedType());
    }

    /**
     * This observer add an injection point in all bean having @Cachecontext annotaion on some field
     */
    public <T> void CheckBeansForCacheContext(@Observes ProcessManagedBean<T> pmb, BeanManager bm) {
        AnnotatedType<T> beanAT = pmb.getAnnotatedBeanClass();
        if(atWithCacheContext.contains(beanAT)) {
            Bean<T> bean = pmb.getBean();
            Set<InjectionPoint> ips = new HashSet(bean.getInjectionPoints());
            for (AnnotatedField<? super T> f : beanAT.getFields()) {
                if(f.isAnnotationPresent(CacheContext.class)) {
                    ips.add(bm.createInjectionPoint(f));
                }
            }
        }
    }
}
{code}

One class, 42 lines.


> Clarification needed on Set mutability returned by SPI
> ------------------------------------------------------
>
>                 Key: CDI-584
>                 URL: https://issues.jboss.org/browse/CDI-584
>             Project: CDI Specification Issues
>          Issue Type: Clarification
>          Components: Portable Extensions
>            Reporter: Antoine Sabot-Durand
>
> {{ProcessBean}} lifecycle event could be the occasion to add new Injection point to an existing bean, but when you call {{ProcessBean#getBean()#getInjectionPoints()}} the returned set is mutable in OWB and immutable in Weld.
> As the spec doesn't precise if the Set should be mutable or not, each impl made its own choice.
> The result is a lack of consistency between both impl and an interesting feature harder to do with Weld (work with AnnotatedType or create a custom bean to add injection point)
> More generally we should clarify mutability of each Set returned in the SPI. And check if it wouldn't be better to add method to life cycle event to provide a "temporary" mutable set (i.e. {{ProcessBean#getInjectionPoints()}}



--
This message was sent by Atlassian JIRA
(v6.4.11#64026)


More information about the cdi-dev mailing list