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