Search in sources :

Example 11 with MethodIdentifier

use of org.jboss.invocation.proxy.MethodIdentifier in project wildfly by wildfly.

the class DefaultInterceptorConfigurator method configure.

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 EEApplicationClasses applicationClasses = deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
    final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
    final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
    final boolean metadataComplete = MetadataCompleteMarker.isMetadataComplete(deploymentUnit);
    // Module stuff
    final Deque<InterceptorFactory> instantiators = new ArrayDeque<>();
    final Deque<InterceptorFactory> injectors = new ArrayDeque<>();
    final Deque<InterceptorFactory> uninjectors = new ArrayDeque<>();
    final Deque<InterceptorFactory> destructors = new ArrayDeque<>();
    final Map<String, List<InterceptorFactory>> userAroundInvokesByInterceptorClass = new HashMap<>();
    final Map<String, List<InterceptorFactory>> userAroundConstructsByInterceptorClass = new HashMap<String, List<InterceptorFactory>>();
    final Map<String, List<InterceptorFactory>> userAroundTimeoutsByInterceptorClass;
    final Map<String, List<InterceptorFactory>> userPrePassivatesByInterceptorClass;
    final Map<String, List<InterceptorFactory>> userPostActivatesByInterceptorClass;
    final Map<String, List<InterceptorFactory>> userPostConstructByInterceptorClass = new HashMap<String, List<InterceptorFactory>>();
    final Map<String, List<InterceptorFactory>> userPreDestroyByInterceptorClass = new HashMap<String, List<InterceptorFactory>>();
    final Set<MethodIdentifier> timeoutMethods = description.getTimerMethods();
    if (description.isTimerServiceRequired()) {
        userAroundTimeoutsByInterceptorClass = new HashMap<>();
    } else {
        userAroundTimeoutsByInterceptorClass = null;
    }
    if (description.isPassivationApplicable()) {
        userPrePassivatesByInterceptorClass = new HashMap<>();
        userPostActivatesByInterceptorClass = new HashMap<>();
    } else {
        userPrePassivatesByInterceptorClass = null;
        userPostActivatesByInterceptorClass = null;
    }
    // the actual component creation interceptor
    // this really belongs in DefaultComponentConfigurator, but all the other AroundConstruct chain is assembled here
    final InterceptorFactory instantiator;
    // Primary instance
    final ComponentFactory instanceFactory = configuration.getInstanceFactory();
    if (instanceFactory != null) {
        instantiator = new ImmediateInterceptorFactory(new ComponentInstantiatorInterceptor(instanceFactory, BasicComponentInstance.INSTANCE_KEY, true));
    } else {
        final ClassReflectionIndex componentClassIndex = deploymentReflectionIndex.getClassIndex(configuration.getComponentClass());
        // use the default constructor if no instanceFactory has been set
        final Constructor<?> constructor = componentClassIndex.getConstructor(EMPTY_CLASS_ARRAY);
        if (constructor == null) {
            throw EeLogger.ROOT_LOGGER.defaultConstructorNotFound(configuration.getComponentClass());
        }
        instantiator = new ImmediateInterceptorFactory(new ComponentInstantiatorInterceptor(new ConstructorComponentFactory(constructor), BasicComponentInstance.INSTANCE_KEY, true));
    }
    // all interceptors with lifecycle callbacks, in the correct order
    final List<InterceptorDescription> interceptorWithLifecycleCallbacks = new ArrayList<InterceptorDescription>();
    if (!description.isExcludeDefaultInterceptors()) {
        interceptorWithLifecycleCallbacks.addAll(description.getDefaultInterceptors());
    }
    interceptorWithLifecycleCallbacks.addAll(description.getClassInterceptors());
    for (final InterceptorDescription interceptorDescription : description.getAllInterceptors()) {
        final String interceptorClassName = interceptorDescription.getInterceptorClassName();
        final Class<?> interceptorClass;
        try {
            interceptorClass = ClassLoadingUtils.loadClass(interceptorClassName, module);
        } catch (ClassNotFoundException e) {
            throw EeLogger.ROOT_LOGGER.cannotLoadInterceptor(e, interceptorClassName);
        }
        final InterceptorEnvironment interceptorEnvironment = moduleDescription.getInterceptorEnvironment().get(interceptorClassName);
        if (interceptorEnvironment != null) {
            // if the interceptor has environment config we merge it into the components environment
            description.getBindingConfigurations().addAll(interceptorEnvironment.getBindingConfigurations());
            for (final ResourceInjectionConfiguration injection : interceptorEnvironment.getResourceInjections()) {
                description.addResourceInjection(injection);
            }
        }
        // we store the interceptor instance under the class key
        final Object contextKey = interceptorClass;
        configuration.getInterceptorContextKeys().add(contextKey);
        final ClassReflectionIndex interceptorIndex = deploymentReflectionIndex.getClassIndex(interceptorClass);
        final Constructor<?> constructor = interceptorIndex.getConstructor(EMPTY_CLASS_ARRAY);
        if (constructor == null) {
            throw EeLogger.ROOT_LOGGER.defaultConstructorNotFoundOnComponent(interceptorClassName, configuration.getComponentClass());
        }
        instantiators.addFirst(new ImmediateInterceptorFactory(new ComponentInstantiatorInterceptor(new ConstructorComponentFactory(constructor), contextKey, false)));
        destructors.addLast(new ImmediateInterceptorFactory(new ManagedReferenceReleaseInterceptor(contextKey)));
        final boolean interceptorHasLifecycleCallbacks = interceptorWithLifecycleCallbacks.contains(interceptorDescription);
        new ClassDescriptionTraversal(interceptorClass, applicationClasses) {

            @Override
            public void handle(final Class<?> clazz, EEModuleClassDescription classDescription) throws DeploymentUnitProcessingException {
                mergeInjectionsForClass(clazz, interceptorClass, classDescription, moduleDescription, deploymentReflectionIndex, description, configuration, context, injectors, contextKey, uninjectors, metadataComplete);
                final InterceptorClassDescription interceptorConfig;
                if (classDescription != null && !metadataComplete) {
                    interceptorConfig = InterceptorClassDescription.merge(classDescription.getInterceptorClassDescription(), moduleDescription.getInterceptorClassOverride(clazz.getName()));
                } else {
                    interceptorConfig = InterceptorClassDescription.merge(null, moduleDescription.getInterceptorClassOverride(clazz.getName()));
                }
                // methods, as per interceptors spec
                if (interceptorHasLifecycleCallbacks && !description.isIgnoreLifecycleInterceptors()) {
                    final MethodIdentifier postConstructMethodIdentifier = interceptorConfig.getPostConstruct();
                    handleInterceptorClass(clazz, postConstructMethodIdentifier, userPostConstructByInterceptorClass, true, true);
                    final MethodIdentifier preDestroyMethodIdentifier = interceptorConfig.getPreDestroy();
                    handleInterceptorClass(clazz, preDestroyMethodIdentifier, userPreDestroyByInterceptorClass, true, true);
                    final MethodIdentifier aroundConstructMethodIdentifier = interceptorConfig.getAroundConstruct();
                    handleInterceptorClass(clazz, aroundConstructMethodIdentifier, userAroundConstructsByInterceptorClass, true, true);
                }
                final MethodIdentifier aroundInvokeMethodIdentifier = interceptorConfig.getAroundInvoke();
                handleInterceptorClass(clazz, aroundInvokeMethodIdentifier, userAroundInvokesByInterceptorClass, false, false);
                if (description.isTimerServiceRequired()) {
                    final MethodIdentifier aroundTimeoutMethodIdentifier = interceptorConfig.getAroundTimeout();
                    handleInterceptorClass(clazz, aroundTimeoutMethodIdentifier, userAroundTimeoutsByInterceptorClass, false, false);
                }
                if (description.isPassivationApplicable()) {
                    handleInterceptorClass(clazz, interceptorConfig.getPrePassivate(), userPrePassivatesByInterceptorClass, false, false);
                    handleInterceptorClass(clazz, interceptorConfig.getPostActivate(), userPostActivatesByInterceptorClass, false, false);
                }
            }

            private void handleInterceptorClass(final Class<?> clazz, final MethodIdentifier methodIdentifier, final Map<String, List<InterceptorFactory>> classMap, final boolean changeMethod, final boolean lifecycleMethod) throws DeploymentUnitProcessingException {
                if (methodIdentifier != null) {
                    final Method method = ClassReflectionIndexUtil.findRequiredMethod(deploymentReflectionIndex, clazz, methodIdentifier);
                    if (isNotOverriden(clazz, method, interceptorClass, deploymentReflectionIndex)) {
                        final InterceptorFactory interceptorFactory = new ImmediateInterceptorFactory(new ManagedReferenceLifecycleMethodInterceptor(contextKey, method, changeMethod, lifecycleMethod));
                        List<InterceptorFactory> factories = classMap.get(interceptorClassName);
                        if (factories == null) {
                            classMap.put(interceptorClassName, factories = new ArrayList<InterceptorFactory>());
                        }
                        factories.add(interceptorFactory);
                    }
                }
            }
        }.run();
    }
    final List<InterceptorFactory> userAroundConstruct = new ArrayList<InterceptorFactory>();
    final List<InterceptorFactory> userPostConstruct = new ArrayList<InterceptorFactory>();
    final List<InterceptorFactory> userPreDestroy = new ArrayList<InterceptorFactory>();
    final List<InterceptorFactory> userPrePassivate = new ArrayList<InterceptorFactory>();
    final List<InterceptorFactory> userPostActivate = new ArrayList<InterceptorFactory>();
    // now add the lifecycle interceptors in the correct order
    for (final InterceptorDescription interceptorClass : interceptorWithLifecycleCallbacks) {
        if (userPostConstructByInterceptorClass.containsKey(interceptorClass.getInterceptorClassName())) {
            userPostConstruct.addAll(userPostConstructByInterceptorClass.get(interceptorClass.getInterceptorClassName()));
        }
        if (userAroundConstructsByInterceptorClass.containsKey(interceptorClass.getInterceptorClassName())) {
            userAroundConstruct.addAll(userAroundConstructsByInterceptorClass.get(interceptorClass.getInterceptorClassName()));
        }
        if (userPreDestroyByInterceptorClass.containsKey(interceptorClass.getInterceptorClassName())) {
            userPreDestroy.addAll(userPreDestroyByInterceptorClass.get(interceptorClass.getInterceptorClassName()));
        }
        if (description.isPassivationApplicable()) {
            if (userPrePassivatesByInterceptorClass.containsKey(interceptorClass.getInterceptorClassName())) {
                userPrePassivate.addAll(userPrePassivatesByInterceptorClass.get(interceptorClass.getInterceptorClassName()));
            }
            if (userPostActivatesByInterceptorClass.containsKey(interceptorClass.getInterceptorClassName())) {
                userPostActivate.addAll(userPostActivatesByInterceptorClass.get(interceptorClass.getInterceptorClassName()));
            }
        }
    }
    if (!injectors.isEmpty()) {
        configuration.addPostConstructInterceptors(new ArrayList<>(injectors), InterceptorOrder.ComponentPostConstruct.INTERCEPTOR_RESOURCE_INJECTION_INTERCEPTORS);
    }
    if (!instantiators.isEmpty()) {
        configuration.addPostConstructInterceptors(new ArrayList<>(instantiators), InterceptorOrder.ComponentPostConstruct.INTERCEPTOR_INSTANTIATION_INTERCEPTORS);
    }
    if (!userAroundConstruct.isEmpty()) {
        configuration.addAroundConstructInterceptors(userAroundConstruct, InterceptorOrder.AroundConstruct.INTERCEPTOR_AROUND_CONSTRUCT);
    }
    configuration.addAroundConstructInterceptor(instantiator, InterceptorOrder.AroundConstruct.CONSTRUCT_COMPONENT);
    configuration.addAroundConstructInterceptor(new ImmediateInterceptorFactory(Interceptors.getTerminalInterceptor()), InterceptorOrder.AroundConstruct.TERMINAL_INTERCEPTOR);
    if (!configuration.getAroundConstructInterceptors().isEmpty()) {
        configuration.addPostConstructInterceptor(new AroundConstructInterceptorFactory(Interceptors.getChainedInterceptorFactory(configuration.getAroundConstructInterceptors())), InterceptorOrder.ComponentPostConstruct.AROUND_CONSTRUCT_CHAIN);
    }
    if (!userPostConstruct.isEmpty()) {
        configuration.addPostConstructInterceptors(userPostConstruct, InterceptorOrder.ComponentPostConstruct.INTERCEPTOR_USER_INTERCEPTORS);
    }
    // Apply pre-destroy
    if (!uninjectors.isEmpty()) {
        configuration.addPreDestroyInterceptors(new ArrayList<>(uninjectors), InterceptorOrder.ComponentPreDestroy.INTERCEPTOR_UNINJECTION_INTERCEPTORS);
    }
    if (!destructors.isEmpty()) {
        configuration.addPreDestroyInterceptors(new ArrayList<>(destructors), InterceptorOrder.ComponentPreDestroy.INTERCEPTOR_DESTRUCTION_INTERCEPTORS);
    }
    if (!userPreDestroy.isEmpty()) {
        configuration.addPreDestroyInterceptors(userPreDestroy, InterceptorOrder.ComponentPreDestroy.INTERCEPTOR_USER_INTERCEPTORS);
    }
    if (description.isPassivationApplicable()) {
        if (!userPrePassivate.isEmpty()) {
            configuration.addPrePassivateInterceptors(userPrePassivate, InterceptorOrder.ComponentPassivation.INTERCEPTOR_USER_INTERCEPTORS);
        }
        if (!userPostActivate.isEmpty()) {
            configuration.addPostActivateInterceptors(userPostActivate, InterceptorOrder.ComponentPassivation.INTERCEPTOR_USER_INTERCEPTORS);
        }
    }
    // @AroundInvoke interceptors
    final List<InterceptorDescription> classInterceptors = description.getClassInterceptors();
    final Map<MethodIdentifier, List<InterceptorDescription>> methodInterceptors = description.getMethodInterceptors();
    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
            final MethodIdentifier identifier = MethodIdentifier.getIdentifier(method.getReturnType(), method.getName(), method.getParameterTypes());
            final List<InterceptorFactory> userAroundInvokes = new ArrayList<InterceptorFactory>();
            final List<InterceptorFactory> userAroundTimeouts = new ArrayList<InterceptorFactory>();
            // first add the default interceptors (if not excluded) to the deque
            final boolean requiresTimerChain = description.isTimerServiceRequired() && timeoutMethods.contains(identifier);
            if (!description.isExcludeDefaultInterceptors() && !description.isExcludeDefaultInterceptors(identifier)) {
                for (InterceptorDescription interceptorDescription : description.getDefaultInterceptors()) {
                    String interceptorClassName = interceptorDescription.getInterceptorClassName();
                    List<InterceptorFactory> aroundInvokes = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                    if (aroundInvokes != null) {
                        userAroundInvokes.addAll(aroundInvokes);
                    }
                    if (requiresTimerChain) {
                        List<InterceptorFactory> aroundTimeouts = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                        if (aroundTimeouts != null) {
                            userAroundTimeouts.addAll(aroundTimeouts);
                        }
                    }
                }
            }
            // now add class level interceptors (if not excluded) to the deque
            if (!description.isExcludeClassInterceptors(identifier)) {
                for (InterceptorDescription interceptorDescription : classInterceptors) {
                    String interceptorClassName = interceptorDescription.getInterceptorClassName();
                    List<InterceptorFactory> aroundInvokes = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                    if (aroundInvokes != null) {
                        userAroundInvokes.addAll(aroundInvokes);
                    }
                    if (requiresTimerChain) {
                        List<InterceptorFactory> aroundTimeouts = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                        if (aroundTimeouts != null) {
                            userAroundTimeouts.addAll(aroundTimeouts);
                        }
                    }
                }
            }
            // now add method level interceptors for to the deque so that they are triggered after the class interceptors
            List<InterceptorDescription> methodLevelInterceptors = methodInterceptors.get(identifier);
            if (methodLevelInterceptors != null) {
                for (InterceptorDescription methodLevelInterceptor : methodLevelInterceptors) {
                    String interceptorClassName = methodLevelInterceptor.getInterceptorClassName();
                    List<InterceptorFactory> aroundInvokes = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                    if (aroundInvokes != null) {
                        userAroundInvokes.addAll(aroundInvokes);
                    }
                    if (requiresTimerChain) {
                        List<InterceptorFactory> aroundTimeouts = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                        if (aroundTimeouts != null) {
                            userAroundTimeouts.addAll(aroundTimeouts);
                        }
                    }
                }
            }
            if (requiresTimerChain) {
                configuration.addComponentInterceptor(method, new UserInterceptorFactory(weaved(userAroundInvokes), weaved(userAroundTimeouts)), InterceptorOrder.Component.INTERCEPTOR_USER_INTERCEPTORS);
            } else {
                configuration.addComponentInterceptors(method, userAroundInvokes, InterceptorOrder.Component.INTERCEPTOR_USER_INTERCEPTORS);
            }
        }
    }
}
Also used : DeploymentUnitProcessingException(org.jboss.as.server.deployment.DeploymentUnitProcessingException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) InterceptorClassDescription(org.jboss.as.ee.component.interceptors.InterceptorClassDescription) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) ArrayList(java.util.ArrayList) List(java.util.List) ClassReflectionIndex(org.jboss.as.server.deployment.reflect.ClassReflectionIndex) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) Method(java.lang.reflect.Method) ArrayDeque(java.util.ArrayDeque) InterceptorFactory(org.jboss.invocation.InterceptorFactory) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) Module(org.jboss.modules.Module) DeploymentUnit(org.jboss.as.server.deployment.DeploymentUnit) DeploymentReflectionIndex(org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex)

