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 Map<PortalCache, UncommittedBuffer> portalCacheMap =
047 _popPortalCacheMap();
048
049 for (Map.Entry<PortalCache, UncommittedBuffer>
050 portalCacheMapEntry : portalCacheMap.entrySet()) {
051
052 PortalCache portalCache = portalCacheMapEntry.getKey();
053
054 UncommittedBuffer uncommittedBuffer =
055 portalCacheMapEntry.getValue();
056
057 uncommittedBuffer.commitTo(portalCache);
058 }
059
060 portalCacheMap.clear();
061 }
062
063 public static boolean isEnabled() {
064 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
065 return false;
066 }
067
068 List<Map<PortalCache, UncommittedBuffer>> portalCacheList =
069 _portalCacheListThreadLocal.get();
070
071 return !portalCacheList.isEmpty();
072 }
073
074 public static void rollback() {
075 if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
076 return;
077 }
078
079 Map<PortalCache, UncommittedBuffer> portalCacheMap =
080 _popPortalCacheMap();
081
082 portalCacheMap.clear();
083 }
084
085 protected static Object get(PortalCache portalCache, Serializable key) {
086 Map<PortalCache, UncommittedBuffer> portalCacheMap =
087 _peekPortalCacheMap();
088
089 UncommittedBuffer uncommittedBuffer = portalCacheMap.get(portalCache);
090
091 if (uncommittedBuffer == null) {
092 return null;
093 }
094
095 return uncommittedBuffer.get(key);
096 }
097
098 protected static void put(
099 PortalCache portalCache, Serializable key, Object value) {
100
101 Map<PortalCache, UncommittedBuffer> portalCacheMap =
102 _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 void removeAll(PortalCache portalCache) {
116 Map<PortalCache, UncommittedBuffer> portalCacheMap =
117 _peekPortalCacheMap();
118
119 UncommittedBuffer uncommittedBuffer = portalCacheMap.get(portalCache);
120
121 if (uncommittedBuffer == null) {
122 uncommittedBuffer = new UncommittedBuffer();
123
124 portalCacheMap.put(portalCache, uncommittedBuffer);
125 }
126
127 uncommittedBuffer.removeAll();
128 }
129
130 private static Map<PortalCache, UncommittedBuffer>
131 _peekPortalCacheMap() {
132
133 List<Map<PortalCache, UncommittedBuffer>> portalCacheList =
134 _portalCacheListThreadLocal.get();
135
136 return portalCacheList.get(portalCacheList.size() - 1);
137 }
138
139 private static Map<PortalCache, UncommittedBuffer>
140 _popPortalCacheMap() {
141
142 List<Map<PortalCache, UncommittedBuffer>> portalCacheList =
143 _portalCacheListThreadLocal.get();
144
145 return portalCacheList.remove(portalCacheList.size() - 1);
146 }
147
148 private static void _pushPortalCacheMap() {
149 List<Map<PortalCache, UncommittedBuffer>> portalCacheList =
150 _portalCacheListThreadLocal.get();
151
152 portalCacheList.add(new HashMap<PortalCache, UncommittedBuffer>());
153 }
154
155 private static ThreadLocal<List<Map<PortalCache, UncommittedBuffer>>>
156 _portalCacheListThreadLocal = new InitialThreadLocal
157 <List<Map<PortalCache, UncommittedBuffer>>>(
158 TransactionalPortalCacheHelper.class.getName() +
159 "._portalCacheListThreadLocal",
160 new ArrayList<Map<PortalCache, UncommittedBuffer>>());
161
162 private static class UncommittedBuffer {
163
164 public void commitTo(PortalCache portalCache) {
165 if (_removeAll) {
166 portalCache.removeAll();
167 }
168
169 for (Map.Entry<? extends Serializable, ?> entry :
170 _uncommittedMap.entrySet()) {
171
172 Serializable key = entry.getKey();
173 Object value = entry.getValue();
174
175 if (value == TransactionalPortalCache.NULL_HOLDER) {
176 portalCache.remove(key);
177 }
178 else {
179 portalCache.put(entry.getKey(), entry.getValue());
180 }
181 }
182 }
183
184 public Object get(Serializable key) {
185 Object value = _uncommittedMap.get(key);
186
187 if ((value == null) && _removeAll) {
188 value = TransactionalPortalCache.NULL_HOLDER;
189 }
190
191 return value;
192 }
193
194 public void put(Serializable key, Object value) {
195 _uncommittedMap.put(key, value);
196 }
197
198 public void removeAll() {
199 _uncommittedMap.clear();
200
201 _removeAll = true;
202 }
203
204 private boolean _removeAll;
205 private Map<Serializable, Object> _uncommittedMap =
206 new HashMap<Serializable, Object>();
207
208 }
209
210 }