org.jboss.as.ee.component.DefaultComponentConfigurator Maven / Gradle / Ivy
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.jboss.as.ee.component;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Set;
import org.jboss.as.ee.component.interceptors.InterceptorClassDescription;
import org.jboss.as.ee.component.interceptors.InterceptorOrder;
import org.jboss.as.ee.component.interceptors.UserInterceptorFactory;
import org.jboss.as.ee.metadata.MetadataCompleteMarker;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.reflect.ClassReflectionIndexUtil;
import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
import org.jboss.invocation.ContextClassLoaderInterceptor;
import org.jboss.invocation.ImmediateInterceptorFactory;
import org.jboss.invocation.InterceptorFactory;
import org.jboss.invocation.Interceptors;
import org.jboss.invocation.proxy.MethodIdentifier;
import org.jboss.modules.Module;
import static org.jboss.as.server.deployment.Attachments.REFLECTION_INDEX;
/**
* @author Stuart Douglas
*/
class DefaultComponentConfigurator extends AbstractComponentConfigurator implements ComponentConfigurator {
public void configure(final DeploymentPhaseContext context, final ComponentDescription description, final ComponentConfiguration configuration) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = context.getDeploymentUnit();
final DeploymentReflectionIndex deploymentReflectionIndex = deploymentUnit.getAttachment(REFLECTION_INDEX);
final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
final EEApplicationClasses applicationClasses = deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
final boolean metadataComplete = MetadataCompleteMarker.isMetadataComplete(deploymentUnit);
// Module stuff
final Deque injectors = new ArrayDeque<>();
final Deque uninjectors = new ArrayDeque<>();
final Deque destructors = new ArrayDeque<>();
final List componentUserAroundInvoke = new ArrayList<>();
final List componentUserAroundTimeout;
final List userPostConstruct = new ArrayList<>();
final List userPreDestroy = new ArrayList<>();
final List componentUserPrePassivate;
final List componentUserPostActivate;
final Set timeoutMethods = description.getTimerMethods();
if (description.isTimerServiceRequired()) {
componentUserAroundTimeout = new ArrayList<>();
} else {
componentUserAroundTimeout = null;
}
if (description.isPassivationApplicable()) {
componentUserPrePassivate = new ArrayList<>();
componentUserPostActivate = new ArrayList<>();
} else {
componentUserPrePassivate = null;
componentUserPostActivate = null;
}
destructors.add(new ImmediateInterceptorFactory(new ManagedReferenceReleaseInterceptor(BasicComponentInstance.INSTANCE_KEY)));
new ClassDescriptionTraversal(configuration.getComponentClass(), applicationClasses) {
@Override
public void handle(Class> clazz, EEModuleClassDescription classDescription) throws DeploymentUnitProcessingException {
mergeInjectionsForClass(clazz, configuration.getComponentClass(), classDescription, moduleDescription, deploymentReflectionIndex, description, configuration, context, injectors, BasicComponentInstance.INSTANCE_KEY, uninjectors, metadataComplete);
}
}.run();
new ClassDescriptionTraversal(configuration.getComponentClass(), applicationClasses) {
@Override
public void handle(final Class> clazz, EEModuleClassDescription classDescription) throws DeploymentUnitProcessingException {
final InterceptorClassDescription interceptorConfig = InterceptorClassDescription.merge(ComponentDescription.mergeInterceptorConfig(clazz, classDescription, description, metadataComplete), moduleDescription.getInterceptorClassOverride(clazz.getName()));
handleClassMethod(clazz, interceptorConfig.getAroundInvoke(), componentUserAroundInvoke, false, false, configuration);
if (description.isTimerServiceRequired()) {
handleClassMethod(clazz, interceptorConfig.getAroundTimeout(), componentUserAroundTimeout, false, false, configuration);
}
if (!description.isIgnoreLifecycleInterceptors()) {
handleClassMethod(clazz, interceptorConfig.getPostConstruct(), userPostConstruct, true, true, configuration);
handleClassMethod(clazz, interceptorConfig.getPreDestroy(), userPreDestroy, true, true, configuration);
if (description.isPassivationApplicable()) {
handleClassMethod(clazz, interceptorConfig.getPrePassivate(), componentUserPrePassivate, false, true, configuration);
handleClassMethod(clazz, interceptorConfig.getPostActivate(), componentUserPostActivate, false, true, configuration);
}
}
}
private void handleClassMethod(final Class> clazz, final MethodIdentifier methodIdentifier, final List interceptors, boolean changeMethod, boolean lifecycleMethod, ComponentConfiguration configuration) throws DeploymentUnitProcessingException {
if (methodIdentifier != null) {
final Method method = ClassReflectionIndexUtil.findRequiredMethod(deploymentReflectionIndex, clazz, methodIdentifier);
if (isNotOverriden(clazz, method, configuration.getComponentClass(), deploymentReflectionIndex)) {
InterceptorFactory interceptorFactory = new ImmediateInterceptorFactory(new ManagedReferenceLifecycleMethodInterceptor(BasicComponentInstance.INSTANCE_KEY, method, changeMethod, lifecycleMethod));
interceptors.add(interceptorFactory);
if(lifecycleMethod) {
configuration.addLifecycleMethod(method);
}
}
}
}
}.run();
final ClassLoader classLoader = module.getClassLoader();
final InterceptorFactory tcclInterceptor = new ImmediateInterceptorFactory(new ContextClassLoaderInterceptor(classLoader));
if (!injectors.isEmpty()) {
configuration.addPostConstructInterceptors(new ArrayList<>(injectors), InterceptorOrder.ComponentPostConstruct.COMPONENT_RESOURCE_INJECTION_INTERCEPTORS);
}
// Apply post-construct
if (!userPostConstruct.isEmpty()) {
configuration.addPostConstructInterceptors(userPostConstruct, InterceptorOrder.ComponentPostConstruct.COMPONENT_USER_INTERCEPTORS);
}
configuration.addPostConstructInterceptor(Interceptors.getTerminalInterceptorFactory(), InterceptorOrder.ComponentPostConstruct.TERMINAL_INTERCEPTOR);
configuration.addPostConstructInterceptor(tcclInterceptor, InterceptorOrder.ComponentPostConstruct.TCCL_INTERCEPTOR);
// Apply pre-destroy
if (!uninjectors.isEmpty()) {
configuration.addPreDestroyInterceptors(new ArrayList<>(uninjectors), InterceptorOrder.ComponentPreDestroy.COMPONENT_UNINJECTION_INTERCEPTORS);
}
if (!destructors.isEmpty()) {
configuration.addPreDestroyInterceptors(new ArrayList<>(destructors), InterceptorOrder.ComponentPreDestroy.COMPONENT_DESTRUCTION_INTERCEPTORS);
}
if (!userPreDestroy.isEmpty()) {
configuration.addPreDestroyInterceptors(userPreDestroy, InterceptorOrder.ComponentPreDestroy.COMPONENT_USER_INTERCEPTORS);
}
configuration.addPreDestroyInterceptor(Interceptors.getTerminalInterceptorFactory(), InterceptorOrder.ComponentPreDestroy.TERMINAL_INTERCEPTOR);
configuration.addPreDestroyInterceptor(tcclInterceptor, InterceptorOrder.ComponentPreDestroy.TCCL_INTERCEPTOR);
if (description.isPassivationApplicable()) {
if (!componentUserPrePassivate.isEmpty()) {
configuration.addPrePassivateInterceptors(componentUserPrePassivate, InterceptorOrder.ComponentPassivation.COMPONENT_USER_INTERCEPTORS);
}
configuration.addPrePassivateInterceptor(Interceptors.getTerminalInterceptorFactory(), InterceptorOrder.ComponentPassivation.TERMINAL_INTERCEPTOR);
configuration.addPrePassivateInterceptor(tcclInterceptor, InterceptorOrder.ComponentPassivation.TCCL_INTERCEPTOR);
if (!componentUserPostActivate.isEmpty()) {
configuration.addPostActivateInterceptors(componentUserPostActivate, InterceptorOrder.ComponentPassivation.COMPONENT_USER_INTERCEPTORS);
}
configuration.addPostActivateInterceptor(Interceptors.getTerminalInterceptorFactory(), InterceptorOrder.ComponentPassivation.TERMINAL_INTERCEPTOR);
configuration.addPostActivateInterceptor(tcclInterceptor, InterceptorOrder.ComponentPassivation.TCCL_INTERCEPTOR);
}
// @AroundInvoke interceptors
if (description.isIntercepted()) {
for (final Method method : configuration.getDefinedComponentMethods()) {
//now add the interceptor that initializes and the interceptor that actually invokes to the end of the interceptor chain
configuration.addComponentInterceptor(method, Interceptors.getInitialInterceptorFactory(), InterceptorOrder.Component.INITIAL_INTERCEPTOR);
configuration.addComponentInterceptor(method, new ImmediateInterceptorFactory(new ManagedReferenceMethodInterceptor(BasicComponentInstance.INSTANCE_KEY, method)), InterceptorOrder.Component.TERMINAL_INTERCEPTOR);
final MethodIdentifier identifier = MethodIdentifier.getIdentifier(method.getReturnType(), method.getName(), method.getParameterTypes());
// first add the default interceptors (if not excluded) to the deque
final boolean requiresTimerChain = description.isTimerServiceRequired() && timeoutMethods.contains(identifier);
if(requiresTimerChain) {
configuration.addComponentInterceptor(method, new UserInterceptorFactory(weaved(componentUserAroundInvoke), weaved(componentUserAroundTimeout)), InterceptorOrder.Component.COMPONENT_USER_INTERCEPTORS);
} else {
configuration.addComponentInterceptors(method, componentUserAroundInvoke, InterceptorOrder.Component.COMPONENT_USER_INTERCEPTORS);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy