1
14
15 package com.liferay.portal.cache;
16
17 import com.liferay.portal.kernel.cache.Lifecycle;
18 import com.liferay.portal.kernel.cache.ThreadLocalCachable;
19 import com.liferay.portal.kernel.cache.ThreadLocalCache;
20 import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
21 import com.liferay.portal.kernel.util.MethodTargetClassKey;
22 import com.liferay.portal.kernel.util.StringBundler;
23 import com.liferay.portal.kernel.util.StringPool;
24 import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
25
26 import java.lang.annotation.Annotation;
27
28 import org.aopalliance.intercept.MethodInvocation;
29
30
36 public class ThreadLocalCacheAdvice
37 extends AnnotationChainableMethodAdvice<ThreadLocalCachable> {
38
39 public void afterReturning(
40 MethodInvocation methodInvocation, Object result)
41 throws Throwable {
42
43 MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(
44 methodInvocation);
45
46 ThreadLocalCachable threadLocalCachable = findAnnotation(
47 methodTargetClassKey);
48
49 if (threadLocalCachable == _nullThreadLocalCacheable) {
50 return;
51 }
52
53 ThreadLocalCache<Object> threadLocalCache =
54 ThreadLocalCacheManager.getThreadLocalCache(
55 threadLocalCachable.scope(), methodTargetClassKey.toString());
56
57 String cacheKey = _buildCacheKey(methodInvocation.getArguments());
58
59 if (result == null) {
60 threadLocalCache.put(cacheKey, nullResult);
61 }
62 else {
63 threadLocalCache.put(cacheKey, result);
64 }
65 }
66
67 public Object before(MethodInvocation methodInvocation) throws Throwable {
68 MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(
69 methodInvocation);
70
71 ThreadLocalCachable threadLocalCachable = findAnnotation(
72 methodTargetClassKey);
73
74 if (threadLocalCachable == _nullThreadLocalCacheable) {
75 return null;
76 }
77
78 ThreadLocalCache<?> threadLocalCache =
79 ThreadLocalCacheManager.getThreadLocalCache(
80 threadLocalCachable.scope(), methodTargetClassKey.toString());
81
82 String cacheKey = _buildCacheKey(methodInvocation.getArguments());
83
84 Object value = threadLocalCache.get(cacheKey);
85
86 if (value == nullResult) {
87 return null;
88 }
89
90 return value;
91 }
92
93 public Class<ThreadLocalCachable> getAnnotationClass() {
94 return ThreadLocalCachable.class;
95 }
96
97 public ThreadLocalCachable getNullAnnotation() {
98 return _nullThreadLocalCacheable;
99 }
100
101 private String _buildCacheKey(Object[] arguments) {
102 StringBundler sb = new StringBundler(arguments.length * 2 - 1);
103
104 for (int i = 0; i < arguments.length; i++) {
105 sb.append(String.valueOf(arguments[i]));
106
107 if ((i + 1) < arguments.length) {
108 sb.append(StringPool.POUND);
109 }
110 }
111
112 return sb.toString();
113 }
114
115 private static ThreadLocalCachable _nullThreadLocalCacheable =
116 new ThreadLocalCachable() {
117
118 public Class<? extends Annotation> annotationType() {
119 return ThreadLocalCachable.class;
120 }
121
122 public Lifecycle scope() {
123 return null;
124 }
125
126 };
127
128 }