Example 12 with MethodIdentifier

use of org.jboss.invocation.proxy.MethodIdentifier in project wildfly by wildfly.

the class DefaultComponentConfigurator method configure.

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<InterceptorFactory> injectors = new ArrayDeque<>();
    final Deque<InterceptorFactory> uninjectors = new ArrayDeque<>();
    final Deque<InterceptorFactory> destructors = new ArrayDeque<>();
    final List<InterceptorFactory> componentUserAroundInvoke = new ArrayList<>();
    final List<InterceptorFactory> componentUserAroundTimeout;
    final List<InterceptorFactory> userPostConstruct = new ArrayList<>();
    final List<InterceptorFactory> userPreDestroy = new ArrayList<>();
    final List<InterceptorFactory> componentUserPrePassivate;
    final List<InterceptorFactory> componentUserPostActivate;
    final Set<MethodIdentifier> 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<InterceptorFactory> 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);
            }
        }
    }
}
Also used : DeploymentUnitProcessingException(org.jboss.as.server.deployment.DeploymentUnitProcessingException) ArrayList(java.util.ArrayList) ContextClassLoaderInterceptor(org.jboss.invocation.ContextClassLoaderInterceptor) InterceptorClassDescription(org.jboss.as.ee.component.interceptors.InterceptorClassDescription) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) Method(java.lang.reflect.Method) ArrayDeque(java.util.ArrayDeque) InterceptorFactory(org.jboss.invocation.InterceptorFactory) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) Module(org.jboss.modules.Module) DeploymentUnit(org.jboss.as.server.deployment.DeploymentUnit) DeploymentReflectionIndex(org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex)

