Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.caucho.config.inject.InjectManager Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.config.inject;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.annotation.sql.DataSourceDefinition;
import javax.annotation.sql.DataSourceDefinitions;
import javax.ejb.EJB;
import javax.ejb.EJBs;
import javax.ejb.Stateful;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.AmbiguousResolutionException;
import javax.enterprise.inject.IllegalProductException;
import javax.enterprise.inject.InjectionException;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Specializes;
import javax.enterprise.inject.Stereotype;
import javax.enterprise.inject.UnsatisfiedResolutionException;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.InterceptionType;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.Producer;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Qualifier;
import javax.inject.Scope;
import javax.interceptor.InterceptorBinding;
import javax.naming.InitialContext;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import com.caucho.config.CauchoDeployment;
import com.caucho.config.ConfigException;
import com.caucho.config.Configured;
import com.caucho.config.ContextDependent;
import com.caucho.config.LineConfigException;
import com.caucho.config.ModulePrivate;
import com.caucho.config.ModulePrivateLiteral;
import com.caucho.config.bytecode.ScopeAdapter;
import com.caucho.config.el.CandiElResolver;
import com.caucho.config.el.CandiExpressionFactory;
import com.caucho.config.event.EventBeanImpl;
import com.caucho.config.event.EventManager;
import com.caucho.config.extension.ExtensionManager;
import com.caucho.config.j2ee.DataSourceDefinitionHandler;
import com.caucho.config.j2ee.EjbHandler;
import com.caucho.config.j2ee.PersistenceContextHandler;
import com.caucho.config.j2ee.PersistenceUnitHandler;
import com.caucho.config.j2ee.ResourceHandler;
import com.caucho.config.program.ConfigProgram;
import com.caucho.config.program.ResourceProgramManager;
import com.caucho.config.reflect.AnnotatedTypeUtil;
import com.caucho.config.reflect.BaseType;
import com.caucho.config.reflect.BaseTypeFactory;
import com.caucho.config.reflect.ReflectionAnnotatedFactory;
import com.caucho.config.scope.ApplicationContext;
import com.caucho.config.scope.DependentContext;
import com.caucho.config.scope.ErrorContext;
import com.caucho.config.scope.SingletonScope;
import com.caucho.config.xml.XmlCookie;
import com.caucho.config.xml.XmlCookieLiteral;
import com.caucho.config.xml.XmlStandardPlugin;
import com.caucho.inject.Module;
import com.caucho.inject.RequestContext;
import com.caucho.loader.DynamicClassLoader;
import com.caucho.loader.Environment;
import com.caucho.loader.EnvironmentApply;
import com.caucho.loader.EnvironmentClassLoader;
import com.caucho.loader.EnvironmentListener;
import com.caucho.loader.EnvironmentLocal;
import com.caucho.util.CurrentTime;
import com.caucho.util.IoUtil;
import com.caucho.util.L10N;
import com.caucho.vfs.Path;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.Vfs;
/**
* The CDI container for a given environment.
*/
@ModulePrivate
@SuppressWarnings("serial")
public final class InjectManager
implements BeanManager, EnvironmentListener,
Serializable, HandleAware
{
private static final L10N L = new L10N(InjectManager.class);
private static final Logger log
= Logger.getLogger(InjectManager.class.getName());
private static final EnvironmentLocal _localContainer
= new EnvironmentLocal();
private static final int DEFAULT_PRIORITY = 1;
private static final Annotation []DEFAULT_ANN
= DefaultLiteral.DEFAULT_ANN_LIST;
private static final String []FORBIDDEN_ANNOTATIONS = {
"javax.persistence.Entity",
/*
"javax.ejb.Stateful",
"javax.ejb.Stateless",
"javax.ejb.Singleton",
"javax.ejb.MessageDriven"
*/
};
private static final String []FORBIDDEN_CLASSES = {
"javax.servlet.Servlet",
"javax.servlet.Filter",
"javax.servlet.ServletContextListener",
"javax.servlet.http.HttpSessionListener",
"javax.servlet.ServletRequestListener",
"javax.ejb.EnterpriseBean",
"javax.faces.component.UIComponent",
"javax.enterprise.inject.spi.Extension",
};
private static final Class extends Annotation> []_forbiddenAnnotations;
private static final Class> []_forbiddenClasses;
private static final ClassLoader _systemClassLoader;
private final String _id;
private final InjectManager _parent;
private EnvironmentClassLoader _classLoader;
private ClassLoader _jndiClassLoader;
private boolean _isChildManager;
private final InjectScanManager _scanManager;
private final ExtensionManager _extensionManager;
private EventManager _eventManager = new EventManager(this);
private AtomicLong _version = new AtomicLong();
private HashMap,Class>> _specializedMap
= new HashMap,Class>>();
private HashMap,Integer> _deploymentMap
= new HashMap,Integer>();
private BaseTypeFactory _baseTypeFactory = new BaseTypeFactory();
private HashMap,InjectionPointHandler> _injectionMap
= new HashMap,InjectionPointHandler>();
private ResourceProgramManager _resourceManager
= new ResourceProgramManager();
//
// self configuration
//
private Map,ArrayList> _selfBeanMap
= new ConcurrentHashMap,ArrayList>();
private Map>> _selfNamedBeanMap
= new ConcurrentHashMap>>();
private HashMap> _selfPassivationBeanMap
= new HashMap>();
//
// combined visibility configuration
//
private HashMap _beanMap
= new HashMap();
private Map>> _namedBeanMap
= new ConcurrentHashMap>>();
private HashMap> _newBeanMap
= new HashMap>();
private HashSet> _qualifierSet
= new HashSet>();
private HashSet> _scopeTypeSet
= new HashSet>();
private HashSet> _normalScopeSet
= new HashSet>();
private HashSet> _passivatingScopeSet
= new HashSet>();
private HashMap, Set> _stereotypeMap
= new HashMap, Set>();
private HashMap,Context> _contextMap
= new HashMap,Context>();
private ArrayList> _interceptorClassList
= new ArrayList>();
private ArrayList> _interceptorList
= new ArrayList>();
private ArrayList> _decoratorClassList
= new ArrayList>();
private ArrayList> _decoratorList
= new ArrayList>();
private HashSet> _beanSet = new HashSet>();
private boolean _isEnableAutoUpdate = true;
private boolean _isUpdateNeeded = true;
private boolean _isAfterValidationNeeded = true;
private Map> _beansXMLOverrides
= new ConcurrentHashMap>();
private ArrayList> _pendingAnnotatedTypes
= new ArrayList>();
private ArrayList> _pendingBindList
= new ArrayList>();
private ArrayList> _pendingValidationBeans
= new ArrayList>();
private ArrayList> _pendingServiceList
= new ArrayList>();
private ArrayList _globalProgram
= new ArrayList();
private Map,ReferenceFactory>> _refFactoryMap
= new ConcurrentHashMap,ReferenceFactory>>();
private Map> _namedRefFactoryMap
= new ConcurrentHashMap>();
private Map _staticMemberMap
= new ConcurrentHashMap();
private ThreadLocal> _proxyThreadLocal
= new ThreadLocal>();
private Map,ManagedBeanImpl>> _transientMap
= new ConcurrentHashMap,ManagedBeanImpl>>();
private Map> _xmlTargetMap
= new ConcurrentHashMap>();
private boolean _isBeforeBeanDiscoveryComplete;
private boolean _isBeforeBeanDiscoverFired;
private boolean _isAfterBeanDiscoveryComplete;
private final AtomicLong _xmlCookieSequence
= new AtomicLong(CurrentTime.getCurrentTime());
// XXX: needs to be a local resolver
private ELResolver _elResolver = new CandiElResolver(this);
private final DependentContext _dependentContext = new DependentContext();
private SingletonScope _singletonScope;
private ApplicationContext _applicationScope;
private final XmlStandardPlugin _xmlExtension;
private RuntimeException _configException;
private Object _serializationHandle;
private InjectManager(String id,
InjectManager parent,
EnvironmentClassLoader loader,
boolean isSetLocal)
{
_id = id;
_classLoader = loader;
_parent = parent;
_extensionManager = new ExtensionManager(this);
_scanManager = new InjectScanManager(this);
_xmlExtension = new XmlStandardPlugin(this);
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(_classLoader);
if (isSetLocal) {
_localContainer.set(this, _classLoader);
if (_parent == null) {
_localContainer.setGlobal(this);
}
}
if (_classLoader != null) {
_classLoader.getNewTempClassLoader();
}
} finally {
thread.setContextClassLoader(oldLoader);
}
}
private void init(boolean isSetLocal)
{
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(_classLoader);
try {
InitialContext ic = new InitialContext();
ic.rebind("java:comp/BeanManager", new WebBeansJndiProxy());
} catch (Throwable e) {
log.log(Level.FINEST, e.toString(), e);
}
_singletonScope = new SingletonScope();
_applicationScope = new ApplicationContext();
addContext(new RequestContext());
addContext("com.caucho.server.webbeans.SessionScopeImpl");
addContext("com.caucho.server.webbeans.ConversationContext");
addContext("com.caucho.server.webbeans.TransactionScope");
addContext(_applicationScope);
addContext(_singletonScope);
addContext(_dependentContext);
initPersistence();
try {
_injectionMap.put(Resource.class,
new ResourceHandler(this));
} catch (Throwable e) {
log.log(Level.FINE, e.toString(), e);
}
_injectionMap.put(EJB.class,
new EjbHandler(this));
_injectionMap.put(EJBs.class,
new EjbHandler(this));
_injectionMap.put(DataSourceDefinition.class,
new DataSourceDefinitionHandler(this));
_injectionMap.put(DataSourceDefinitions.class,
new DataSourceDefinitionHandler(this));
_deploymentMap.put(CauchoDeployment.class, 0);
// DEFAULT_PRIORITY
_deploymentMap.put(Configured.class, 2);
BeanBuilder factory = createBeanFactory(InjectManager.class);
// factory.deployment(Standard.class);
factory.type(InjectManager.class);
factory.type(BeanManager.class);
factory.annotation(ModulePrivateLiteral.create());
addBean(factory.singleton(this));
// ioc/0162
addBean(new InjectionPointStandardBean());
addExtension(_xmlExtension);
_extensionManager.createExtension("com.caucho.server.webbeans.ResinStandardPlugin");
if (_classLoader != null && isSetLocal) {
// _classLoader.addScanListener(this);
_classLoader.addScanListener(_scanManager);
}
Environment.addEnvironmentListener(this, _classLoader);
} finally {
thread.setContextClassLoader(oldLoader);
}
}
private void initPersistence()
{
try {
_injectionMap.put(PersistenceContext.class,
new PersistenceContextHandler(this));
_injectionMap.put(PersistenceUnit.class,
new PersistenceUnitHandler(this));
} catch (Throwable e) {
log.finer("InjectManager: " + e);
log.log(Level.FINEST, e.toString(), e);
}
}
/**
* Returns the modification version.
*/
public long getVersion()
{
return _version.get();
}
public InjectScanManager getScanManager()
{
return _scanManager;
}
public void setIsCustomExtension(boolean isCustom)
{
getScanManager().setIsCustomExtension(isCustom);
}
@Module
public EventManager getEventManager()
{
return _eventManager;
}
@Module
public ExtensionManager getExtensionManager()
{
return _extensionManager;
}
private void addContext(String contextClassName)
{
try {
Class> cl = Class.forName(contextClassName);
Context context = (Context) cl.newInstance();
addContext(context);
} catch (ClassNotFoundException e) {
log.log(Level.FINER, e.toString(), e);
} catch (NoClassDefFoundError e) {
log.log(Level.FINER, e.toString(), e);
} catch (Exception e) {
throw ConfigException.create(e);
}
}
/**
* Returns the local container.
*/
public static InjectManager getCurrent()
{
return getCurrent(Thread.currentThread().getContextClassLoader());
}
/**
* Returns the current environment container.
*/
public static InjectManager getCurrent(ClassLoader loader)
{
return _localContainer.get(loader);
}
/**
* Returns the current active container.
*/
public static InjectManager create()
{
return create(Thread.currentThread().getContextClassLoader());
}
/**
* Returns the current active container.
*/
public static InjectManager create(ClassLoader loader)
{
if (loader == null)
loader = _systemClassLoader;
InjectManager manager = null;
manager = _localContainer.getLevel(loader);
if (manager != null)
return manager;
EnvironmentClassLoader envLoader
= Environment.getEnvironmentClassLoader(loader);
// ejb doesn't create a new InjectManager even though it's a new
// environment
// XXX: yes it does, because of the SessionContext
// ejb/2016 vs ejb/12h0
/*
if (envLoader != null
&& Boolean.FALSE.equals(envLoader.getAttribute("caucho.inject"))) {
manager = create(envLoader.getParent());
if (manager != null)
return manager;
}
*/
String id;
if (envLoader != null)
id = envLoader.getId();
else
id = "";
InjectManager parent = null;
if (envLoader != null && envLoader != _systemClassLoader) {
parent = create(envLoader.getParent());
}
synchronized (_localContainer) {
manager = _localContainer.getLevel(envLoader);
if (manager != null)
return manager;
manager = new InjectManager(id, parent, envLoader, true);
}
manager.init(true);
return manager;
}
/**
* Returns the current active container.
*/
/*
public InjectManager createParent(String prefix)
{
_parent = new InjectManager(prefix + _id,
_parent,
_classLoader,
false);
_parent.init(false);
return _parent;
}
*/
public ClassLoader getClassLoader()
{
return _classLoader;
}
public ClassLoader getJndiClassLoader()
{
return _jndiClassLoader;
}
public boolean isChildManager()
{
return _isChildManager;
}
public void setJndiClassLoader(ClassLoader loader)
{
if (_parent == null)
throw new IllegalStateException();
_isChildManager = true;
_jndiClassLoader = loader;
}
public InjectManager getParent()
{
return _parent;
}
public ApplicationContext getApplicationScope()
{
return _applicationScope;
}
/*
public void setParent(InjectManager parent)
{
_parent = parent;
}
*/
public void addXmlPath(Path path)
{
_isUpdateNeeded = true;
_xmlExtension.addXmlPath(path);
}
public void addBeansXmlOverride(Path path, Path beansXmlPath)
{
if (path == null)
throw new NullPointerException();
List beansXmlPaths = _beansXMLOverrides.get(path);
if (beansXmlPaths == null) {
beansXmlPaths = new ArrayList();
}
beansXmlPaths.add(beansXmlPath);
_beansXMLOverrides.put(path, beansXmlPaths);
}
public List getBeansXmlOverride(Path path)
{
return _beansXMLOverrides.get(path);
}
public void setEnableAutoUpdate(boolean isEnable)
{
_isEnableAutoUpdate = isEnable;
}
public void setDeploymentTypes(ArrayList> deploymentList)
{
_deploymentMap.clear();
_deploymentMap.put(CauchoDeployment.class, 0);
// DEFAULT_PRIORITY
int priority = DEFAULT_PRIORITY + 1;
if (! deploymentList.contains(Configured.class)) {
_deploymentMap.put(Configured.class, priority);
}
for (int i = deploymentList.size() - 1; i >= 0; i--) {
_deploymentMap.put(deploymentList.get(i), priority);
}
}
/**
* Adds the bean to the named bean map.
*/
private void addBeanByName(String name, Bean> bean)
{
ArrayList> beanList = _selfNamedBeanMap.get(name);
if (beanList == null) {
beanList = new ArrayList>();
_selfNamedBeanMap.put(name, beanList);
}
else if (bean.isAlternative()) {
}
else if (_specializedMap.get(bean.getBeanClass()) != null) {
}
else {
// ioc/0n18 vs ioc/0g30
for (Bean> testBean : beanList) {
if (testBean.isAlternative()) {
}
else if (bean.isAlternative()) {
}
else if (bean.getBeanClass().isAnnotationPresent(Specializes.class)
&& testBean.getBeanClass().isAssignableFrom(bean.getBeanClass())) {
}
else if (testBean.getBeanClass().isAnnotationPresent(Specializes.class)
&& bean.getBeanClass().isAssignableFrom(testBean.getBeanClass())) {
}
else if ((bean instanceof AbstractIntrospectedBean>)
&& ((AbstractIntrospectedBean>) bean).getAnnotated().isAnnotationPresent(Specializes.class)) {
// ioc/07a2
}
else if ((testBean instanceof AbstractIntrospectedBean>)
&& ((AbstractIntrospectedBean>) testBean).getAnnotated().isAnnotationPresent(Specializes.class)) {
}
else if (! bean.getName().startsWith(testBean.getName())
&& ! testBean.getName().startsWith(bean.getName())) {
}
else {
throw new ConfigException(L.l("@Named('{0}') is a duplicate name for\n {1}\n {2}",
name, bean, testBean));
}
}
}
beanList.add(bean);
_namedBeanMap.remove(name);
// ioc/0g31
int p = name.indexOf('.');
if (p > 0) {
addBeanByName(name.substring(0, p), bean);
}
}
/**
* Adds a bean by the interface type
*
* @param type the interface type to expose the component
* @param bean the component to register
*/
private void addBeanByType(Type type,
Annotated annotated,
Bean> bean)
{
if (type == null)
return;
BaseType baseType = createSourceBaseType(type);
addBeanByType(baseType, annotated, bean);
}
private void addBeanByType(BaseType type,
Annotated annotated,
Bean> bean)
{
if (type == null)
return;
if (isSpecialized(bean.getBeanClass())) {
return;
}
if (log.isLoggable(Level.FINEST))
log.finest(bean + "(" + type + ") added to " + this);
Class> rawType = type.getRawClass();
ArrayList beanSet = _selfBeanMap.get(rawType);
if (beanSet == null) {
beanSet = new ArrayList();
_selfBeanMap.put(rawType, beanSet);
}
_beanMap.remove(rawType);
TypedBean typedBean = new TypedBean(type, annotated, bean);
if (! beanSet.contains(typedBean)) {
beanSet.add(typedBean);
}
}
/**
* Finds a component by its component name.
*/
protected ArrayList> findByName(String name)
{
// #3334 - shutdown timing issues
Map>> namedBeanMap = _namedBeanMap;
if (namedBeanMap == null)
return null;
ArrayList> beanList = _namedBeanMap.get(name);
if (beanList == null) {
beanList = new ArrayList>();
if (_classLoader != null)
_classLoader.applyVisibleModules(new FillByName(name, beanList));
// ioc/0680
/*
for (int i = beanList.size() - 1; i >= 0; i--) {
if (getDeploymentPriority(beanList.get(i)) < 0) {
beanList.remove(i);
}
}
*/
_namedBeanMap.put(name, beanList);
}
return beanList;
}
private void fillByName(String name, ArrayList> beanList)
{
ArrayList> localBeans = _selfNamedBeanMap.get(name);
if (localBeans != null) {
for (Bean> bean : localBeans) {
/*
if (getDeploymentPriority(bean) < 0)
continue;
*/
// ioc/0g20
if (bean.isAlternative() && ! isEnabled(bean))
continue;
if (_specializedMap.containsKey(bean.getBeanClass()))
continue;
if (! beanList.contains(bean))
beanList.add(bean);
}
}
}
//
// javax.enterprise.context.Conversation
//
public Conversation createConversation()
{
return (Conversation) _contextMap.get(ConversationScoped.class);
}
/**
* Creates an object, but does not register the
* component with webbeans.
*/
public T createTransientObject(Class type)
{
ManagedBeanImpl bean = createCachedManagedBean(type);
validate(bean);
// server/10gn
//return factory.create(new ConfigContext());
InjectionTarget injectionTarget = bean.getInjectionTarget();
CreationalContext env = new OwnerCreationalContext(bean);
T instance = injectionTarget.produce(env);
injectionTarget.inject(instance, env);
// jsp/1o60
injectionTarget.postConstruct(instance);
return instance;
}
/**
* Creates an object, but does not register the
* component with webbeans.
*/
private ManagedBeanImpl createCachedManagedBean(Class type)
{
ManagedBeanImpl bean = (ManagedBeanImpl) _transientMap.get(type);
if (bean == null) {
bean = createManagedBean(type);
validate(bean);
_transientMap.putIfAbsent(type, bean);
bean = (ManagedBeanImpl) _transientMap.get(type);
}
return bean;
}
/**
* Returns a new instance for a class, but does not register the
* component with webbeans.
*/
public BeanBuilder createBeanFactory(ManagedBeanImpl managedBean)
{
return new BeanBuilder(managedBean);
}
/**
* Returns a new instance for a class, but does not register the
* component with webbeans.
*/
public BeanBuilder createBeanFactory(Class type)
{
ManagedBeanImpl managedBean = createManagedBean(type);
if (managedBean != null)
return createBeanFactory(managedBean);
else
return null;
}
/**
* Returns a new instance for a class, but does not register the
* component with CDI.
*/
public BeanBuilder createBeanFactory(AnnotatedType type)
{
return createBeanFactory(createManagedBean(type));
}
public Bean addSingleton(T obj)
{
BeanBuilder builder = createBeanFactory((Class) obj.getClass());
Bean bean = builder.singleton(obj);
addBeanDiscover(bean);
return bean;
}
//
// enabled deployment types, scopes, and qualifiers
//
@Module
public void addScope(Class extends Annotation> scopeType,
boolean isNormal,
boolean isPassivating)
{
if (isPassivating && ! isNormal)
throw new ConfigException(L.l("@{0} must be 'normal' because it's using 'passivating'",
scopeType.getName()));
_scopeTypeSet.add(scopeType);
if (isNormal)
_normalScopeSet.add(scopeType);
if (isPassivating)
_passivatingScopeSet.add(scopeType);
if (isNormal) {
// TCK - force validation of all methods
_scanManager.setIsCustomExtension(true);
}
}
/**
* Tests if an annotation is an enabled scope type
*/
@Override
public boolean isScope(Class extends Annotation> annotationType)
{
return (annotationType.isAnnotationPresent(Scope.class)
|| annotationType.isAnnotationPresent(NormalScope.class)
|| _scopeTypeSet.contains(annotationType));
}
/**
* Tests if an annotation is an enabled scope type
*/
@Override
public boolean isNormalScope(Class extends Annotation> annotationType)
{
return (annotationType.isAnnotationPresent(NormalScope.class)
|| _normalScopeSet.contains(annotationType));
}
/**
* Tests if an annotation is an enabled scope type
*/
@Override
public boolean isPassivatingScope(Class extends Annotation> annotationType)
{
NormalScope scope = annotationType.getAnnotation(NormalScope.class);
if (scope != null)
return scope.passivating();
return _passivatingScopeSet.contains(annotationType);
}
@Module
public void addQualifier(Class extends Annotation> qualifier)
{
_qualifierSet.add(qualifier);
}
/**
* Tests if an annotation is an enabled binding type
*/
@Override
public boolean isQualifier(Class extends Annotation> annotationType)
{
return (annotationType.isAnnotationPresent(Qualifier.class)
|| _qualifierSet.contains(annotationType));
}
/**
* Tests if an annotation is an enabled interceptor binding type
*/
@Override
public boolean isInterceptorBinding(Class extends Annotation> annotationType)
{
return annotationType.isAnnotationPresent(InterceptorBinding.class);
}
/**
* Returns the bindings for an interceptor binding type
*/
@Override
public Set getInterceptorBindingDefinition(Class extends Annotation> bindingType)
{
LinkedHashSet annSet = new LinkedHashSet();
for (Annotation ann : bindingType.getAnnotations()) {
annSet.add(ann);
}
return annSet;
}
@Module
public void addStereotype(Class extends Annotation> annotationType,
Annotation []annotations)
{
LinkedHashSet annSet = new LinkedHashSet();
for (Annotation ann : annotations)
annSet.add(ann);
_stereotypeMap.put(annotationType, annSet);
}
/**
* Tests if an annotation is an enabled stereotype.
*/
@Override
public boolean isStereotype(Class extends Annotation> annotationType)
{
return (annotationType.isAnnotationPresent(Stereotype.class)
|| _stereotypeMap.get(annotationType) != null);
}
/**
* Returns the annotations associated with a stereotype
*/
@Override
public Set getStereotypeDefinition(Class extends Annotation> stereotype)
{
Set mapAnnSet = _stereotypeMap.get(stereotype);
if (mapAnnSet != null)
return mapAnnSet;
if (! stereotype.isAnnotationPresent(Stereotype.class))
return null;
LinkedHashMap, Annotation> annMap
= new LinkedHashMap, Annotation>();
addStereotypeDefinitions(annMap, stereotype);
mapAnnSet = new LinkedHashSet(annMap.values());
_stereotypeMap.put(stereotype, mapAnnSet);
return mapAnnSet;
}
private void addStereotypeDefinitions(Map,Annotation> annMap,
Class extends Annotation> stereotype)
{
for (Annotation ann : stereotype.getAnnotations()) {
if (annMap.get(ann.annotationType()) == null)
annMap.put(ann.annotationType(), ann);
}
for (Annotation ann : stereotype.getAnnotations()) {
Class extends Annotation> annType = ann.annotationType();
if (annType.isAnnotationPresent(Stereotype.class)) {
addStereotypeDefinitions(annMap, annType);
}
}
}
//
// bean resolution and instantiation
//
/**
* Creates a BaseType from a Type used as a target, for example
* an injection point.
*/
public BaseType createTargetBaseType(Type type)
{
return _baseTypeFactory.createForTarget(type);
}
/**
* Creates a BaseType from a Type used as a source, for example a Bean.
*/
public BaseType createSourceBaseType(Type type)
{
return _baseTypeFactory.createForSource(type);
}
/**
* Creates an annotated type.
*/
@Override
public AnnotatedType createAnnotatedType(Class cl)
{
if (cl == null)
throw new NullPointerException();
AnnotatedType annType = ReflectionAnnotatedFactory.introspectType(cl);
// TCK:
// return getExtensionManager().processAnnotatedType(annType);
return annType;
}
/**
* Creates an injection target
*/
@Override
public InjectionTarget createInjectionTarget(AnnotatedType type)
{
InjectionTarget target = new InjectionTargetBuilder(this, type);
// ioc/0p14 - createInjectionTarget doesn't trigger the event, the
// initial scan does
// return getExtensionManager().processInjectionTarget(target, type);
return target;
}
/**
* Creates an injection target
*/
public InjectionTarget discoverInjectionTarget(AnnotatedType type)
{
InjectionTarget target = createInjectionTarget(type);
return getExtensionManager().processInjectionTarget(target, type);
}
/**
* Creates a managed bean.
*/
public InjectionTarget createInjectionTarget(Class type)
{
// ioc/0062 (vs discover)
try {
AnnotatedType annType = ReflectionAnnotatedFactory.introspectType(type);
// special call from servlet, etc.
return createInjectionTarget(annType);
} catch (Exception e) {
throw ConfigException.createConfig(e);
}
}
/**
* Creates a managed bean.
*/
public InjectionTarget discoverInjectionTarget(Class type)
{
fireBeforeBeanDiscovery();
try {
AnnotatedType annType = ReflectionAnnotatedFactory.introspectType(type);
AnnotatedType enhAnnType
= getExtensionManager().processAnnotatedType(annType);
if (enhAnnType != null)
return discoverInjectionTarget(enhAnnType);
else {
// special call from servlet, etc.
return discoverInjectionTarget(annType);
}
} catch (Exception e) {
throw ConfigException.createConfig(e);
}
}
public void addObserver(ObserverMethod observer,
AnnotatedMethod method)
{
_extensionManager.processObserver(observer, method);
getEventManager().addObserver(observer);
}
/**
* Creates a managed bean.
*/
public ManagedBeanImpl createManagedBean(AnnotatedType type)
{
if (type == null)
throw new NullPointerException();
ManagedBeanImpl bean
= new ManagedBeanImpl(this, type, false);
bean.introspect();
return bean;
}
/**
* Creates a managed bean.
*/
public ManagedBeanImpl createManagedBean(Class cl)
{
if (cl == null)
throw new NullPointerException();
AnnotatedType type = createAnnotatedType(cl);
return createManagedBean(type);
}
/**
* Creates a managed bean.
*/
public ManagedBeanImpl discoverManagedBean(Class cl)
{
fireBeforeBeanDiscovery();
if (cl == null)
throw new NullPointerException();
AnnotatedType type = createAnnotatedType(cl);
AnnotatedType extType = getExtensionManager().processAnnotatedType(type);
if (extType != null)
return createManagedBean(extType);
else
return createManagedBean(type);
}
/**
* Processes the discovered bean
*/
public void addBeanDiscover(Bean bean)
{
if (bean == null)
throw new NullPointerException(L.l("null bean passed to addBean"));
addBeanDiscover(bean, (Annotated) null);
}
/**
* Processes the discovered bean
*/
public void addBean(Bean bean)
{
if (bean == null)
throw new NullPointerException(L.l("null bean passed to addBean"));
addBean(bean, (Annotated) null);
}
/**
* Processes the discovered bean
*/
@Module
public void addBeanDiscover(Bean bean, Annotated ann)
{
fireBeforeBeanDiscovery();
if (ann != null) {
}
else if (bean instanceof AbstractBean>) {
ann = ((AbstractBean) bean).getAnnotatedType();
}
else if (bean instanceof InjectionPointStandardBean) {
ann = ((InjectionPointStandardBean) bean).getAnnotated();
}
else if (bean instanceof InterceptorBean) {
ann = ((InterceptorBean)bean).getAnnotatedType();
}
if (bean instanceof ManagedBeanImpl>) {
ManagedBeanImpl managedBean = (ManagedBeanImpl) bean;
bean = getExtensionManager().processManagedBean(managedBean, ann);
}
else if (bean instanceof ProducesMethodBean,?>) {
ProducesMethodBean,T> methodBean = (ProducesMethodBean,T>) bean;
bean = getExtensionManager().processProducerMethod(methodBean);
}
else if (bean instanceof ProducesFieldBean,?>) {
ProducesFieldBean,T> fieldBean = (ProducesFieldBean,T>) bean;
bean = getExtensionManager().processProducerField(fieldBean);
}
else {
bean = getExtensionManager().processBean(bean, ann);
}
addBean(bean, ann);
}
@Module
public void addBean(Bean bean, Annotated ann)
{
addBeanImpl(bean, ann);
}
/**
* Adds a new bean definition to the manager
*/
public void addBean(Bean bean, ProcessBean process)
{
bean = getExtensionManager().processBean(bean, process);
if (bean != null)
addBeanImpl(bean, process.getAnnotated());
}
/**
* Adds a new bean definition to the manager
*/
public synchronized void addBeanImpl(Bean bean, Annotated ann)
{
if (bean == null) {
return;
}
if (_specializedMap.containsKey(bean.getBeanClass())) {
return;
}
if (log.isLoggable(Level.FINER))
log.finer(this + " add bean " + bean);
_isAfterValidationNeeded = true;
_version.incrementAndGet();
if (bean instanceof Interceptor>) {
addInterceptor((Interceptor>) bean);
return;
}
else if (bean instanceof Decorator>) {
addDecorator((Decorator>) bean);
return;
}
// bean = new InjectBean(bean, this);
_beanSet.add(bean);
for (Type type : bean.getTypes()) {
addBeanByType(type, ann, bean);
}
if (bean.getName() != null) {
addBeanByName(bean.getName(), bean);
}
// XXX: required for TCK, although we use lazily
boolean isNullable = bean.isNullable();
if (bean instanceof PassivationCapable) {
PassivationCapable pass = (PassivationCapable) bean;
if (pass.getId() != null)
_selfPassivationBeanMap.put(pass.getId(), bean);
}
// server/1aj1
clearBeanCache();
registerJmx(bean);
}
public ResourceProgramManager getResourceManager()
{
return _resourceManager;
}
private void registerJmx(Bean> bean)
{
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(_classLoader);
/*
WebBeanAdmin admin = new WebBeanAdmin(bean, _beanId);
admin.register();
*/
} finally {
thread.setContextClassLoader(oldLoader);
}
}
void addGlobalProgram(ConfigProgram program)
{
if (program != null) {
if (_isChildManager) {
_parent.addGlobalProgram(program);
}
else {
_globalProgram.add(program);
}
}
}
/**
* Returns the bean definitions matching a given name
*
* @param name the name of the bean to match
*/
@Override
public Set> getBeans(String name)
{
ArrayList> beanList = findByName(name);
if (beanList != null)
return new LinkedHashSet>(beanList);
else
return new LinkedHashSet>();
}
@Module
public AtomicBoolean getStaticMemberBoolean(Member member)
{
AtomicBoolean flag = _staticMemberMap.get(member);
if (flag == null) {
flag = new AtomicBoolean();
_staticMemberMap.putIfAbsent(member, flag);
flag = _staticMemberMap.get(member);
}
return flag;
}
@Module
public ReferenceFactory> getReferenceFactory(String name)
{
// ioc/23n3
update();
ReferenceFactory> refFactory = _namedRefFactoryMap.get(name);
if (refFactory == null) {
Set> beanSet = getBeans(name);
if (beanSet != null && beanSet.size() > 0) {
Bean> bean = resolve(beanSet);
// server/10sx
if (name.equals(bean.getName())) {
refFactory = getReferenceFactory(bean);
// ioc/0301
if (refFactory instanceof DependentReferenceFactoryImpl>)
refFactory = new DependentElReferenceFactoryImpl((ManagedBeanImpl>) bean);
}
}
if (refFactory == null) {
refFactory = new UnresolvedReferenceFactory();
}
_namedRefFactoryMap.put(name, refFactory);
}
return refFactory;
}
/**
* Returns the beans matching a class and annotation set
*
* @param type the bean's class
* @param qualifiers required @Qualifier annotations
*/
@Override
public Set> getBeans(Type type,
Annotation... qualifiers)
{
if (qualifiers != null) {
for (int i = 0; i < qualifiers.length; i++) {
for (int j = i + 1; j < qualifiers.length; j++) {
if (qualifiers[i].annotationType() == qualifiers[j].annotationType())
throw new IllegalArgumentException(L.l("getBeans may not have a duplicate qualifier '{0}'",
qualifiers[i]));
}
}
}
Set> set = resolve(type, qualifiers, null);
if (set != null)
return (Set>) set;
else
return new HashSet>();
}
/**
* Returns the beans matching a class and annotation set
*
* @param type the bean's class
* @param qualifierSet required @Qualifier annotations
*/
private Set> getBeans(Type type,
Set qualifierSet)
{
Annotation []qualifiers = new Annotation[qualifierSet.size()];
qualifierSet.toArray(qualifiers);
return getBeans(type, qualifiers);
}
/**
* Returns the web beans component with a given binding list.
*/
private Set> resolve(Type type,
Annotation []bindings,
InjectionPoint ip)
{
if (type == null)
throw new NullPointerException();
if (bindings == null || bindings.length == 0) {
if (Object.class.equals(type))
return resolveAllBeans();
bindings = DEFAULT_ANN;
}
BaseType baseType = createTargetBaseType(type);
// ioc/024n
/*
if (baseType.isGeneric())
throw new IllegalArgumentException(L.l("'{0}' is an invalid getBeans type because it's generic.",
baseType));
*/
// ioc/02b1
if (baseType.isVariable())
throw new IllegalArgumentException(L.l("'{0}' is an invalid getBeans type because it's a type variable.",
baseType));
return resolveRec(baseType, bindings, ip);
}
/**
* Returns the web beans component with a given binding list.
*/
private Set> resolveRec(BaseType baseType,
Annotation []qualifiers,
InjectionPoint ip)
{
WebComponent component = getWebComponent(baseType);
if (component != null) {
Set> beans = component.resolve(baseType, qualifiers);
if (beans != null && beans.size() > 0) {
if (log.isLoggable(Level.FINEST))
log.finest(this + " bind(" + baseType.getSimpleName()
+ "," + toList(qualifiers) + ") -> " + beans);
return beans;
}
}
if (New.class.equals(qualifiers[0].annotationType())) {
// ioc/0721
New newQualifier = (New) qualifiers[0];
HashSet> set = new HashSet>();
Class> newClass = newQualifier.value();
if (newClass == null || newClass.equals(void.class))
newClass = baseType.getRawClass();
AnnotatedType> ann = ReflectionAnnotatedFactory.introspectType(newClass);
NewBean> newBean = new NewBean(this, baseType.getRawClass(), ann);
newBean.introspect();
if (component != null) {
component.addComponent(baseType, null, newBean);
}
set.add(newBean);
return set;
}
Class> rawType = baseType.getRawClass();
if (Instance.class.equals(rawType)
|| Provider.class.equals(rawType)) {
BaseType []param = baseType.getParameters();
Type beanType;
if (param.length > 0)
beanType = param[0].getRawClass();
else
beanType = Object.class;
HashSet> set = new HashSet>();
set.add(new InstanceBeanImpl(this, beanType, qualifiers, ip));
return set;
}
else if (Event.class.equals(rawType)) {
if (baseType.isGenericRaw())
throw new InjectionException(L.l("Event must have parameters because a non-parameterized Event would observe no events."));
BaseType []param = baseType.getParameters();
Type beanType;
if (param.length > 0)
beanType = param[0].getRawClass();
else
beanType = Object.class;
HashSet qualifierSet = new LinkedHashSet();
for (Annotation ann : qualifiers) {
qualifierSet.add(ann);
}
qualifierSet.add(AnyLiteral.ANY);
HashSet> set = new HashSet>();
set.add(new EventBeanImpl(this, beanType, qualifierSet));
return set;
}
if (_parent != null) {
return _parent.resolveRec(baseType, qualifiers, ip);
}
for (Annotation ann : qualifiers) {
if (! ann.annotationType().isAnnotationPresent(Qualifier.class)) {
throw new IllegalArgumentException(L.l("'{0}' is an invalid binding annotation because it does not have a @Qualifier meta-annotation",
ann));
}
}
if (log.isLoggable(Level.FINEST)) {
log.finest(this + " bind(" + baseType.getSimpleName()
+ "," + toList(qualifiers) + ") -> none");
}
return null;
}
/**
* Returns the web beans component with a given binding list.
*/
public Set> resolveAllByType(Class> type)
{
Annotation []bindings = new Annotation[0];
WebComponent component = getWebComponent(createTargetBaseType(type));
if (component != null) {
Set> beans = component.resolve(type, bindings);
if (log.isLoggable(Level.FINEST))
log.finest(this + " bind(" + getSimpleName(type)
+ "," + toList(bindings) + ") -> " + beans);
if (beans != null && beans.size() > 0)
return beans;
}
if (_parent != null) {
return _parent.resolveAllByType(type);
}
return null;
}
private WebComponent getWebComponent(BaseType baseType)
{
if (_beanMap == null)
return null;
Class> rawClass = baseType.getRawClass();
String className = rawClass.getName();
WebComponent beanSet = _beanMap.get(className);
if (beanSet == null) {
HashSet typedBeans = new HashSet();
if (_classLoader != null) {
FillByType fillByType = new FillByType(baseType, typedBeans, this);
_classLoader.applyVisibleModules(fillByType);
}
beanSet = new WebComponent(this, className);
_beanMap.put(className, beanSet);
for (TypedBean typedBean : typedBeans) {
if (getDeploymentPriority(typedBean.getBean()) < 0) {
continue;
}
_pendingValidationBeans.add(typedBean.getBean());
beanSet.addComponent(typedBean.getType(),
typedBean.getAnnotated(),
typedBean.getBean());
}
}
return beanSet;
}
private void clearBeanCache()
{
_namedRefFactoryMap.clear();
_beanMap.clear();
}
private void fillByType(BaseType baseType,
HashSet beanSet,
InjectManager beanManager)
{
Class> rawClass = baseType.getRawClass();
InjectScanClass scanClass
= _scanManager.getScanClass(rawClass.getName());
if (scanClass != null && ! scanClass.isRegistered()) {
discoverScanClass(scanClass);
processPendingAnnotatedTypes();
}
ArrayList localBeans = _selfBeanMap.get(rawClass);
if (localBeans != null) {
// ioc/0k00, ioc/0400 - XXX: not exactly right. want local beans to have
// priority if type and binding match
/*
if (this == beanManager)
beanSet.clear();
else if (beanSet.size() > 0) {
return;
}
*/
for (TypedBean bean : localBeans) {
if (getDeploymentPriority(bean.getBean()) < 0)
continue;
if (bean.isModulePrivate() && this != beanManager)
continue;
beanSet.add(bean);
}
}
}
//@Override
public Bean getMostSpecializedBean(Bean bean)
{
throw new UnsupportedOperationException();
/*
Bean> special = _specializedMap.get(bean.getBeanClass());
if (special != null)
return (Bean) special;
else
return bean;
*/
}
@Module
public boolean isSpecialized(Class> beanClass)
{
return _specializedMap.get(beanClass) != null;
}
@Override
public Bean extends X> resolve(Set> beans)
{
Bean extends X> bestBean = null;
Bean extends X> secondBean = null;
int bestPriority = -1;
boolean isSpecializes = false;
for (Bean extends X> bean : beans) {
if (_specializedMap.get(bean.getBeanClass()) != null)
continue;
if ((bean instanceof AbstractIntrospectedBean>)
&& ((AbstractIntrospectedBean>) bean).getAnnotated().isAnnotationPresent(Specializes.class)) {
if (! isSpecializes) {
// ioc/07a3
bestPriority = -1;
bestBean = null;
secondBean = null;
isSpecializes = true;
}
}
else if (isSpecializes) {
continue;
}
int priority = getDeploymentPriority(bean);
if (priority < 0) {
// alternatives
}
else if (bestPriority < priority) {
bestBean = bean;
secondBean = null;
bestPriority = priority;
}
else if (bestPriority == priority) {
secondBean = bean;
// TCK: ProducerFieldDefinitionTest
boolean isFirstProduces = (bestBean instanceof ProducesMethodBean,?>
|| bestBean instanceof ProducesFieldBean,?>);
boolean isSecondProduces = (secondBean instanceof ProducesMethodBean,?>
|| secondBean instanceof ProducesFieldBean,?>);
// ioc/02b0
if (isFirstProduces && ! isSecondProduces) {
secondBean = null;
}
else if (isSecondProduces && ! isFirstProduces) {
bestBean = bean;
secondBean = null;
}
}
}
if (secondBean == null)
return bestBean;
else {
throw ambiguousException(beans, bestPriority);
}
}
private void validate(Type type)
{
BaseType baseType = createTargetBaseType(type);
WebComponent comp = getWebComponent(baseType);
}
private void validate(Bean> bean)
{
if (bean.isAlternative() && ! isEnabled(bean))
return;
boolean isPassivating = isPassivatingScope(bean.getScope());
if (bean instanceof InjectEnvironmentBean) {
InjectEnvironmentBean envBean = (InjectEnvironmentBean) bean;
if (envBean.getCdiManager() != this) {
envBean.getCdiManager().validate(bean);
return;
}
}
if (bean instanceof CdiStatefulBean)
isPassivating = true;
if (bean instanceof ManagedBeanImpl
&& ((ManagedBeanImpl) bean).validate()) {
}
for (InjectionPoint ip : bean.getInjectionPoints()) {
ReferenceFactory> factory = validateInjectionPoint(ip);
if (ip.isDelegate() && ! (bean instanceof Decorator))
throw new ConfigException(L.l("'{0}' is an invalid delegate because {1} is not a Decorator.",
ip.getMember().getName(),
bean));
RuntimeException exn = validatePassivation(ip);
if (exn != null && ! factory.isProducer())
throw exn;
}
if (isNormalScope(bean.getScope())) {
validateNormal(bean);
}
}
private RuntimeException validatePassivation(InjectionPoint ip)
{
Bean> bean = ip.getBean();
if (bean == null)
return null;
boolean isPassivating = isPassivatingScope(bean.getScope());
if (bean instanceof CdiStatefulBean
|| bean.getBeanClass().isAnnotationPresent(Stateful.class)) {
isPassivating = true;
}
if (isPassivating && ! ip.isTransient()) {
Class> cl = getRawClass(ip.getType());
Bean> prodBean = resolve(getBeans(ip.getType(), ip.getQualifiers()));
// TCK conflict
if (! cl.isInterface()
&& ! cl.isPrimitive()
&& ! Serializable.class.isAssignableFrom(cl)
&& ! isPassivationCapable(prodBean)) {
RuntimeException exn;
if (isProduct(prodBean))
exn = new IllegalProductException(L.l("'{0}' is an invalid injection point of type {1} because it's not serializable for {2}",
ip.getMember().getName(),
ip.getType(),
bean));
else
exn = new ConfigException(L.l("'{0}.{1}' is an invalid injection point of type {2} ({3}) because it's not serializable for {4}",
bean.getBeanClass().getName(),
ip.getMember().getName(),
ip.getType(),
prodBean,
bean));
return exn;
}
}
return null;
}
private boolean isPassivationCapable(Bean> bean)
{
if (isNormalScope(bean.getScope()))
return true;
// ioc/05e2
if (bean instanceof PassivationCapable
&& ((PassivationCapable) bean).getId() != null) {
return true;
}
return false;
}
private boolean isProduct(Bean> bean)
{
return ((bean instanceof ProducesFieldBean,?>)
|| (bean instanceof ProducesMethodBean,?>));
}
private Class> getRawClass(Type type)
{
if (type instanceof Class>)
return (Class>) type;
BaseType baseType = createSourceBaseType(type);
return baseType.getRawClass();
}
private void validateNormal(Bean> bean)
{
Annotated ann = null;
if (bean instanceof AbstractBean) {
AbstractBean absBean = (AbstractBean) bean;
ann = absBean.getAnnotated();
}
if (ann == null)
return;
Type baseType = ann.getBaseType();
Class> cl = createTargetBaseType(baseType).getRawClass();
if (cl.isInterface())
return;
int modifiers = cl.getModifiers();
if (Modifier.isFinal(modifiers)) {
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because it's a final class, for {2}.",
cl.getSimpleName(), bean.getScope().getSimpleName(),
bean));
}
Constructor> ctor = null;
for (Constructor> ctorPtr : cl.getDeclaredConstructors()) {
if (ctorPtr.getParameterTypes().length > 0
&& ! ctorPtr.isAnnotationPresent(Inject.class)) {
// ioc/05am
continue;
}
if (Modifier.isPrivate(ctorPtr.getModifiers())) {
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because its constructor is private for {2}.",
cl.getSimpleName(), bean.getScope().getSimpleName(),
bean));
}
ctor = ctorPtr;
}
if (ctor == null) {
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because it doesn't have a zero-arg constructor for {2}.",
cl.getName(), bean.getScope().getSimpleName(),
bean));
}
for (Method method : cl.getMethods()) {
if (method.getDeclaringClass() == Object.class)
continue;
if (Modifier.isFinal(method.getModifiers())) {
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because {2} is a final method for {3}.",
cl.getSimpleName(), bean.getScope().getSimpleName(),
method.getName(),
bean));
}
}
for (Field field : cl.getFields()) {
if (Modifier.isStatic(field.getModifiers()))
continue;
if (Modifier.isPublic(field.getModifiers())) {
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because {2} is a public field for {3}.",
cl.getSimpleName(), bean.getScope().getSimpleName(),
field.getName(),
bean));
}
}
for (InjectionPoint ip : bean.getInjectionPoints()) {
if (ip.getType().equals(InjectionPoint.class))
throw new ConfigException(L.l("'{0}' is an invalid @{1} bean because '{2}' injects an InjectionPoint for {3}.",
cl.getSimpleName(), bean.getScope().getSimpleName(),
ip.getMember().getName(),
bean));
}
}
@Override
public void validate(InjectionPoint ij)
{
validateInjectionPoint(ij);
}
public ReferenceFactory> validateInjectionPoint(InjectionPoint ij)
{
try {
if (ij.isDelegate()) {
if (! (ij.getBean() instanceof Decorator>))
throw new ConfigException(L.l("'{0}' is an invalid @Delegate because {1} is not a decorator",
ij.getMember().getName(), ij.getBean()));
}
else {
return getReferenceFactory(ij);
}
} catch (AmbiguousResolutionException e) {
throw new AmbiguousResolutionException(L.l("{0}.{1}: {2}",
ij.getMember().getDeclaringClass().getName(),
ij.getMember().getName(),
e.getMessage()),
e);
} catch (UnsatisfiedResolutionException e) {
throw new UnsatisfiedResolutionException(L.l("{0}.{1}: {2}",
ij.getMember().getDeclaringClass().getName(),
ij.getMember().getName(),
e.getMessage()),
e);
} catch (IllegalProductException e) {
throw new IllegalProductException(L.l("{0}.{1}: {2}",
ij.getMember().getDeclaringClass().getName(),
ij.getMember().getName(),
e.getMessage()),
e);
} catch (Exception e) {
throw new InjectionException(L.l("{0}.{1}: {2}",
ij.getMember().getDeclaringClass().getName(),
ij.getMember().getName(),
e.getMessage()),
e);
}
return null;
}
public int getDeploymentPriority(Bean> bean)
{
int priority = DEFAULT_PRIORITY;
if (bean.isAlternative()) {
priority = -1;
Integer value = getPriority(bean.getBeanClass());
if (value != null)
priority = value;
}
Set> stereotypes = bean.getStereotypes();
if (stereotypes != null) {
for (Class extends Annotation> annType : stereotypes) {
Integer value = _deploymentMap.get(annType);
if (value != null) {
if (priority < value)
priority = value;
}
else if (annType.isAnnotationPresent(Alternative.class)
&& priority == DEFAULT_PRIORITY)
priority = -1;
}
}
if (priority < 0)
return priority;
else if (bean instanceof AbstractBean>) {
// ioc/0213
AbstractBean> absBean = (AbstractBean>) bean;
if (absBean.getBeanManager() == this)
priority += 1000000;
}
else {
priority += 1000000;
}
return priority;
}
private Integer getPriority(Class> cl)
{
Integer value = _deploymentMap.get(cl);
if (value != null)
return value;
else if (_parent != null)
return _parent.getPriority(cl);
else
return null;
}
private Set> resolveAllBeans()
{
LinkedHashSet> beans = new LinkedHashSet>();
for (ArrayList comp : _selfBeanMap.values()) {
for (TypedBean typedBean : comp) {
beans.add(typedBean.getBean());
}
}
return beans;
}
@Override
public CreationalContext createCreationalContext(Contextual bean)
{
return new OwnerCreationalContext(bean);
}
/**
* Convenience-class for Resin.
*/
public T getReference(Class type, Annotation... qualifiers)
{
Set> beans = getBeans(type, qualifiers);
Bean bean = (Bean) resolve(beans);
if (bean == null)
return null;
return getReference(bean);
}
/**
* Convenience for Resin.
*/
public T getReference(Bean bean)
{
ReferenceFactory factory = getReferenceFactory(bean);
if (factory != null)
return factory.create(null, null, null);
else
return null;
}
/**
* Convenience for Resin.
*/
public T findReference(Bean bean)
{
Context context = getContext(bean.getScope());
if (context != null)
return context.get(bean);
else
return null;
}
/**
* Convenience for Resin.
*/
public T getReference(Bean bean, CreationalContextImpl> parentEnv)
{
ReferenceFactory factory = getReferenceFactory(bean);
return factory.create(null, parentEnv, null);
}
/**
* Convenience-class for Resin.
*/
public T getReference(String name)
{
Set> beans = getBeans(name);
Bean bean = (Bean) resolve(beans);
if (bean == null)
return null;
ReferenceFactory factory = getReferenceFactory(bean);
return factory.create(null, null, null);
}
/**
* Convenience-class for Resin.
*/
public T getReference(String name, CreationalContextImpl parentEnv)
{
Set> beans = getBeans(name);
Bean bean = (Bean) resolve(beans);
if (bean == null)
return null;
ReferenceFactory factory = getReferenceFactory(bean);
return factory.create(null, parentEnv, null);
}
/**
* Returns an instance for the given bean. This method will obey
* the scope of the bean, so a singleton will return the single bean.
*
* @param bean the metadata for the bean
*
* @return an instance of the bean obeying scope
*/
@Override
public Object getReference(Bean> bean,
Type type,
CreationalContext> createContext)
{
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(getClassLoader());
ReferenceFactory factory = getReferenceFactory(bean);
if (factory == null) {
throw new IllegalStateException(L.l("{0} is an uninstantiable bean",
bean));
}
if (createContext instanceof CreationalContextImpl>)
return factory.create((CreationalContextImpl) createContext, null, null);
else
return factory.create(null, null, null);
} finally {
thread.setContextClassLoader(oldLoader);
}
}
/**
* Used by ScopeProxy
*/
private T getInstanceForProxy(Bean bean)
{
CreationalContextImpl> oldEnv = _proxyThreadLocal.get();
T value;
if (oldEnv != null) {
value = oldEnv.get(bean);
if (value != null)
return value;
}
try {
CreationalContextImpl env = new OwnerCreationalContext(bean, oldEnv);
_proxyThreadLocal.set(env);
value = bean.create(env);
return value;
} finally {
_proxyThreadLocal.set(oldEnv);
}
}
public ReferenceFactory