Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
332 additions
and
0 deletions.
There are no files selected for viewing
128 changes: 128 additions & 0 deletions
128
impl/src/main/java/org/jboss/weld/extensions/bean/NarrowingBean.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package org.jboss.weld.extensions.bean; | ||
|
||
import static org.jboss.weld.extensions.util.Reflections.cast; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Type; | ||
import java.util.Set; | ||
|
||
import javax.enterprise.context.spi.CreationalContext; | ||
import javax.enterprise.inject.spi.Bean; | ||
import javax.enterprise.inject.spi.InjectionPoint; | ||
|
||
import org.jboss.weld.extensions.util.Reflections; | ||
|
||
/** | ||
* <p> | ||
* A narrowing bean allows you to build some general purpose bean (likely a | ||
* producer method), and register it for a narrowed type (or qualifiers). For | ||
* example, you could create a producer method which uses an a String ID to | ||
* located an object (the object can have any class): | ||
* </p> | ||
* | ||
* <pre> | ||
* @Produces | ||
* // Use some synthetic scope to prevent this from interfering with other resolutions | ||
* @MyProducer | ||
* Object produce(InjectionPoint ip) | ||
* { | ||
* String id = ip.getAnnotated().getAnnotation(Id.class).value(); | ||
* // Lookup and return the object for the id | ||
* } | ||
* </pre> | ||
* | ||
* <p> | ||
* You can then register a narrowing bean for each type you need: | ||
* </p> | ||
* | ||
* <pre> | ||
* event.addBean(new NarrowingBeanBuilder<T>(delegateBean).readFromType(type).create()); | ||
* </pre> | ||
* | ||
* <p> | ||
* {@link NarrowingBean} will use the annotations on <code>defininingType</code> | ||
* to discover the qualifiers, types, scope, stereotypes of the bean, as well as | ||
* determine it's name (if any) and whether it is an alternative. | ||
* </p> | ||
* | ||
* @author Pete Muir | ||
* @see NarrowingBeanBuilder | ||
*/ | ||
public class NarrowingBean<T> implements Bean<T> | ||
{ | ||
|
||
private final Bean<Object> delegate; | ||
private final Set<Type> types; | ||
private final Set<Annotation> qualifiers; | ||
private final String name; | ||
private final Class<? extends Annotation> scope; | ||
private final boolean alternative; | ||
private final Set<Class<? extends Annotation>> stereotypes; | ||
|
||
NarrowingBean(Bean<Object> loggerProducerBean, Set<Type> types, Set<Annotation> qualifiers, String name, Class<? extends Annotation> scope, boolean alternative, Set<Class<? extends Annotation>> stereotypes) | ||
{ | ||
this.delegate = loggerProducerBean; | ||
this.types = types; | ||
this.qualifiers = qualifiers; | ||
this.name = name; | ||
this.scope = scope; | ||
this.alternative = alternative; | ||
this.stereotypes = stereotypes; | ||
} | ||
|
||
public Set<Type> getTypes() | ||
{ | ||
return types; | ||
} | ||
|
||
public Set<Annotation> getQualifiers() | ||
{ | ||
return qualifiers; | ||
} | ||
|
||
public String getName() | ||
{ | ||
return name; | ||
} | ||
|
||
public Class<? extends Annotation> getScope() | ||
{ | ||
return scope; | ||
} | ||
|
||
public T create(CreationalContext<T> creationalContext) | ||
{ | ||
return Reflections.<T>cast(delegate.create(Reflections.<CreationalContext<Object>>cast(creationalContext))); | ||
} | ||
|
||
public void destroy(T instance, CreationalContext<T> creationalContext) | ||
{ | ||
delegate.destroy(instance, Reflections.<CreationalContext<Object>>cast(creationalContext)); | ||
} | ||
|
||
public Set<Class<? extends Annotation>> getStereotypes() | ||
{ | ||
return stereotypes; | ||
} | ||
|
||
public Class<?> getBeanClass() | ||
{ | ||
return delegate.getBeanClass(); | ||
} | ||
|
||
public boolean isAlternative() | ||
{ | ||
return alternative; | ||
} | ||
|
||
public boolean isNullable() | ||
{ | ||
return false; | ||
} | ||
|
||
public Set<InjectionPoint> getInjectionPoints() | ||
{ | ||
return delegate.getInjectionPoints(); | ||
} | ||
|
||
} |
204 changes: 204 additions & 0 deletions
204
impl/src/main/java/org/jboss/weld/extensions/bean/NarrowingBeanBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
package org.jboss.weld.extensions.bean; | ||
|
||
import static org.jboss.weld.extensions.util.Arrays2.asSet; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Type; | ||
import java.util.Collection; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import javax.enterprise.context.Dependent; | ||
import javax.enterprise.inject.Alternative; | ||
import javax.enterprise.inject.spi.AnnotatedType; | ||
import javax.enterprise.inject.spi.Bean; | ||
import javax.enterprise.inject.spi.BeanManager; | ||
import javax.inject.Named; | ||
|
||
import org.jboss.weld.extensions.literal.AnyLiteral; | ||
import org.jboss.weld.extensions.literal.DefaultLiteral; | ||
|
||
/** | ||
* Builder for {@link NarrowingBean} | ||
* | ||
* @author Pete Muir | ||
* @see NarrowingBean | ||
* | ||
*/ | ||
public class NarrowingBeanBuilder<T> | ||
{ | ||
|
||
private final Bean<Object> delegate; | ||
private Set<Type> types; | ||
private Set<Annotation> qualifiers; | ||
private String name; | ||
private Class<? extends Annotation> scope; | ||
private boolean alternative; | ||
private Set<Class<? extends Annotation>> stereotypes; | ||
|
||
public static <T> NarrowingBeanBuilder<T> of(Bean<Object> delegate) | ||
{ | ||
return new NarrowingBeanBuilder<T>(delegate); | ||
} | ||
|
||
public NarrowingBeanBuilder(Bean<Object> delegate) | ||
{ | ||
this.delegate = delegate; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> readFromType(AnnotatedType<T> type, BeanManager beanManager) | ||
{ | ||
this.types = new HashSet<Type>(type.getTypeClosure()); | ||
this.qualifiers = new HashSet<Annotation>(); | ||
this.stereotypes = new HashSet<Class<? extends Annotation>>(); | ||
String name = null; | ||
Class<? extends Annotation> scope = Dependent.class; | ||
for (Annotation annotation : type.getAnnotations()) | ||
{ | ||
if (beanManager.isQualifier(annotation.annotationType())) | ||
{ | ||
this.qualifiers.add(annotation); | ||
} | ||
else if (annotation.annotationType().equals(Named.class)) | ||
{ | ||
name = Named.class.cast(annotation).value(); | ||
} | ||
else if (beanManager.isScope(annotation.annotationType())) | ||
{ | ||
scope = annotation.annotationType(); | ||
} | ||
else if (beanManager.isStereotype(annotation.annotationType())) | ||
{ | ||
this.stereotypes.add(annotation.annotationType()); | ||
} | ||
} | ||
if (qualifiers.isEmpty()) | ||
{ | ||
this.qualifiers.add(DefaultLiteral.INSTANCE); | ||
} | ||
this.qualifiers.add(AnyLiteral.INSTANCE); | ||
this.name = "".equals(name) ? null : name; | ||
this.scope = scope; | ||
this.alternative = type.isAnnotationPresent(Alternative.class); | ||
return this; | ||
} | ||
|
||
public Set<Type> getTypes() | ||
{ | ||
return types; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> types(Set<Type> types) | ||
{ | ||
this.types = types; | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> types(Type... types) | ||
{ | ||
this.types = asSet(types); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addType(Type type) | ||
{ | ||
this.types.add(type); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addTypes(Type... types) | ||
{ | ||
this.types.addAll(asSet(types)); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addTypes(Collection<Type> types) | ||
{ | ||
this.types.addAll(types); | ||
return this; | ||
} | ||
|
||
public Set<Annotation> getQualifiers() | ||
{ | ||
return qualifiers; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> qualifiers(Set<Annotation> qualifiers) | ||
{ | ||
this.qualifiers = qualifiers; | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> qualifiers(Annotation... qualifiers) | ||
{ | ||
this.qualifiers = asSet(qualifiers); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addQualifier(Annotation qualifier) | ||
{ | ||
this.qualifiers.add(qualifier); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addQualifiers(Annotation... qualifiers) | ||
{ | ||
this.qualifiers.addAll(asSet(qualifiers)); | ||
return this; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> addQualifiers(Collection<Annotation> qualifiers) | ||
{ | ||
this.qualifiers.addAll(qualifiers); | ||
return this; | ||
} | ||
|
||
public String getName() | ||
{ | ||
return name; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> name(String name) | ||
{ | ||
this.name = name; | ||
return this; | ||
} | ||
|
||
public Class<? extends Annotation> getScope() | ||
{ | ||
return scope; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> scope(Class<? extends Annotation> scope) | ||
{ | ||
this.scope = scope; | ||
return this; | ||
} | ||
|
||
public boolean isAlternative() | ||
{ | ||
return alternative; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> alternative(boolean alternative) | ||
{ | ||
this.alternative = alternative; | ||
return this; | ||
} | ||
|
||
public Set<Class<? extends Annotation>> getStereotypes() | ||
{ | ||
return stereotypes; | ||
} | ||
|
||
public NarrowingBeanBuilder<T> stereotypes(Set<Class<? extends Annotation>> stereotypes) | ||
{ | ||
this.stereotypes = stereotypes; | ||
return this; | ||
} | ||
|
||
public NarrowingBean<T> create() | ||
{ | ||
return new NarrowingBean<T>(delegate, types, qualifiers, name, scope, alternative, stereotypes); | ||
} | ||
} |