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.
org.jboss.weld.bean.ManagedBean Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.weld.bean;
import static org.jboss.weld.logging.Category.BEAN;
import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
import static org.jboss.weld.logging.messages.BeanMessage.BEAN_MUST_BE_DEPENDENT;
import static org.jboss.weld.logging.messages.BeanMessage.DELEGATE_INJECTION_POINT_NOT_FOUND;
import static org.jboss.weld.logging.messages.BeanMessage.ERROR_DESTROYING;
import static org.jboss.weld.logging.messages.BeanMessage.FINAL_BEAN_CLASS_WITH_DECORATORS_NOT_ALLOWED;
import static org.jboss.weld.logging.messages.BeanMessage.FINAL_BEAN_CLASS_WITH_INTERCEPTORS_NOT_ALLOWED;
import static org.jboss.weld.logging.messages.BeanMessage.NON_CONTAINER_DECORATOR;
import static org.jboss.weld.logging.messages.BeanMessage.PASSIVATING_BEAN_HAS_NON_PASSIVATION_CAPABLE_DECORATOR;
import static org.jboss.weld.logging.messages.BeanMessage.PASSIVATING_BEAN_HAS_NON_PASSIVATION_CAPABLE_INTERCEPTOR;
import static org.jboss.weld.logging.messages.BeanMessage.PASSIVATING_BEAN_NEEDS_SERIALIZABLE_IMPL;
import static org.jboss.weld.logging.messages.BeanMessage.PUBLIC_FIELD_ON_NORMAL_SCOPED_BEAN_NOT_ALLOWED;
import static org.jboss.weld.logging.messages.BeanMessage.SIMPLE_BEAN_AS_NON_STATIC_INNER_CLASS_NOT_ALLOWED;
import static org.jboss.weld.logging.messages.BeanMessage.SPECIALIZING_BEAN_MUST_EXTEND_A_BEAN;
import static org.jboss.weld.util.reflection.Reflections.cast;
import java.util.Set;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyObject;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.PassivationCapable;
import org.jboss.weld.Container;
import org.jboss.weld.bean.interceptor.WeldInterceptorClassMetadata;
import org.jboss.weld.bean.interceptor.WeldInterceptorInstantiator;
import org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler;
import org.jboss.weld.bootstrap.BeanDeployerEnvironment;
import org.jboss.weld.bootstrap.api.ServiceRegistry;
import org.jboss.weld.context.CreationalContextImpl;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.exceptions.DeploymentException;
import org.jboss.weld.exceptions.IllegalStateException;
import org.jboss.weld.injection.CurrentInjectionPoint;
import org.jboss.weld.injection.InjectionContextImpl;
import org.jboss.weld.injection.ProxyClassConstructorInjectionPointWrapper;
import org.jboss.weld.injection.WeldInjectionPoint;
import org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory;
import org.jboss.weld.interceptor.proxy.InterceptorProxyCreatorImpl;
import org.jboss.weld.interceptor.spi.metadata.InterceptorMetadata;
import org.jboss.weld.interceptor.util.InterceptionUtils;
import org.jboss.weld.introspector.WeldClass;
import org.jboss.weld.introspector.WeldField;
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
import org.jboss.weld.util.AnnotatedTypes;
import org.jboss.weld.util.Beans;
import org.jboss.weld.util.BeansClosure;
import org.jboss.weld.util.Proxies;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;
import org.slf4j.cal10n.LocLogger;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLogger.Level;
/**
* Represents a simple bean
*
* @param The type (class) of the bean
* @author Pete Muir
* @author Marius Bogoevici
* @author Ales Justin
* @author Marko Luksa
*/
public class ManagedBean extends AbstractClassBean {
private abstract static class FixInjectionPoint {
private final AbstractClassBean bean;
private InjectionPoint originalInjectionPoint;
private FixInjectionPoint(AbstractClassBean bean) {
this.bean = bean;
}
protected abstract T work();
private void setup() {
if (bean.hasDecorators()) {
Decorator> decorator = bean.getDecorators().get(bean.getDecorators().size() - 1);
InjectionPoint outerDelegateInjectionPoint = Beans.getDelegateInjectionPoint(decorator);
if (outerDelegateInjectionPoint == null) {
throw new IllegalStateException(DELEGATE_INJECTION_POINT_NOT_FOUND, decorator);
}
CurrentInjectionPoint currentInjectionPoint = Container.instance().services().get(CurrentInjectionPoint.class);
if (currentInjectionPoint.peek() != null) {
this.originalInjectionPoint = currentInjectionPoint.pop();
currentInjectionPoint.push(outerDelegateInjectionPoint);
} else {
currentInjectionPoint.push(outerDelegateInjectionPoint);
}
}
}
public InjectionPoint getOriginalInjectionPoint() {
return originalInjectionPoint;
}
private void cleanup() {
if (bean.hasDecorators()) {
final CurrentInjectionPoint currentInjectionPoint = Container.instance().services().get(CurrentInjectionPoint.class);
currentInjectionPoint.pop();
currentInjectionPoint.push(originalInjectionPoint);
}
}
public T run() {
try {
setup();
return work();
} finally {
cleanup();
}
}
}
private static class ManagedBeanInjectionTarget implements InjectionTarget {
private final ManagedBean bean;
private ManagedBeanInjectionTarget(ManagedBean bean) {
this.bean = bean;
}
protected ManagedBean getBean() {
return bean;
}
public void inject(final T instance, final CreationalContext ctx) {
new FixInjectionPoint(bean) {
@Override
protected T work() {
new InjectionContextImpl(bean.getBeanManager(), ManagedBeanInjectionTarget.this, getBean().getWeldAnnotated(), instance) {
public void proceed() {
Beans.injectEEFields(instance, bean.getBeanManager(), bean.ejbInjectionPoints, bean.persistenceContextInjectionPoints, bean.persistenceUnitInjectionPoints, bean.resourceInjectionPoints);
Beans.injectFieldsAndInitializers(instance, ctx, bean.getBeanManager(), bean.getInjectableFields(), bean.getInitializerMethods());
}
}.run();
return null;
}
}.run();
}
public void postConstruct(T instance) {
if (bean.hasInterceptors()) {
InterceptionUtils.executePostConstruct(instance);
} else {
bean.defaultPostConstruct(instance);
}
}
public void preDestroy(T instance) {
if (bean.hasInterceptors()) {
InterceptionUtils.executePredestroy(instance);
} else {
bean.defaultPreDestroy(instance);
}
}
public void dispose(T instance) {
// No-op
}
public Set getInjectionPoints() {
return cast(bean.getWeldInjectionPoints());
}
public T produce(final CreationalContext ctx) {
T instance;
if (!bean.hasDecorators()) {
// This should be safe, but needs verification PLM
// Without this, the chaining of decorators will fail as the
// incomplete instance will be resolved
instance = bean.createInstance(ctx);
// Do not keep dependent instances as incomplete
if (bean.isDependent() == false) {
ctx.push(instance);
}
} else {
instance = new FixInjectionPoint(bean) {
@Override
protected T work() {
// for decorated beans, creation should use the fixed injection point
// thus ensuring that the innermost decorator is provided as InjectionPoint
T undecoratedInstance = bean.createInstance(ctx);
return bean.applyDecorators(undecoratedInstance, ctx, getOriginalInjectionPoint());
}
}.run();
}
if (bean.hasInterceptors()) {
return bean.applyInterceptors(instance, ctx);
} else {
return instance;
}
}
}
// Logger
private static final LocLogger log = loggerFactory().getLogger(BEAN);
private static final XLogger xLog = loggerFactory().getXLogger(BEAN);
// The Java EE style injection points
private Set> ejbInjectionPoints;
private Set> persistenceContextInjectionPoints;
private Set> persistenceUnitInjectionPoints;
private Set> resourceInjectionPoints;
private ManagedBean> specializedBean;
private boolean passivationCapableBean;
private boolean passivationCapableDependency;
private final boolean proxiable;
/**
* Creates a simple, annotation defined Web Bean
*
* @param The type
* @param clazz The class
* @param beanManager the current manager
* @return A Web Bean
*/
public static ManagedBean of(WeldClass clazz, BeanManagerImpl beanManager, ServiceRegistry services) {
if (clazz.isDiscovered()) {
return new ManagedBean(clazz, createSimpleId(ManagedBean.class.getSimpleName(), clazz), beanManager, services);
} else {
return new ManagedBean(clazz, createId(ManagedBean.class.getSimpleName(), clazz), beanManager, services);
}
}
protected static String createSimpleId(String beanType, WeldClass> clazz) {
return new StringBuilder().append(beanType).append(BEAN_ID_SEPARATOR).append(clazz.getBaseType()).toString();
}
/**
* create a more complete id for types that have been added through the SPI
* to prevent duplicate id's
*/
protected static String createId(String beanType, WeldClass> clazz) {
return new StringBuilder().append(beanType).append(BEAN_ID_SEPARATOR).append(AnnotatedTypes.createTypeId(clazz)).toString();
}
/**
* Constructor
*
* @param type The type of the bean
* @param beanManager The Bean manager
*/
protected ManagedBean(WeldClass type, String idSuffix, BeanManagerImpl beanManager, ServiceRegistry services) {
super(type, idSuffix, beanManager, services);
initType();
initTypes();
initQualifiers();
initConstructor();
this.proxiable = Proxies.isTypesProxyable(getTypes());
}
/**
* Creates an instance of the bean
*
* @return The instance
*/
public T create(CreationalContext creationalContext) {
T instance = getInjectionTarget().produce(creationalContext);
getInjectionTarget().inject(instance, creationalContext);
getInjectionTarget().postConstruct(instance);
return instance;
}
/**
* Destroys an instance of the bean
*
* @param instance The instance
*/
public void destroy(T instance, CreationalContext creationalContext) {
try {
getInjectionTarget().preDestroy(instance);
// WELD-1010 hack?
if (creationalContext instanceof CreationalContextImpl) {
((CreationalContextImpl) creationalContext).release(this, instance);
} else {
creationalContext.release();
}
} catch (Exception e) {
log.error(ERROR_DESTROYING, this, instance);
xLog.throwing(Level.DEBUG, e);
}
}
/**
* Initializes the bean and its metadata
*/
@Override
public void initialize(BeanDeployerEnvironment environment) {
if (!isInitialized()) {
checkConstructor();
super.initialize(environment);
initPostConstruct();
initPreDestroy();
initEEInjectionPoints();
initPassivationCapable();
setInjectionTarget(new ManagedBeanInjectionTarget(this));
}
}
protected T createInstance(CreationalContext ctx) {
if (!isSubclassed()) {
return getConstructor().newInstance(beanManager, ctx);
} else {
ProxyClassConstructorInjectionPointWrapper constructorInjectionPointWrapper = new ProxyClassConstructorInjectionPointWrapper(this, constructorForEnhancedSubclass, getConstructor());
return constructorInjectionPointWrapper.newInstance(beanManager, ctx);
}
}
@Override
protected void initAfterInterceptorsAndDecoratorsInitialized() {
super.initAfterInterceptorsAndDecoratorsInitialized();
if (this.passivationCapableBean && hasDecorators() && !allDecoratorsArePassivationCapable()) {
this.passivationCapableBean = false;
}
if (this.passivationCapableBean && hasInterceptors() && !allInterceptorsArePassivationCapable()) {
this.passivationCapableBean = false;
}
}
private boolean allDecoratorsArePassivationCapable() {
return getFirstNonPassivationCapableDecorator() == null;
}
private Decorator> getFirstNonPassivationCapableDecorator() {
for (Decorator> decorator : getDecorators()) {
if (!(PassivationCapable.class.isAssignableFrom(decorator.getClass())) || !((WeldDecorator>) decorator).getWeldAnnotated().isSerializable()) {
return decorator;
}
}
return null;
}
private boolean allInterceptorsArePassivationCapable() {
return getFirstNonPassivationCapableInterceptor() == null;
}
private InterceptorMetadata> getFirstNonPassivationCapableInterceptor() {
for (InterceptorMetadata> interceptorMetadata : getBeanManager().getInterceptorModelRegistry().get(getType()).getAllInterceptors()) {
if (!Reflections.isSerializable(interceptorMetadata.getInterceptorClass().getJavaClass())) {
return interceptorMetadata;
}
}
return null;
}
private void initPassivationCapable() {
this.passivationCapableBean = getWeldAnnotated().isSerializable();
this.passivationCapableDependency = isNormalScoped() || (isDependent() && passivationCapableBean);
}
@Override
public boolean isPassivationCapableBean() {
return passivationCapableBean;
}
@Override
public boolean isPassivationCapableDependency() {
return passivationCapableDependency;
}
private void initEEInjectionPoints() {
this.ejbInjectionPoints = Beans.getEjbInjectionPoints(this, getWeldAnnotated(), getBeanManager());
this.persistenceContextInjectionPoints = Beans.getPersistenceContextInjectionPoints(this, getWeldAnnotated(), getBeanManager());
this.persistenceUnitInjectionPoints = Beans.getPersistenceUnitInjectionPoints(this, getWeldAnnotated(), getBeanManager());
this.resourceInjectionPoints = Beans.getResourceInjectionPoints(this, getWeldAnnotated(), beanManager);
}
/**
* Validates the type
*/
@Override
protected void checkType() {
if (getWeldAnnotated().isAnonymousClass() || (getWeldAnnotated().isMemberClass() && !getWeldAnnotated().isStatic())) {
throw new DefinitionException(SIMPLE_BEAN_AS_NON_STATIC_INNER_CLASS_NOT_ALLOWED, type);
}
if (!isDependent() && getWeldAnnotated().isParameterizedType()) {
throw new DefinitionException(BEAN_MUST_BE_DEPENDENT, type);
}
boolean passivating = beanManager.getServices().get(MetaAnnotationStore.class).getScopeModel(scope).isPassivating();
if (passivating && !isPassivationCapableBean()) {
if (!getWeldAnnotated().isSerializable()) {
throw new DeploymentException(PASSIVATING_BEAN_NEEDS_SERIALIZABLE_IMPL, this);
} else if (hasDecorators() && !allDecoratorsArePassivationCapable()) {
throw new DeploymentException(PASSIVATING_BEAN_HAS_NON_PASSIVATION_CAPABLE_DECORATOR, this, getFirstNonPassivationCapableDecorator());
} else if (hasInterceptors() && !allInterceptorsArePassivationCapable()) {
throw new DeploymentException(PASSIVATING_BEAN_HAS_NON_PASSIVATION_CAPABLE_INTERCEPTOR, this, getFirstNonPassivationCapableInterceptor());
}
}
if (hasDecorators()) {
if (getWeldAnnotated().isFinal()) {
throw new DefinitionException(FINAL_BEAN_CLASS_WITH_DECORATORS_NOT_ALLOWED, this);
}
for (Decorator> decorator : getDecorators()) {
WeldClass> decoratorClass;
if (decorator instanceof DecoratorImpl>) {
DecoratorImpl> decoratorBean = (DecoratorImpl>) decorator;
decoratorClass = decoratorBean.getWeldAnnotated();
} else if (decorator instanceof CustomDecoratorWrapper>) {
decoratorClass = ((CustomDecoratorWrapper>) decorator).getWeldAnnotated();
} else {
throw new IllegalStateException(NON_CONTAINER_DECORATOR, decorator);
}
for (WeldMethod, ?> decoratorMethod : decoratorClass.getWeldMethods()) {
WeldMethod, ?> method = getWeldAnnotated().getWeldMethod(decoratorMethod.getSignature());
if (method != null && !method.isStatic() && !method.isPrivate() && method.isFinal()) {
throw new DefinitionException(FINAL_BEAN_CLASS_WITH_INTERCEPTORS_NOT_ALLOWED, method, decoratorMethod);
}
}
}
}
}
@Override
protected void checkBeanImplementation() {
super.checkBeanImplementation();
if (isNormalScoped()) {
for (WeldField, ?> field : getWeldAnnotated().getWeldFields()) {
if (field.isPublic() && !field.isStatic()) {
throw new DefinitionException(PUBLIC_FIELD_ON_NORMAL_SCOPED_BEAN_NOT_ALLOWED, getWeldAnnotated());
}
}
}
}
@Override
protected void preSpecialize(BeanDeployerEnvironment environment) {
super.preSpecialize(environment);
BeansClosure closure = beanManager.getClosure();
if (closure.isEJB(getWeldAnnotated().getWeldSuperclass())) {
throw new DefinitionException(SPECIALIZING_BEAN_MUST_EXTEND_A_BEAN, this);
}
}
@Override
protected void specialize(BeanDeployerEnvironment environment) {
BeansClosure closure = beanManager.getClosure();
Bean> specializedBean = closure.getClassBean(getWeldAnnotated().getWeldSuperclass());
if (specializedBean == null) {
throw new DefinitionException(SPECIALIZING_BEAN_MUST_EXTEND_A_BEAN, this);
}
if (!(specializedBean instanceof ManagedBean>)) {
throw new DefinitionException(SPECIALIZING_BEAN_MUST_EXTEND_A_BEAN, this);
} else {
this.specializedBean = (ManagedBean>) specializedBean;
}
}
@Override
public ManagedBean> getSpecializedBean() {
return specializedBean;
}
@Override
protected boolean isInterceptionCandidate() {
return !Beans.isInterceptor(getWeldAnnotated()) && !Beans.isDecorator(getWeldAnnotated());
}
protected T applyInterceptors(T instance, final CreationalContext creationalContext) {
try {
WeldInterceptorInstantiator interceptorInstantiator = new WeldInterceptorInstantiator(beanManager, creationalContext);
InterceptorProxyCreatorImpl interceptorProxyCreator = new InterceptorProxyCreatorImpl(interceptorInstantiator, new DefaultInvocationContextFactory(), beanManager.getInterceptorModelRegistry().get(getType()));
MethodHandler methodHandler = interceptorProxyCreator.createSubclassingMethodHandler(null, WeldInterceptorClassMetadata.of(getWeldAnnotated()));
CombinedInterceptorAndDecoratorStackMethodHandler wrapperMethodHandler = (CombinedInterceptorAndDecoratorStackMethodHandler) ((ProxyObject) instance).getHandler();
wrapperMethodHandler.setInterceptorMethodHandler(methodHandler);
} catch (Exception e) {
throw new DeploymentException(e);
}
return instance;
}
@Override
public String toString() {
return "Managed Bean [" + getBeanClass().toString() + "] with qualifiers [" + Formats.formatAnnotations(getQualifiers()) + "]";
}
@Override
public boolean isProxyable() {
return proxiable;
}
@Override
public boolean hasDefaultProducer() {
return getInjectionTarget() instanceof ManagedBean.ManagedBeanInjectionTarget;
}
}