001
014
015 package com.liferay.portal.kernel.cache.thread.local;
016
017 import com.liferay.portal.kernel.transaction.NewTransactionLifecycleListener;
018 import com.liferay.portal.kernel.transaction.TransactionAttribute;
019 import com.liferay.portal.kernel.transaction.TransactionLifecycleListener;
020 import com.liferay.portal.kernel.transaction.TransactionStatus;
021 import com.liferay.portal.kernel.util.InitialThreadLocal;
022
023 import java.io.Serializable;
024
025 import java.util.EnumMap;
026 import java.util.HashMap;
027 import java.util.Map;
028
029
032 public class ThreadLocalCacheManager {
033
034 public static final TransactionLifecycleListener
035 TRANSACTION_LIFECYCLE_LISTENER = new NewTransactionLifecycleListener() {
036
037 @Override
038 protected void doCommitted(
039 TransactionAttribute transactionAttribute,
040 TransactionStatus transactionStatus) {
041
042 if (!transactionAttribute.isReadOnly()) {
043 enable(Lifecycle.REQUEST);
044 }
045 }
046
047 @Override
048 protected void doCreated(
049 TransactionAttribute transactionAttribute,
050 TransactionStatus transactionStatus) {
051
052 if (!transactionAttribute.isReadOnly()) {
053 disable(Lifecycle.REQUEST);
054 }
055 }
056
057 @Override
058 protected void doRollbacked(
059 TransactionAttribute transactionAttribute,
060 TransactionStatus transactionStatus, Throwable throwable) {
061
062 if (!transactionAttribute.isReadOnly()) {
063 enable(Lifecycle.REQUEST);
064 }
065 }
066
067 };
068
069 public static void clearAll(Lifecycle lifecycle) {
070 Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>
071 threadLocalCacheMaps = _threadLocalCacheMaps.get();
072
073 Map<Serializable, ThreadLocalCache<?>> threadLocalCacheMap =
074 threadLocalCacheMaps.get(lifecycle);
075
076 if (threadLocalCacheMap != null) {
077 threadLocalCacheMap.clear();
078 }
079 }
080
081 public static void destroy() {
082 _threadLocalCacheMaps.remove();
083 }
084
085 public static void disable(Lifecycle lifecycle) {
086 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
087 _threadLocalCacheDisabledFlags.get();
088
089 threadLocalCacheDisabledFlags.put(lifecycle, Boolean.TRUE);
090
091 clearAll(lifecycle);
092 }
093
094 public static void enable(Lifecycle lifecycle) {
095 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
096 _threadLocalCacheDisabledFlags.get();
097
098 threadLocalCacheDisabledFlags.remove(lifecycle);
099 }
100
101 public static <T> ThreadLocalCache<T> getThreadLocalCache(
102 Lifecycle lifecycle, Serializable name) {
103
104 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
105 _threadLocalCacheDisabledFlags.get();
106
107 if (threadLocalCacheDisabledFlags.get(lifecycle) == Boolean.TRUE) {
108 return (ThreadLocalCache<T>)_emptyThreadLocalCache;
109 }
110
111 Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>
112 threadLocalCacheMaps = _threadLocalCacheMaps.get();
113
114 Map<Serializable, ThreadLocalCache<?>> threadLocalCacheMap =
115 threadLocalCacheMaps.get(lifecycle);
116
117 if (threadLocalCacheMap == null) {
118 threadLocalCacheMap = new HashMap<>();
119
120 threadLocalCacheMaps.put(lifecycle, threadLocalCacheMap);
121 }
122
123 ThreadLocalCache<?> threadLocalCache = threadLocalCacheMap.get(name);
124
125 if (threadLocalCache == null) {
126 threadLocalCache = new ThreadLocalCache<>(name, lifecycle);
127
128 threadLocalCacheMap.put(name, threadLocalCache);
129 }
130
131 return (ThreadLocalCache<T>)threadLocalCache;
132 }
133
134 private static final EmptyThreadLocalCahce<?> _emptyThreadLocalCache =
135 new EmptyThreadLocalCahce<>();
136 private static final ThreadLocal
137 <Map<Lifecycle, Boolean>>
138 _threadLocalCacheDisabledFlags = new InitialThreadLocal
139 <Map<Lifecycle, Boolean>>(
140 ThreadLocalCacheManager.class +
141 "._threadLocalCacheDisabledFlags",
142 new EnumMap<Lifecycle, Boolean>(Lifecycle.class));
143 private static final ThreadLocal
144 <Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>>
145 _threadLocalCacheMaps = new InitialThreadLocal
146 <Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>>(
147 ThreadLocalCacheManager.class + "._threadLocalCacheMaps",
148 new EnumMap
149 <Lifecycle, Map<Serializable, ThreadLocalCache<?>>>(
150 Lifecycle.class));
151
152 private static class EmptyThreadLocalCahce<T> extends ThreadLocalCache<T> {
153
154 public EmptyThreadLocalCahce() {
155 super(null, null);
156 }
157
158 @Override
159 public T get(String key) {
160 return null;
161 }
162
163 @Override
164 public void put(String key, T obj) {
165 }
166
167 @Override
168 public void remove(String key) {
169 }
170
171 @Override
172 public void removeAll() {
173 }
174
175 @Override
176 public String toString() {
177 return EmptyThreadLocalCahce.class.getName();
178 }
179
180 }
181
182 }