package org.infinispan.cdi.common.util; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.enterprise.context.Dependent; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.Default; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.InjectionPoint; import org.infinispan.cdi.common.util.logging.Log; import org.infinispan.commons.logging.LogFactory; /** * <p> * A base class for implementing {@link Bean}. The attributes are immutable, and * collections are defensively copied on instantiation. It uses the defaults * from the specification for properties if not specified. * </p> * <p/> * <p> * This class does not provide any bean lifecycle operations * </p> * * @author Pete Muir * @see ImmutableBean * @see ImmutableNarrowingBean */ public abstract class AbstractImmutableBean<T> implements Bean<T> { private static final Log log = LogFactory.getLog(AbstractImmutableBean.class, Log.class); private final Class<?> beanClass; private final String name; private final Set<Annotation> qualifiers; private final Class<? extends Annotation> scope; private final Set<Class<? extends Annotation>> stereotypes; private final Set<Type> types; private final boolean alternative; private final boolean nullable; private final Set<InjectionPoint> injectionPoints; private final String toString; /** * Create a new, immutable bean. All arguments passed as collections are * defensively copied. * * @param beanClass The Bean class, may not be null * @param name The bean name * @param qualifiers The bean's qualifiers, if null, a singleton set of * {@link Default} is used * @param scope The bean's scope, if null, the default scope of * {@link Dependent} is used * @param stereotypes The bean's stereotypes, if null, an empty set is used * @param types The bean's types, if null, the beanClass and {@link Object} * will be used * @param alternative True if the bean is an alternative * @param nullable True if the bean is nullable * @param injectionPoints the bean's injection points, if null an empty set * is used * @param beanLifecycle Handler for {@link #create(CreationalContext)} and * {@link #destroy(Object, CreationalContext)} * @throws IllegalArgumentException if the beanClass is null */ public AbstractImmutableBean(Class<?> beanClass, String name, Set<Annotation> qualifiers, Class<? extends Annotation> scope, Set<Class<? extends Annotation>> stereotypes, Set<Type> types, boolean alternative, boolean nullable, Set<InjectionPoint> injectionPoints, String toString) { if (beanClass == null) { throw new IllegalArgumentException("beanClass cannot be null"); } this.beanClass = beanClass; this.name = name; if (qualifiers == null) { this.qualifiers = Collections.<Annotation>singleton(DefaultLiteral.INSTANCE); log.trace("No qualifers provided for bean class " + beanClass + ", using singleton set of @Default"); } else { this.qualifiers = new HashSet<Annotation>(qualifiers); } if (scope == null) { this.scope = Dependent.class; log.trace("No scope provided for bean class " + beanClass + ", using @Dependent"); } else { this.scope = scope; } if (stereotypes == null) { this.stereotypes = Collections.emptySet(); } else { this.stereotypes = new HashSet<Class<? extends Annotation>>(stereotypes); } if (types == null) { this.types = Arrays2.<Type>asSet(Object.class, beanClass); log.trace("No types provided for bean class " + beanClass + ", using [java.lang.Object.class, " + beanClass.getName() + ".class]"); } else { this.types = new HashSet<Type>(types); } if (injectionPoints == null) { this.injectionPoints = Collections.emptySet(); } else { this.injectionPoints = new HashSet<InjectionPoint>(injectionPoints); } this.alternative = alternative; this.nullable = nullable; if (toString != null) { this.toString = toString; } else { this.toString = "Custom Bean with bean class " + beanClass + " and qualifiers " + qualifiers; } } @Override public Class<?> getBeanClass() { return beanClass; } @Override public Set<InjectionPoint> getInjectionPoints() { return injectionPoints; } @Override public String getName() { return name; } @Override public Set<Annotation> getQualifiers() { return Collections.unmodifiableSet(qualifiers); } @Override public Class<? extends Annotation> getScope() { return scope; } @Override public Set<Class<? extends Annotation>> getStereotypes() { return Collections.unmodifiableSet(stereotypes); } @Override public Set<Type> getTypes() { return Collections.unmodifiableSet(types); } @Override public boolean isAlternative() { return alternative; } @Override public boolean isNullable() { return nullable; } @Override public String toString() { return toString; } }