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