001
014
015 package com.liferay.portal.cache.transactional;
016
017 import com.liferay.portal.kernel.cache.PortalCache;
018 import com.liferay.portal.kernel.util.InitialThreadLocal;
019 import com.liferay.portal.util.PropsValues;
020
021 import java.io.Serializable;
022
023 import java.util.ArrayList;
024 import java.util.HashMap;
025 import java.util.List;
026 import java.util.Map;
027
028
031 public class TransactionalPortalCacheHelper {
032
033 public static void begin() {
034 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
035 return;
036 }
037
038 _pushPortalCacheMap();
039 }
040
041 public static void commit() {
042 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
043 return;
044 }
045
046 PortalCacheMap portalCacheMap = _popPortalCacheMap();
047
048 for (Map.Entry
049 <PortalCache<? extends Serializable, ?>, UncommittedBuffer>
050 portalCacheMapEntry : portalCacheMap.entrySet()) {
051
052 PortalCache<Serializable, Object> portalCache =
053 (PortalCache<Serializable, Object>)portalCacheMapEntry.getKey();
054
055 UncommittedBuffer uncommittedBuffer =
056 portalCacheMapEntry.getValue();
057
058 uncommittedBuffer.commitTo(portalCache);
059 }
060
061 portalCacheMap.clear();
062 }
063
064 public static boolean isEnabled() {
065 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
066 return false;
067 }
068
069 List<PortalCacheMap> portalCacheMaps =
070 _portalCacheMapsThreadLocal.get();
071
072 return !portalCacheMaps.isEmpty();
073 }
074
075 public static void rollback() {
076 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
077 return;
078 }
079
080 PortalCacheMap portalCacheMap = _popPortalCacheMap();
081
082 portalCacheMap.clear();
083 }
084
085 protected static <K extends Serializable, V> V get(
086 PortalCache<K, V> portalCache, K key) {
087
088 PortalCacheMap portalCacheMap = _peekPortalCacheMap();
089
090 UncommittedBuffer uncommittedBuffer = portalCacheMap.get(portalCache);
091
092 if (uncommittedBuffer == null) {
093 return null;
094 }
095
096 return (V)uncommittedBuffer.get(key);
097 }
098
099 protected static <K extends Serializable, V> void put(
100 PortalCache<K, V> portalCache, K key, V value) {
101
102 PortalCacheMap portalCacheMap = _peekPortalCacheMap();
103
104 UncommittedBuffer uncommittedBuffer = portalCacheMap.get(portalCache);
105
106 if (uncommittedBuffer == null) {
107 uncommittedBuffer = new UncommittedBuffer();
108
109 portalCacheMap.put(portalCache, uncommittedBuffer);
110 }
111
112 uncommittedBuffer.put(key, value);
113 }
114
115 protected static <K extends Serializable, V> void removeAll(
116 PortalCache<K, V> portalCache) {
117
118 PortalCacheMap portalCacheMap = _peekPortalCacheMap();
119
120 UncommittedBuffer uncommittedBuffer = portalCacheMap.get(portalCache);
121
122 if (uncommittedBuffer == null) {
123 uncommittedBuffer = new UncommittedBuffer();
124
125 portalCacheMap.put(portalCache, uncommittedBuffer);
126 }
127
128 uncommittedBuffer.removeAll();
129 }
130
131 private static PortalCacheMap _peekPortalCacheMap() {
132 List<PortalCacheMap> portalCacheMaps =
133 _portalCacheMapsThreadLocal.get();
134
135 return portalCacheMaps.get(portalCacheMaps.size() - 1);
136 }
137
138 private static PortalCacheMap _popPortalCacheMap() {
139 List<PortalCacheMap> portalCacheMaps =
140 _portalCacheMapsThreadLocal.get();
141
142 return portalCacheMaps.remove(portalCacheMaps.size() - 1);
143 }
144
145 private static void _pushPortalCacheMap() {
146 List<PortalCacheMap> portalCacheMaps =
147 _portalCacheMapsThreadLocal.get();
148
149 portalCacheMaps.add(new PortalCacheMap());
150 }
151
152 private static ThreadLocal<List<PortalCacheMap>>
153 _portalCacheMapsThreadLocal =
154 new InitialThreadLocal<List<PortalCacheMap>>(
155 TransactionalPortalCacheHelper.class.getName() +
156 "._portalCacheMapsThreadLocal",
157 new ArrayList<PortalCacheMap>());
158
159 private static class PortalCacheMap
160 extends HashMap
161 <PortalCache<? extends Serializable, ?>, UncommittedBuffer> {
162 }
163
164 private static class UncommittedBuffer {
165
166 public void commitTo(PortalCache<Serializable, Object> portalCache) {
167 if (_removeAll) {
168 portalCache.removeAll();
169 }
170
171 for (Map.Entry<? extends Serializable, ?> entry :
172 _uncommittedMap.entrySet()) {
173
174 Serializable key = entry.getKey();
175 Object value = entry.getValue();
176
177 if (value == TransactionalPortalCache.NULL_HOLDER) {
178 portalCache.remove(key);
179 }
180 else {
181 portalCache.put(entry.getKey(), entry.getValue());
182 }
183 }
184 }
185
186 public Object get(Serializable key) {
187 Object value = _uncommittedMap.get(key);
188
189 if ((value == null) && _removeAll) {
190 value = TransactionalPortalCache.NULL_HOLDER;
191 }
192
193 return value;
194 }
195
196 public void put(Serializable key, Object value) {
197 _uncommittedMap.put(key, value);
198 }
199
200 public void removeAll() {
201 _uncommittedMap.clear();
202
203 _removeAll = true;
204 }
205
206 private boolean _removeAll;
207 private Map<Serializable, Object> _uncommittedMap =
208 new HashMap<Serializable, Object>();
209
210 }
211
212 }