001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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    /**
029     * @author Shuyang Zhou
030     */
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, Map<Serializable, Object>> portalCacheMap =
047                            _popPortalCacheMap();
048    
049                    for (Map.Entry<PortalCache, Map<Serializable, Object>>
050                            portalCacheMapEntry : portalCacheMap.entrySet()) {
051    
052                            PortalCache portalCache = portalCacheMapEntry.getKey();
053    
054                            Map<Serializable, Object> uncommittedMap =
055                                    portalCacheMapEntry.getValue();
056    
057                            for (Map.Entry<Serializable, Object> uncommittedMapEntry :
058                                            uncommittedMap.entrySet()) {
059    
060                                    portalCache.put(
061                                            uncommittedMapEntry.getKey(),
062                                            uncommittedMapEntry.getValue());
063                            }
064                    }
065    
066                    portalCacheMap.clear();
067            }
068    
069            public static boolean isEnabled() {
070                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
071                            return false;
072                    }
073    
074                    List<Map<PortalCache, Map<Serializable, Object>>> portalCacheList =
075                            _portalCacheListThreadLocal.get();
076    
077                    return !portalCacheList.isEmpty();
078            }
079    
080            public static void rollback() {
081                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
082                            return;
083                    }
084    
085                    Map<PortalCache, Map<Serializable, Object>> portalCacheMap =
086                            _popPortalCacheMap();
087    
088                    portalCacheMap.clear();
089            }
090    
091            protected static Object get(PortalCache portalCache, Serializable key) {
092                    Map<PortalCache, Map<Serializable, Object>> portalCacheMap =
093                            _peekPortalCacheMap();
094    
095                    Map<Serializable, Object> uncommittedMap = portalCacheMap.get(
096                            portalCache);
097    
098                    if (uncommittedMap == null) {
099                            return null;
100                    }
101    
102                    return uncommittedMap.get(key);
103            }
104    
105            protected static void put(
106                    PortalCache portalCache, Serializable key, Object value) {
107    
108                    Map<PortalCache, Map<Serializable, Object>> portalCacheMap =
109                            _peekPortalCacheMap();
110    
111                    Map<Serializable, Object> uncommittedMap = portalCacheMap.get(
112                            portalCache);
113    
114                    if (uncommittedMap == null) {
115                            uncommittedMap = new HashMap<Serializable, Object>();
116    
117                            portalCacheMap.put(portalCache, uncommittedMap);
118                    }
119    
120                    uncommittedMap.put(key, value);
121            }
122    
123            protected static void remove(PortalCache portalCache, Serializable key) {
124                    Map<PortalCache, Map<Serializable, Object>> portalCacheMap =
125                            _peekPortalCacheMap();
126    
127                    Map<Serializable, Object> uncommittedMap = portalCacheMap.get(
128                            portalCache);
129    
130                    if (uncommittedMap != null) {
131                            uncommittedMap.remove(key);
132                    }
133            }
134    
135            protected static void removeAll(PortalCache portalCache) {
136                    Map<PortalCache, Map<Serializable, Object>> portalCacheMap =
137                            _peekPortalCacheMap();
138    
139                    Map<Serializable, Object> uncommittedMap = portalCacheMap.get(
140                            portalCache);
141    
142                    if (uncommittedMap != null) {
143                            uncommittedMap.clear();
144                    }
145            }
146    
147            private static Map<PortalCache, Map<Serializable, Object>>
148                    _peekPortalCacheMap() {
149    
150                    List<Map<PortalCache, Map<Serializable, Object>>> portalCacheList =
151                            _portalCacheListThreadLocal.get();
152    
153                    return portalCacheList.get(portalCacheList.size() - 1);
154            }
155    
156            private static Map<PortalCache, Map<Serializable, Object>>
157                    _popPortalCacheMap() {
158    
159                    List<Map<PortalCache, Map<Serializable, Object>>> portalCacheList =
160                            _portalCacheListThreadLocal.get();
161    
162                    return portalCacheList.remove(portalCacheList.size() - 1);
163            }
164    
165            private static void _pushPortalCacheMap() {
166                    List<Map<PortalCache, Map<Serializable, Object>>> portalCacheList =
167                            _portalCacheListThreadLocal.get();
168    
169                    portalCacheList.add(
170                            new HashMap<PortalCache, Map<Serializable, Object>>());
171            }
172    
173            private static ThreadLocal
174                    <List<Map<PortalCache, Map<Serializable, Object>>>>
175                            _portalCacheListThreadLocal = new InitialThreadLocal
176                                    <List<Map<PortalCache, Map<Serializable, Object>>>>(
177                                            TransactionalPortalCacheHelper.class.getName() +
178                                                    "._portalCacheListThreadLocal",
179                                            new ArrayList
180                                                    <Map<PortalCache, Map<Serializable, Object>>>());
181    
182    }