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 public static void clearAll(Lifecycle lifecycle) {
069 Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>
070 threadLocalCacheMaps = _threadLocalCacheMaps.get();
071
072 Map<Serializable, ThreadLocalCache<?>> threadLocalCacheMap =
073 threadLocalCacheMaps.get(lifecycle);
074
075 if (threadLocalCacheMap != null) {
076 threadLocalCacheMap.clear();
077 }
078 }
079
080 public static void destroy() {
081 _threadLocalCacheMaps.remove();
082 }
083
084 public static void disable(Lifecycle lifecycle) {
085 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
086 _threadLocalCacheDisabledFlags.get();
087
088 threadLocalCacheDisabledFlags.put(lifecycle, Boolean.TRUE);
089
090 clearAll(lifecycle);
091 }
092
093 public static void enable(Lifecycle lifecycle) {
094 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
095 _threadLocalCacheDisabledFlags.get();
096
097 threadLocalCacheDisabledFlags.remove(lifecycle);
098 }
099
100 public static <T> ThreadLocalCache<T> getThreadLocalCache(
101 Lifecycle lifecycle, Serializable name) {
102
103 Map<Lifecycle, Boolean> threadLocalCacheDisabledFlags =
104 _threadLocalCacheDisabledFlags.get();
105
106 if (threadLocalCacheDisabledFlags.get(lifecycle) == Boolean.TRUE) {
107 return (ThreadLocalCache<T>)_emptyThreadLocalCache;
108 }
109
110 Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>
111 threadLocalCacheMaps = _threadLocalCacheMaps.get();
112
113 Map<Serializable, ThreadLocalCache<?>> threadLocalCacheMap =
114 threadLocalCacheMaps.get(lifecycle);
115
116 if (threadLocalCacheMap == null) {
117 threadLocalCacheMap = new HashMap<>();
118
119 threadLocalCacheMaps.put(lifecycle, threadLocalCacheMap);
120 }
121
122 ThreadLocalCache<?> threadLocalCache = threadLocalCacheMap.get(name);
123
124 if (threadLocalCache == null) {
125 threadLocalCache = new ThreadLocalCache<>(name, lifecycle);
126
127 threadLocalCacheMap.put(name, threadLocalCache);
128 }
129
130 return (ThreadLocalCache<T>)threadLocalCache;
131 }
132
133 private static final EmptyThreadLocalCahce<?> _emptyThreadLocalCache =
134 new EmptyThreadLocalCahce<>();
135 private static final ThreadLocal
136 <Map<Lifecycle, Boolean>>
137 _threadLocalCacheDisabledFlags = new InitialThreadLocal
138 <Map<Lifecycle, Boolean>>(
139 ThreadLocalCacheManager.class +
140 "._threadLocalCacheDisabledFlags",
141 new EnumMap<Lifecycle, Boolean>(Lifecycle.class));
142 private static final ThreadLocal
143 <Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>>
144 _threadLocalCacheMaps = new InitialThreadLocal
145 <Map<Lifecycle, Map<Serializable, ThreadLocalCache<?>>>>(
146 ThreadLocalCacheManager.class + "._threadLocalCacheMaps",
147 new EnumMap
148 <Lifecycle, Map<Serializable, ThreadLocalCache<?>>>(
149 Lifecycle.class));
150
151 private static class EmptyThreadLocalCahce<T> extends ThreadLocalCache<T> {
152
153 public EmptyThreadLocalCahce() {
154 super(null, null);
155 }
156
157 @Override
158 public T get(String key) {
159 return null;
160 }
161
162 @Override
163 public void put(String key, T obj) {
164 }
165
166 @Override
167 public void remove(String key) {
168 }
169
170 @Override
171 public void removeAll() {
172 }
173
174 @Override
175 public String toString() {
176 return EmptyThreadLocalCahce.class.getName();
177 }
178
179 }
180
181 }