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 =
117 new HashMap<Serializable, ThreadLocalCache<?>>();
118
119 threadLocalCacheMaps.put(lifecycle, threadLocalCacheMap);
120 }
121
122 ThreadLocalCache<?> threadLocalCache = threadLocalCacheMap.get(name);
123
124 if (threadLocalCache == null) {
125 threadLocalCache = new ThreadLocalCache<T>(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<Object>();
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 }