[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