001    /**
002     * Copyright (c) 2000-2011 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.util.ArrayList;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    
026    /**
027     * @author Shuyang Zhou
028     */
029    public class TransactionalPortalCacheHelper {
030    
031            public static void begin() {
032                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
033                            return;
034                    }
035    
036                    _pushPortalCacheMap();
037            }
038    
039            public static void commit() {
040                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
041                            return;
042                    }
043    
044                    Map<PortalCache, Map<String, Object>> portalCacheMap =
045                            _popPortalCacheMap();
046    
047                    for (Map.Entry<PortalCache, Map<String, Object>> portalCacheMapEntry :
048                                    portalCacheMap.entrySet()) {
049    
050                            PortalCache portalCache = portalCacheMapEntry.getKey();
051    
052                            Map<String, Object> uncommittedMap = portalCacheMapEntry.getValue();
053    
054                            for (Map.Entry<String, Object> uncommittedMapEntry :
055                                            uncommittedMap.entrySet()) {
056    
057                                    portalCache.put(
058                                            uncommittedMapEntry.getKey(),
059                                            uncommittedMapEntry.getValue());
060                            }
061                    }
062    
063                    portalCacheMap.clear();
064            }
065    
066            public static boolean isEnabled() {
067                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
068                            return false;
069                    }
070    
071                    List<Map<PortalCache, Map<String, Object>>> portalCacheList =
072                            _portalCacheListThreadLocal.get();
073    
074                    return !portalCacheList.isEmpty();
075            }
076    
077            public static void rollback() {
078                    if (!PropsValues.TRANSACTIONAL_CACHE_ENABLED) {
079                            return;
080                    }
081    
082                    Map<PortalCache, Map<String, Object>> portalCacheMap =
083                            _popPortalCacheMap();
084    
085                    portalCacheMap.clear();
086            }
087    
088            protected static Object get(PortalCache portalCache, String key) {
089                    Map<PortalCache, Map<String, Object>> portalCacheMap =
090                            _peekPortalCacheMap();
091    
092                    Map<String, Object> uncommittedMap = portalCacheMap.get(portalCache);
093    
094                    if (uncommittedMap == null) {
095                            return null;
096                    }
097    
098                    return uncommittedMap.get(key);
099            }
100    
101            protected static void put(
102                    PortalCache portalCache, String key, Object value) {
103    
104                    Map<PortalCache, Map<String, Object>> portalCacheMap =
105                            _peekPortalCacheMap();
106    
107                    Map<String, Object> uncommittedMap = portalCacheMap.get(portalCache);
108    
109                    if (uncommittedMap == null) {
110                            uncommittedMap = new HashMap<String, Object>();
111    
112                            portalCacheMap.put(portalCache, uncommittedMap);
113                    }
114    
115                    uncommittedMap.put(key, value);
116            }
117    
118            protected static void remove(PortalCache portalCache, String key) {
119                    Map<PortalCache, Map<String, Object>> portalCacheMap =
120                            _peekPortalCacheMap();
121    
122                    Map<String, Object> uncommittedMap = portalCacheMap.get(portalCache);
123    
124                    if (uncommittedMap != null) {
125                            uncommittedMap.remove(key);
126                    }
127            }
128    
129            protected static void removeAll(PortalCache portalCache) {
130                    Map<PortalCache, Map<String, Object>> portalCacheMap =
131                            _peekPortalCacheMap();
132    
133                    Map<String, Object> uncommittedMap = portalCacheMap.get(portalCache);
134    
135                    if (uncommittedMap != null) {
136                            uncommittedMap.clear();
137                    }
138            }
139    
140            private static Map<PortalCache, Map<String, Object>> _peekPortalCacheMap() {
141                    List<Map<PortalCache, Map<String, Object>>> portalCacheList =
142                            _portalCacheListThreadLocal.get();
143    
144                    return portalCacheList.get(portalCacheList.size() - 1);
145            }
146    
147            private static Map<PortalCache, Map<String, Object>> _popPortalCacheMap() {
148                    List<Map<PortalCache, Map<String, Object>>> portalCacheList =
149                            _portalCacheListThreadLocal.get();
150    
151                    return portalCacheList.remove(portalCacheList.size() - 1);
152            }
153    
154            private static void _pushPortalCacheMap() {
155                    List<Map<PortalCache, Map<String, Object>>> portalCacheList =
156                            _portalCacheListThreadLocal.get();
157    
158                    portalCacheList.add(new HashMap<PortalCache, Map<String, Object>>());
159            }
160    
161            private static ThreadLocal<List<Map<PortalCache, Map<String, Object>>>>
162                    _portalCacheListThreadLocal =
163                            new InitialThreadLocal<List<Map<PortalCache, Map<String, Object>>>>(
164                                    TransactionalPortalCacheHelper.class.getName() +
165                                            "._portalCacheListThreadLocal",
166                                    new ArrayList<Map<PortalCache, Map<String, Object>>>());
167    
168    }