Example 13 with MethodIdentifier

use of org.jboss.invocation.proxy.MethodIdentifier in project wildfly by wildfly.

the class ClassAnnotationInformationFactory method createAnnotationInformation.

public Map<String, ClassAnnotationInformation<A, T>> createAnnotationInformation(final CompositeIndex index, final PropertyReplacer propertyReplacer) {
    final List<TargetAnnotation> annotations = new ArrayList<TargetAnnotation>();
    if (multiAnnotationDotName != null) {
        for (AnnotationInstance multiInstance : index.getAnnotations(multiAnnotationDotName)) {
            annotations.addAll(fromMultiAnnotation(multiInstance));
        }
    }
    final List<AnnotationInstance> simpleAnnotations = index.getAnnotations(annotationDotName);
    if (simpleAnnotations != null) {
        for (AnnotationInstance annotation : simpleAnnotations) {
            annotations.add(new TargetAnnotation(annotation, annotation.target()));
        }
    }
    final Map<DotName, List<TargetAnnotation>> classLevel = new HashMap<DotName, List<TargetAnnotation>>();
    final Map<DotName, List<TargetAnnotation>> methodLevel = new HashMap<DotName, List<TargetAnnotation>>();
    final Map<DotName, List<TargetAnnotation>> fieldLevel = new HashMap<DotName, List<TargetAnnotation>>();
    for (TargetAnnotation instance : annotations) {
        final DotName targetClass = getAnnotationClass(instance.target()).name();
        if (instance.target() instanceof ClassInfo) {
            List<TargetAnnotation> data = classLevel.get(targetClass);
            if (data == null)
                classLevel.put(targetClass, data = new ArrayList<TargetAnnotation>(1));
            data.add(instance);
        } else if (instance.target() instanceof MethodInfo) {
            List<TargetAnnotation> data = methodLevel.get(targetClass);
            if (data == null)
                methodLevel.put(targetClass, data = new ArrayList<TargetAnnotation>(1));
            data.add(instance);
        } else if (instance.target() instanceof FieldInfo) {
            List<TargetAnnotation> data = fieldLevel.get(targetClass);
            if (data == null)
                fieldLevel.put(targetClass, data = new ArrayList<TargetAnnotation>(1));
            data.add(instance);
        } else if (instance.target() instanceof MethodParameterInfo) {
        // ignore for now
        } else {
            throw EeLogger.ROOT_LOGGER.unknownAnnotationTargetType(instance.target());
        }
    }
    final Map<String, ClassAnnotationInformation<A, T>> ret = new HashMap<String, ClassAnnotationInformation<A, T>>();
    final Set<DotName> allClasses = new HashSet<DotName>(classLevel.keySet());
    allClasses.addAll(methodLevel.keySet());
    allClasses.addAll(fieldLevel.keySet());
    for (DotName clazz : allClasses) {
        final List<TargetAnnotation> classAnnotations = classLevel.get(clazz);
        final List<T> classData;
        if (classAnnotations == null) {
            classData = Collections.emptyList();
        } else {
            classData = new ArrayList<T>(classAnnotations.size());
            for (TargetAnnotation instance : classAnnotations) {
                classData.add(fromAnnotation(instance.instance(), propertyReplacer));
            }
        }
        final List<TargetAnnotation> fieldAnnotations = fieldLevel.get(clazz);
        final Map<String, List<T>> fieldData;
        // field level annotations
        if (fieldAnnotations == null) {
            fieldData = Collections.emptyMap();
        } else {
            fieldData = new HashMap<String, List<T>>();
            for (TargetAnnotation instance : fieldAnnotations) {
                final String name = ((FieldInfo) instance.target()).name();
                List<T> data = fieldData.get(name);
                if (data == null) {
                    fieldData.put(name, data = new ArrayList<T>(1));
                }
                data.add(fromAnnotation(instance.instance(), propertyReplacer));
            }
        }
        final List<TargetAnnotation> methodAnnotations = methodLevel.get(clazz);
        final Map<MethodIdentifier, List<T>> methodData;
        // method level annotations
        if (methodAnnotations == null) {
            methodData = Collections.emptyMap();
        } else {
            methodData = new HashMap<MethodIdentifier, List<T>>();
            for (TargetAnnotation instance : methodAnnotations) {
                final MethodIdentifier identifier = getMethodIdentifier(instance.target());
                List<T> data = methodData.get(identifier);
                if (data == null) {
                    methodData.put(identifier, data = new ArrayList<T>(1));
                }
                data.add(fromAnnotation(instance.instance(), propertyReplacer));
            }
        }
        ClassAnnotationInformation<A, T> information = new ClassAnnotationInformation<A, T>(annotationType, classData, methodData, fieldData);
        ret.put(clazz.toString(), information);
    }
    return ret;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DotName(org.jboss.jandex.DotName) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) MethodInfo(org.jboss.jandex.MethodInfo) MethodParameterInfo(org.jboss.jandex.MethodParameterInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance) FieldInfo(org.jboss.jandex.FieldInfo) ClassInfo(org.jboss.jandex.ClassInfo)

