001
014
015 package com.liferay.portal.increment;
016
017 import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
018 import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
019 import com.liferay.portal.kernel.increment.BufferedIncrement;
020 import com.liferay.portal.kernel.increment.BufferedIncrementThreadLocal;
021 import com.liferay.portal.kernel.increment.Increment;
022 import com.liferay.portal.kernel.increment.IncrementFactory;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
025
026 import java.io.Serializable;
027
028 import java.lang.annotation.Annotation;
029 import java.lang.reflect.Method;
030
031 import java.util.Map;
032 import java.util.concurrent.ConcurrentHashMap;
033 import java.util.concurrent.ConcurrentMap;
034
035 import org.aopalliance.intercept.MethodInvocation;
036
037
041 public class BufferedIncrementAdvice
042 extends AnnotationChainableMethodAdvice<BufferedIncrement> {
043
044 @Override
045 @SuppressWarnings("rawtypes")
046 public Object before(MethodInvocation methodInvocation) throws Throwable {
047 BufferedIncrement bufferedIncrement = findAnnotation(methodInvocation);
048
049 if (!BufferedIncrementThreadLocal.isEnabled() ||
050 (bufferedIncrement == _nullBufferedIncrement)) {
051
052 return null;
053 }
054
055 String configuration = bufferedIncrement.configuration();
056
057 BufferedIncrementConfiguration bufferedIncrementConfiguration =
058 _bufferedIncrementConfigurations.get(configuration);
059
060 if (bufferedIncrementConfiguration == null) {
061 bufferedIncrementConfiguration = new BufferedIncrementConfiguration(
062 configuration);
063
064 _bufferedIncrementConfigurations.put(
065 configuration, bufferedIncrementConfiguration);
066 }
067
068 if (!bufferedIncrementConfiguration.isEnabled()) {
069 return nullResult;
070 }
071
072 Method method = methodInvocation.getMethod();
073
074 BufferedIncrementProcessor bufferedIncrementProcessor =
075 _bufferedIncrementProcessors.get(method);
076
077 if (bufferedIncrementProcessor == null) {
078 bufferedIncrementProcessor = new BufferedIncrementProcessor(
079 bufferedIncrementConfiguration, method);
080
081 BufferedIncrementProcessor previousBufferedIncrementProcessor =
082 _bufferedIncrementProcessors.putIfAbsent(
083 method, bufferedIncrementProcessor);
084
085 if (previousBufferedIncrementProcessor != null) {
086 bufferedIncrementProcessor = previousBufferedIncrementProcessor;
087 }
088 }
089
090 Object[] arguments = methodInvocation.getArguments();
091
092 Object value = arguments[arguments.length - 1];
093
094 CacheKeyGenerator cacheKeyGenerator =
095 CacheKeyGeneratorUtil.getCacheKeyGenerator(
096 BufferedIncrementAdvice.class.getName());
097
098 for (int i = 0; i < arguments.length - 1; i++) {
099 cacheKeyGenerator.append(StringUtil.toHexString(arguments[i]));
100 }
101
102 Serializable batchKey = cacheKeyGenerator.finish();
103
104 Increment<?> increment = IncrementFactory.createIncrement(
105 bufferedIncrement.incrementClass(), value);
106
107 BufferedIncreasableEntry bufferedIncreasableEntry =
108 new BufferedIncreasableEntry(methodInvocation, batchKey, increment);
109
110 bufferedIncrementProcessor.process(bufferedIncreasableEntry);
111
112 return nullResult;
113 }
114
115 public void destroy() {
116 for (BufferedIncrementProcessor bufferedIncrementProcessor :
117 _bufferedIncrementProcessors.values()) {
118
119 bufferedIncrementProcessor.destroy();
120 }
121 }
122
123 @Override
124 public BufferedIncrement getNullAnnotation() {
125 return _nullBufferedIncrement;
126 }
127
128 private static BufferedIncrement _nullBufferedIncrement =
129 new BufferedIncrement() {
130
131 @Override
132 public Class<? extends Annotation> annotationType() {
133 return BufferedIncrement.class;
134 }
135
136 @Override
137 public String configuration() {
138 return "default";
139 }
140
141 @Override
142 public Class<? extends Increment<?>> incrementClass() {
143 return null;
144 }
145
146 };
147
148 private Map<String, BufferedIncrementConfiguration>
149 _bufferedIncrementConfigurations =
150 new ConcurrentHashMap<String, BufferedIncrementConfiguration>();
151 private ConcurrentMap<Method, BufferedIncrementProcessor>
152 _bufferedIncrementProcessors =
153 new ConcurrentHashMap<Method, BufferedIncrementProcessor>();
154
155 }