1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.messaging.async;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.messaging.MessageBusUtil;
20  import com.liferay.portal.kernel.messaging.async.Async;
21  import com.liferay.portal.kernel.util.MethodTargetClassKey;
22  import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
23  
24  import java.lang.annotation.Annotation;
25  import java.lang.reflect.Method;
26  
27  import java.util.Map;
28  
29  import org.aopalliance.intercept.MethodInvocation;
30  
31  /**
32   * <a href="AsyncAdvice.java.html"><b><i>View Source</i></b></a>
33   *
34   * @author Shuyang Zhou
35   * @author Brian Wing Shun Chan
36   */
37  public class AsyncAdvice extends AnnotationChainableMethodAdvice<Async> {
38  
39      public Object before(final MethodInvocation methodInvocation)
40          throws Throwable {
41  
42          MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(
43              methodInvocation);
44  
45          Async async = findAnnotation(methodTargetClassKey);
46  
47          if (async == _nullAsync) {
48              return null;
49          }
50  
51          Method method = methodTargetClassKey.getMethod();
52  
53          if (method.getReturnType() != void.class) {
54              if (_log.isWarnEnabled()) {
55                  _log.warn(
56                      "Async annotation on method " + method.getName() +
57                          " does not return void");
58              }
59  
60              return null;
61          }
62  
63          String destinationName = null;
64  
65          if ((_destinationNames != null) && !_destinationNames.isEmpty()) {
66              destinationName = _destinationNames.get(
67                  methodTargetClassKey.getTargetClass());
68          }
69  
70          if (destinationName == null) {
71              destinationName = _defaultDestinationName;
72          }
73  
74          MessageBusUtil.sendMessage(
75              destinationName,
76              new Runnable() {
77  
78                  public void run() {
79                      try {
80                          nextMethodInterceptor.invoke(methodInvocation);
81                      }
82                      catch (Throwable t) {
83                          throw new RuntimeException(t);
84                      }
85                  }
86  
87                  public String toString() {
88                      return methodInvocation.toString();
89                  }
90  
91              });
92  
93          return nullResult;
94      }
95  
96      public String getDefaultDestinationName() {
97          return _defaultDestinationName;
98      }
99  
100     public Async getNullAnnotation() {
101         return _nullAsync;
102     }
103 
104     public void setDefaultDestinationName(String defaultDestinationName) {
105         _defaultDestinationName = defaultDestinationName;
106     }
107 
108     public void setDestinationNames(Map<Class<?>, String> destinationNames) {
109         _destinationNames = destinationNames;
110     }
111 
112     private static Async _nullAsync =
113         new Async() {
114 
115             public Class<? extends Annotation> annotationType() {
116                 return Async.class;
117             }
118 
119         };
120 
121     private static Log _log = LogFactoryUtil.getLog(AsyncAdvice.class);
122 
123     private String _defaultDestinationName;
124     private Map<Class<?>, String> _destinationNames;
125 
126 }