Example 14 with MethodIdentifier

use of org.jboss.invocation.proxy.MethodIdentifier in project wildfly by wildfly.

the class MethodAnnotationAggregator method runtimeAnnotationInformation.

public static <A extends Annotation, T> RuntimeAnnotationInformation<T> runtimeAnnotationInformation(final Class<?> componentClass, final EEApplicationClasses applicationClasses, final DeploymentReflectionIndex index, final Class<A> annotationType) {
    final HashSet<MethodIdentifier> methodIdentifiers = new HashSet<MethodIdentifier>();
    final Map<Method, List<T>> methods = new HashMap<Method, List<T>>();
    final Map<String, List<T>> classAnnotations = new HashMap<String, List<T>>();
    Class<?> c = componentClass;
    while (c != null && c != Object.class) {
        final ClassReflectionIndex classIndex = index.getClassIndex(c);
        final EEModuleClassDescription description = applicationClasses.getClassByName(c.getName());
        if (description != null) {
            ClassAnnotationInformation<A, T> annotationData = description.getAnnotationInformation(annotationType);
            if (annotationData != null) {
                if (!annotationData.getClassLevelAnnotations().isEmpty()) {
                    classAnnotations.put(c.getName(), annotationData.getClassLevelAnnotations());
                }
                for (Map.Entry<MethodIdentifier, List<T>> entry : annotationData.getMethodLevelAnnotations().entrySet()) {
                    final Method method = classIndex.getMethod(entry.getKey());
                    if (method != null) {
                        // we do not have to worry about private methods being overridden
                        if (Modifier.isPrivate(method.getModifiers()) || !methodIdentifiers.contains(entry.getKey())) {
                            methods.put(method, entry.getValue());
                        }
                    } else {
                        // but if it does, we give some info
                        throw EeLogger.ROOT_LOGGER.cannotResolveMethod(entry.getKey(), c, entry.getValue());
                    }
                }
            }
        }
        // so we can check if a method is overriden
        for (Method method : (Iterable<Method>) classIndex.getMethods()) {
            // we do not have to worry about private methods being overridden
            if (!Modifier.isPrivate(method.getModifiers())) {
                methodIdentifiers.add(MethodIdentifier.getIdentifierForMethod(method));
            }
        }
        c = c.getSuperclass();
    }
    return new RuntimeAnnotationInformation<T>(classAnnotations, methods);
}
Also used : HashMap(java.util.HashMap) ClassReflectionIndex(org.jboss.as.server.deployment.reflect.ClassReflectionIndex) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) Method(java.lang.reflect.Method) List(java.util.List) EEModuleClassDescription(org.jboss.as.ee.component.EEModuleClassDescription) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 15 with MethodIdentifier

