/jboss-as-7.1.1.Final/ejb3/src/main/java/org/jboss/as/ejb3/deployment/processors/merging/AsynchronousMergingProcessor.java
Java | 169 lines | 124 code | 17 blank | 28 comment | 23 complexity | dfdfe38afa52b79094089a8a85ba53ae MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
- /*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
- package org.jboss.as.ejb3.deployment.processors.merging;
- import java.lang.reflect.Method;
- import java.util.Collection;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Future;
- import javax.ejb.Asynchronous;
- import org.jboss.as.ee.component.ComponentConfiguration;
- import org.jboss.as.ee.component.ComponentConfigurator;
- import org.jboss.as.ee.component.ComponentDescription;
- import org.jboss.as.ee.component.DependencyConfigurator;
- import org.jboss.as.ee.component.EEApplicationClasses;
- import org.jboss.as.ee.component.ViewConfiguration;
- import org.jboss.as.ee.component.ViewConfigurator;
- import org.jboss.as.ee.component.ViewDescription;
- import org.jboss.as.ee.component.interceptors.InterceptorOrder;
- import org.jboss.as.ee.metadata.MethodAnnotationAggregator;
- import org.jboss.as.ee.metadata.RuntimeAnnotationInformation;
- import org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory;
- import org.jboss.as.ejb3.component.interceptors.AsyncVoidInterceptorFactory;
- import org.jboss.as.ejb3.component.EJBViewDescription;
- import org.jboss.as.ejb3.component.session.SessionBeanComponentCreateService;
- import org.jboss.as.ejb3.component.session.SessionBeanComponentDescription;
- import org.jboss.as.ejb3.deployment.processors.dd.MethodResolutionUtils;
- 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.proxy.MethodIdentifier;
- import org.jboss.metadata.ejb.spec.AsyncMethodMetaData;
- import org.jboss.metadata.ejb.spec.AsyncMethodsMetaData;
- import org.jboss.metadata.ejb.spec.SessionBean31MetaData;
- import org.jboss.metadata.ejb.spec.SessionBeanMetaData;
- import org.jboss.msc.service.ServiceBuilder;
- import org.jboss.msc.service.ServiceName;
- import static org.jboss.as.ejb3.EjbMessages.MESSAGES;
- /**
- * Merging processor that handles EJB async methods, and adds a configurator to configure any that are found.
- *
- * @author Stuart Douglas
- */
- public class AsynchronousMergingProcessor extends AbstractMergingProcessor<SessionBeanComponentDescription> {
- final ServiceName asynchronousThreadPoolService;
- public AsynchronousMergingProcessor(final ServiceName asynchronousThreadPoolService) {
- super(SessionBeanComponentDescription.class);
- this.asynchronousThreadPoolService = asynchronousThreadPoolService;
- }
- @Override
- protected void handleAnnotations(final DeploymentUnit deploymentUnit, final EEApplicationClasses applicationClasses, final DeploymentReflectionIndex deploymentReflectionIndex, final Class<?> componentClass, final SessionBeanComponentDescription description) throws DeploymentUnitProcessingException {
- final RuntimeAnnotationInformation<Boolean> data = MethodAnnotationAggregator.runtimeAnnotationInformation(componentClass, applicationClasses, deploymentReflectionIndex, Asynchronous.class);
- for (final Map.Entry<String, List<Boolean>> entry : data.getClassAnnotations().entrySet()) {
- if (!entry.getValue().isEmpty()) {
- description.addAsynchronousClass(entry.getKey());
- }
- }
- for (final Map.Entry<Method, List<Boolean>> entry : data.getMethodAnnotations().entrySet()) {
- if (!entry.getValue().isEmpty()) {
- description.addAsynchronousMethod(MethodIdentifier.getIdentifierForMethod(entry.getKey()));
- }
- }
- }
- @Override
- protected void handleDeploymentDescriptor(final DeploymentUnit deploymentUnit, final DeploymentReflectionIndex deploymentReflectionIndex, final Class<?> componentClass, final SessionBeanComponentDescription description) throws DeploymentUnitProcessingException {
- final SessionBeanMetaData data = description.getDescriptorData();
- if (data != null) {
- if (data instanceof SessionBean31MetaData) {
- final SessionBean31MetaData sessionBeanData = (SessionBean31MetaData) data;
- final AsyncMethodsMetaData async = sessionBeanData.getAsyncMethods();
- if (async != null) {
- for (AsyncMethodMetaData method : async) {
- final Collection<Method> methods = MethodResolutionUtils.resolveMethods(method.getMethodName(), method.getMethodParams(), componentClass, deploymentReflectionIndex);
- for(final Method m : methods ) {
- description.addAsynchronousMethod(MethodIdentifier.getIdentifierForMethod(m));
- }
- }
- }
- }
- }
- if (!description.getAsynchronousClasses().isEmpty() ||
- !description.getAsynchronousMethods().isEmpty()) {
- //setup a dependency on the executor service
- description.getConfigurators().add(new ComponentConfigurator() {
- @Override
- public void configure(final DeploymentPhaseContext context, final ComponentDescription description, final ComponentConfiguration configuration) throws DeploymentUnitProcessingException {
- configuration.getCreateDependencies().add(new DependencyConfigurator<SessionBeanComponentCreateService>() {
- @Override
- public void configureDependency(final ServiceBuilder<?> serviceBuilder, final SessionBeanComponentCreateService service) throws DeploymentUnitProcessingException {
- serviceBuilder.addDependency(asynchronousThreadPoolService, ExecutorService.class, service.getAsyncExecutorService());
- }
- });
- }
- });
- for (final ViewDescription view : description.getViews()) {
- final EJBViewDescription ejbView = (EJBViewDescription) view;
- ejbView.getConfigurators().add(new ViewConfigurator() {
- @Override
- public void configure(final DeploymentPhaseContext context, final ComponentConfiguration componentConfiguration, final ViewDescription description, final ViewConfiguration configuration) throws DeploymentUnitProcessingException {
- final SessionBeanComponentDescription componentDescription = (SessionBeanComponentDescription) componentConfiguration.getComponentDescription();
- for (final Method method : configuration.getProxyFactory().getCachedMethods()) {
- //we need the component method to get the correct declaring class
- final Method componentMethod = ClassReflectionIndexUtil.findMethod(deploymentReflectionIndex, componentClass, method);
- if (componentMethod != null) {
- if (componentDescription.getAsynchronousClasses().contains(componentMethod.getDeclaringClass().getName())) {
- addAsyncInterceptor(configuration, method);
- configuration.addAsyncMethod(method);
- } else {
- MethodIdentifier id = MethodIdentifier.getIdentifierForMethod(method);
- if (componentDescription.getAsynchronousMethods().contains(id)) {
- addAsyncInterceptor(configuration, method);
- configuration.addAsyncMethod(method);
- }
- }
- }
- }
- }
- });
- }
- }
- }
- private static void addAsyncInterceptor(final ViewConfiguration configuration, final Method method) throws DeploymentUnitProcessingException {
- if (method.getReturnType().equals(void.class)) {
- configuration.addClientInterceptor(method, AsyncVoidInterceptorFactory.INSTANCE, InterceptorOrder.Client.LOCAL_ASYNC_INVOCATION);
- } else if (method.getReturnType().equals(Future.class)) {
- configuration.addClientInterceptor(method, AsyncFutureInterceptorFactory.INSTANCE, InterceptorOrder.Client.LOCAL_ASYNC_INVOCATION);
- } else {
- throw MESSAGES.wrongReturnTypeForAsyncMethod(method);
- }
- }
- }