PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2010, Red Hat Inc., and individual contributors as indicated
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.ejb3.deployment.processors.merging;
  23. import java.lang.reflect.Method;
  24. import java.util.Collection;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.concurrent.ExecutorService;
  28. import java.util.concurrent.Future;
  29. import javax.ejb.Asynchronous;
  30. import org.jboss.as.ee.component.ComponentConfiguration;
  31. import org.jboss.as.ee.component.ComponentConfigurator;
  32. import org.jboss.as.ee.component.ComponentDescription;
  33. import org.jboss.as.ee.component.DependencyConfigurator;
  34. import org.jboss.as.ee.component.EEApplicationClasses;
  35. import org.jboss.as.ee.component.ViewConfiguration;
  36. import org.jboss.as.ee.component.ViewConfigurator;
  37. import org.jboss.as.ee.component.ViewDescription;
  38. import org.jboss.as.ee.component.interceptors.InterceptorOrder;
  39. import org.jboss.as.ee.metadata.MethodAnnotationAggregator;
  40. import org.jboss.as.ee.metadata.RuntimeAnnotationInformation;
  41. import org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory;
  42. import org.jboss.as.ejb3.component.interceptors.AsyncVoidInterceptorFactory;
  43. import org.jboss.as.ejb3.component.EJBViewDescription;
  44. import org.jboss.as.ejb3.component.session.SessionBeanComponentCreateService;
  45. import org.jboss.as.ejb3.component.session.SessionBeanComponentDescription;
  46. import org.jboss.as.ejb3.deployment.processors.dd.MethodResolutionUtils;
  47. import org.jboss.as.server.deployment.DeploymentPhaseContext;
  48. import org.jboss.as.server.deployment.DeploymentUnit;
  49. import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
  50. import org.jboss.as.server.deployment.reflect.ClassReflectionIndexUtil;
  51. import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
  52. import org.jboss.invocation.proxy.MethodIdentifier;
  53. import org.jboss.metadata.ejb.spec.AsyncMethodMetaData;
  54. import org.jboss.metadata.ejb.spec.AsyncMethodsMetaData;
  55. import org.jboss.metadata.ejb.spec.SessionBean31MetaData;
  56. import org.jboss.metadata.ejb.spec.SessionBeanMetaData;
  57. import org.jboss.msc.service.ServiceBuilder;
  58. import org.jboss.msc.service.ServiceName;
  59. import static org.jboss.as.ejb3.EjbMessages.MESSAGES;
  60. /**
  61. * Merging processor that handles EJB async methods, and adds a configurator to configure any that are found.
  62. *
  63. * @author Stuart Douglas
  64. */
  65. public class AsynchronousMergingProcessor extends AbstractMergingProcessor<SessionBeanComponentDescription> {
  66. final ServiceName asynchronousThreadPoolService;
  67. public AsynchronousMergingProcessor(final ServiceName asynchronousThreadPoolService) {
  68. super(SessionBeanComponentDescription.class);
  69. this.asynchronousThreadPoolService = asynchronousThreadPoolService;
  70. }
  71. @Override
  72. protected void handleAnnotations(final DeploymentUnit deploymentUnit, final EEApplicationClasses applicationClasses, final DeploymentReflectionIndex deploymentReflectionIndex, final Class<?> componentClass, final SessionBeanComponentDescription description) throws DeploymentUnitProcessingException {
  73. final RuntimeAnnotationInformation<Boolean> data = MethodAnnotationAggregator.runtimeAnnotationInformation(componentClass, applicationClasses, deploymentReflectionIndex, Asynchronous.class);
  74. for (final Map.Entry<String, List<Boolean>> entry : data.getClassAnnotations().entrySet()) {
  75. if (!entry.getValue().isEmpty()) {
  76. description.addAsynchronousClass(entry.getKey());
  77. }
  78. }
  79. for (final Map.Entry<Method, List<Boolean>> entry : data.getMethodAnnotations().entrySet()) {
  80. if (!entry.getValue().isEmpty()) {
  81. description.addAsynchronousMethod(MethodIdentifier.getIdentifierForMethod(entry.getKey()));
  82. }
  83. }
  84. }
  85. @Override
  86. protected void handleDeploymentDescriptor(final DeploymentUnit deploymentUnit, final DeploymentReflectionIndex deploymentReflectionIndex, final Class<?> componentClass, final SessionBeanComponentDescription description) throws DeploymentUnitProcessingException {
  87. final SessionBeanMetaData data = description.getDescriptorData();
  88. if (data != null) {
  89. if (data instanceof SessionBean31MetaData) {
  90. final SessionBean31MetaData sessionBeanData = (SessionBean31MetaData) data;
  91. final AsyncMethodsMetaData async = sessionBeanData.getAsyncMethods();
  92. if (async != null) {
  93. for (AsyncMethodMetaData method : async) {
  94. final Collection<Method> methods = MethodResolutionUtils.resolveMethods(method.getMethodName(), method.getMethodParams(), componentClass, deploymentReflectionIndex);
  95. for(final Method m : methods ) {
  96. description.addAsynchronousMethod(MethodIdentifier.getIdentifierForMethod(m));
  97. }
  98. }
  99. }
  100. }
  101. }
  102. if (!description.getAsynchronousClasses().isEmpty() ||
  103. !description.getAsynchronousMethods().isEmpty()) {
  104. //setup a dependency on the executor service
  105. description.getConfigurators().add(new ComponentConfigurator() {
  106. @Override
  107. public void configure(final DeploymentPhaseContext context, final ComponentDescription description, final ComponentConfiguration configuration) throws DeploymentUnitProcessingException {
  108. configuration.getCreateDependencies().add(new DependencyConfigurator<SessionBeanComponentCreateService>() {
  109. @Override
  110. public void configureDependency(final ServiceBuilder<?> serviceBuilder, final SessionBeanComponentCreateService service) throws DeploymentUnitProcessingException {
  111. serviceBuilder.addDependency(asynchronousThreadPoolService, ExecutorService.class, service.getAsyncExecutorService());
  112. }
  113. });
  114. }
  115. });
  116. for (final ViewDescription view : description.getViews()) {
  117. final EJBViewDescription ejbView = (EJBViewDescription) view;
  118. ejbView.getConfigurators().add(new ViewConfigurator() {
  119. @Override
  120. public void configure(final DeploymentPhaseContext context, final ComponentConfiguration componentConfiguration, final ViewDescription description, final ViewConfiguration configuration) throws DeploymentUnitProcessingException {
  121. final SessionBeanComponentDescription componentDescription = (SessionBeanComponentDescription) componentConfiguration.getComponentDescription();
  122. for (final Method method : configuration.getProxyFactory().getCachedMethods()) {
  123. //we need the component method to get the correct declaring class
  124. final Method componentMethod = ClassReflectionIndexUtil.findMethod(deploymentReflectionIndex, componentClass, method);
  125. if (componentMethod != null) {
  126. if (componentDescription.getAsynchronousClasses().contains(componentMethod.getDeclaringClass().getName())) {
  127. addAsyncInterceptor(configuration, method);
  128. configuration.addAsyncMethod(method);
  129. } else {
  130. MethodIdentifier id = MethodIdentifier.getIdentifierForMethod(method);
  131. if (componentDescription.getAsynchronousMethods().contains(id)) {
  132. addAsyncInterceptor(configuration, method);
  133. configuration.addAsyncMethod(method);
  134. }
  135. }
  136. }
  137. }
  138. }
  139. });
  140. }
  141. }
  142. }
  143. private static void addAsyncInterceptor(final ViewConfiguration configuration, final Method method) throws DeploymentUnitProcessingException {
  144. if (method.getReturnType().equals(void.class)) {
  145. configuration.addClientInterceptor(method, AsyncVoidInterceptorFactory.INSTANCE, InterceptorOrder.Client.LOCAL_ASYNC_INVOCATION);
  146. } else if (method.getReturnType().equals(Future.class)) {
  147. configuration.addClientInterceptor(method, AsyncFutureInterceptorFactory.INSTANCE, InterceptorOrder.Client.LOCAL_ASYNC_INVOCATION);
  148. } else {
  149. throw MESSAGES.wrongReturnTypeForAsyncMethod(method);
  150. }
  151. }
  152. }