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.increment;
16  
17  import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
18  import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
19  import com.liferay.portal.kernel.concurrent.BatchablePipe;
20  import com.liferay.portal.kernel.increment.BufferedIncrement;
21  import com.liferay.portal.kernel.increment.Increment;
22  import com.liferay.portal.kernel.increment.IncrementFactory;
23  import com.liferay.portal.kernel.messaging.DestinationNames;
24  import com.liferay.portal.kernel.messaging.MessageBusUtil;
25  import com.liferay.portal.kernel.util.MethodTargetClassKey;
26  import com.liferay.portal.kernel.util.StringUtil;
27  import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
28  
29  import java.lang.annotation.Annotation;
30  
31  import org.aopalliance.intercept.MethodInvocation;
32  
33  /**
34   * <a href="BufferedIncrementAdvice.java.html"><b><i>View Source</i></b></a>
35   *
36   * @author Zsolt Berentey
37   * @author Shuyang Zhou
38   */
39  public class BufferedIncrementAdvice
40      extends AnnotationChainableMethodAdvice<BufferedIncrement> {
41  
42      @SuppressWarnings("rawtypes")
43      public Object before(MethodInvocation methodInvocation) throws Throwable {
44          MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(
45              methodInvocation);
46  
47          BufferedIncrement bufferedIncrement = findAnnotation(
48              methodTargetClassKey);
49  
50          if (bufferedIncrement == _nullBufferedIncrement) {
51              return null;
52          }
53  
54          Object[] arguments = methodInvocation.getArguments();
55  
56          Object value = arguments[arguments.length - 1];
57  
58          CacheKeyGenerator cacheKeyGenerator =
59              CacheKeyGeneratorUtil.getCacheKeyGenerator(
60                  BufferedIncrementAdvice.class.getName());
61  
62          cacheKeyGenerator.append(methodTargetClassKey.toString());
63  
64          for (int i = 0; i < arguments.length - 1; i++) {
65              cacheKeyGenerator.append(StringUtil.toHexString(arguments[i]));
66          }
67  
68          String batchKey = cacheKeyGenerator.finish();
69  
70          Increment<?> increment = IncrementFactory.createIncrement(
71              bufferedIncrement.incrementClass(), value);
72  
73          BufferedIncreasableEntry bufferedIncreasableEntry =
74              new BufferedIncreasableEntry(
75                  nextMethodInterceptor, methodInvocation, batchKey, increment);
76  
77          if (_batchablePipe.put(bufferedIncreasableEntry)) {
78              if (bufferedIncrement.parallel()) {
79                  MessageBusUtil.sendMessage(
80                      DestinationNames.BUFFERED_INCREMENT_PARALLEL,
81                      _batchablePipe);
82              }
83              else {
84                  MessageBusUtil.sendMessage(
85                      DestinationNames.BUFFERED_INCREMENT_SERIAL, _batchablePipe);
86              }
87          }
88  
89          return nullResult;
90      }
91  
92      public BufferedIncrement getNullAnnotation() {
93          return _nullBufferedIncrement;
94      }
95  
96      @SuppressWarnings("rawtypes")
97      private static BatchablePipe<String, BufferedIncreasableEntry>
98          _batchablePipe = new BatchablePipe<String, BufferedIncreasableEntry>();
99  
100     private static BufferedIncrement _nullBufferedIncrement =
101         new BufferedIncrement() {
102 
103             public Class<? extends Annotation> annotationType() {
104                 return BufferedIncrement.class;
105             }
106 
107             public Class<? extends Increment<?>> incrementClass() {
108                 return null;
109             }
110 
111             public boolean parallel() {
112                 return true;
113             }
114 
115         };
116 
117 }