use of org.jboss.invocation.proxy.MethodIdentifier in project wildfly by wildfly.

the class EJBContainerInterceptorsViewConfigurator method doConfigure.

private void doConfigure(final DeploymentPhaseContext context, final EJBComponentDescription ejbComponentDescription, final ViewConfiguration viewConfiguration) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = context.getDeploymentUnit();
    final EEApplicationClasses applicationClasses = deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
    final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
    final Map<String, List<InterceptorFactory>> userAroundInvokesByInterceptorClass = new HashMap<String, List<InterceptorFactory>>();
    final Map<String, List<InterceptorFactory>> userAroundTimeoutsByInterceptorClass;
    if (ejbComponentDescription.isTimerServiceRequired()) {
        userAroundTimeoutsByInterceptorClass = new HashMap<String, List<InterceptorFactory>>();
    } else {
        userAroundTimeoutsByInterceptorClass = null;
    }
    // info
    for (final InterceptorDescription interceptorDescription : ejbComponentDescription.getAllContainerInterceptors()) {
        final String interceptorClassName = interceptorDescription.getInterceptorClassName();
        final Class<?> intereptorClass;
        try {
            intereptorClass = ClassLoadingUtils.loadClass(interceptorClassName, module);
        } catch (ClassNotFoundException e) {
            throw EeLogger.ROOT_LOGGER.cannotLoadInterceptor(e, interceptorClassName);
        }
        // run the interceptor class (and its super class hierarchy) through the InterceptorClassDescriptionTraversal so that it can
        // find the relevant @AroundInvoke/@AroundTimeout methods
        final InterceptorClassDescriptionTraversal interceptorClassDescriptionTraversal = new InterceptorClassDescriptionTraversal(intereptorClass, applicationClasses, deploymentUnit, ejbComponentDescription);
        interceptorClassDescriptionTraversal.run();
        // now that the InterceptorClassDescriptionTraversal has done the relevant processing, keep track of the @AroundInvoke and
        // @AroundTimeout methods applicable for this interceptor class, within a map
        final List<InterceptorFactory> aroundInvokeInterceptorFactories = interceptorClassDescriptionTraversal.getAroundInvokeInterceptorFactories();
        if (aroundInvokeInterceptorFactories != null) {
            userAroundInvokesByInterceptorClass.put(interceptorClassName, aroundInvokeInterceptorFactories);
        }
        if (ejbComponentDescription.isTimerServiceRequired()) {
            final List<InterceptorFactory> aroundTimeoutInterceptorFactories = interceptorClassDescriptionTraversal.getAroundTimeoutInterceptorFactories();
            if (aroundTimeoutInterceptorFactories != null) {
                userAroundTimeoutsByInterceptorClass.put(interceptorClassName, aroundTimeoutInterceptorFactories);
            }
        }
    }
    // At this point we have each interceptor class mapped against their corresponding @AroundInvoke/@AroundTimeout InterceptorFactory(s)
    // Let's now iterate over all the methods of the Jakarta Enterprise Beans view and apply the relevant InterceptorFactory(s) to that method
    final List<InterceptorDescription> classLevelContainerInterceptors = ejbComponentDescription.getClassLevelContainerInterceptors();
    final Map<MethodIdentifier, List<InterceptorDescription>> methodLevelContainerInterceptors = ejbComponentDescription.getMethodLevelContainerInterceptors();
    final List<Method> viewMethods = viewConfiguration.getProxyFactory().getCachedMethods();
    for (final Method method : viewMethods) {
        final MethodIdentifier methodIdentifier = MethodIdentifier.getIdentifier(method.getReturnType(), method.getName(), method.getParameterTypes());
        final List<InterceptorFactory> aroundInvokesApplicableForMethod = new ArrayList<InterceptorFactory>();
        final List<InterceptorFactory> aroundTimeoutsApplicableForMethod = new ArrayList<InterceptorFactory>();
        // first add the default interceptors (if not excluded) to the deque
        if (!ejbComponentDescription.isExcludeDefaultContainerInterceptors() && !ejbComponentDescription.isExcludeDefaultContainerInterceptors(methodIdentifier)) {
            for (final InterceptorDescription interceptorDescription : ejbComponentDescription.getDefaultContainerInterceptors()) {
                String interceptorClassName = interceptorDescription.getInterceptorClassName();
                final List<InterceptorFactory> aroundInvokesOnInterceptor = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                if (aroundInvokesOnInterceptor != null) {
                    aroundInvokesApplicableForMethod.addAll(aroundInvokesOnInterceptor);
                }
                if (ejbComponentDescription.isTimerServiceRequired()) {
                    final List<InterceptorFactory> aroundTimeoutsOnInterceptor = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                    if (aroundTimeoutsOnInterceptor != null) {
                        aroundTimeoutsApplicableForMethod.addAll(aroundTimeoutsOnInterceptor);
                    }
                }
            }
        }
        // now add class level interceptors (if not excluded) to the deque
        if (!ejbComponentDescription.isExcludeClassLevelContainerInterceptors(methodIdentifier)) {
            for (final InterceptorDescription interceptorDescription : classLevelContainerInterceptors) {
                String interceptorClassName = interceptorDescription.getInterceptorClassName();
                final List<InterceptorFactory> aroundInvokesOnInterceptor = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                if (aroundInvokesOnInterceptor != null) {
                    aroundInvokesApplicableForMethod.addAll(aroundInvokesOnInterceptor);
                }
                if (ejbComponentDescription.isTimerServiceRequired()) {
                    final List<InterceptorFactory> aroundTimeoutsOnInterceptor = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                    if (aroundTimeoutsOnInterceptor != null) {
                        aroundTimeoutsApplicableForMethod.addAll(aroundTimeoutsOnInterceptor);
                    }
                }
            }
        }
        // now add method level interceptors for to the deque so that they are triggered after the class interceptors
        final List<InterceptorDescription> interceptorsForMethod = methodLevelContainerInterceptors.get(methodIdentifier);
        if (interceptorsForMethod != null) {
            for (final InterceptorDescription methodLevelInterceptor : interceptorsForMethod) {
                String interceptorClassName = methodLevelInterceptor.getInterceptorClassName();
                final List<InterceptorFactory> aroundInvokesOnInterceptor = userAroundInvokesByInterceptorClass.get(interceptorClassName);
                if (aroundInvokesOnInterceptor != null) {
                    aroundInvokesApplicableForMethod.addAll(aroundInvokesOnInterceptor);
                }
                if (ejbComponentDescription.isTimerServiceRequired()) {
                    final List<InterceptorFactory> aroundTimeoutsOnInterceptor = userAroundTimeoutsByInterceptorClass.get(interceptorClassName);
                    if (aroundTimeoutsOnInterceptor != null) {
                        aroundTimeoutsApplicableForMethod.addAll(aroundTimeoutsOnInterceptor);
                    }
                }
            }
        }
        // apply the interceptors to the view's method.
        viewConfiguration.addViewInterceptor(method, new UserInterceptorFactory(weaved(aroundInvokesApplicableForMethod), weaved(aroundTimeoutsApplicableForMethod)), InterceptorOrder.View.USER_APP_SPECIFIC_CONTAINER_INTERCEPTORS);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) Method(java.lang.reflect.Method) InterceptorDescription(org.jboss.as.ee.component.InterceptorDescription) InterceptorFactory(org.jboss.invocation.InterceptorFactory) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) EEApplicationClasses(org.jboss.as.ee.component.EEApplicationClasses) UserInterceptorFactory(org.jboss.as.ee.component.interceptors.UserInterceptorFactory) ArrayList(java.util.ArrayList) List(java.util.List) Module(org.jboss.modules.Module) DeploymentUnit(org.jboss.as.server.deployment.DeploymentUnit)

Aggregations

MethodIdentifier (org.jboss.invocation.proxy.MethodIdentifier)24 Method (java.lang.reflect.Method)17 InterceptorClassDescription (org.jboss.as.ee.component.interceptors.InterceptorClassDescription)9 List (java.util.List)8 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)6 Map (java.util.Map)6 DeploymentUnit (org.jboss.as.server.deployment.DeploymentUnit)6 ClassReflectionIndex (org.jboss.as.server.deployment.reflect.ClassReflectionIndex)5 DeploymentReflectionIndex (org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex)5 HashSet (java.util.HashSet)4 ComponentDescription (org.jboss.as.ee.component.ComponentDescription)4 InterceptorDescription (org.jboss.as.ee.component.InterceptorDescription)4 DeploymentUnitProcessingException (org.jboss.as.server.deployment.DeploymentUnitProcessingException)4 Module (org.jboss.modules.Module)4 EEModuleClassDescription (org.jboss.as.ee.component.EEModuleClassDescription)3 EEModuleDescription (org.jboss.as.ee.component.EEModuleDescription)3 UserInterceptorFactory (org.jboss.as.ee.component.interceptors.UserInterceptorFactory)3 EJBComponentDescription (org.jboss.as.ejb3.component.EJBComponentDescription)3 SessionBeanComponentDescription (org.jboss.as.ejb3.component.session.SessionBeanComponentDescription)3