001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.security.permission;
016    
017    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
018    import com.liferay.portal.kernel.cache.PortalCache;
019    import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
020    import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
021    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
022    import com.liferay.portal.util.PropsValues;
023    
024    import java.util.Map;
025    
026    import org.apache.commons.collections.map.LRUMap;
027    
028    /**
029     * @author Charles May
030     * @author Michael Young
031     */
032    public class PermissionCacheUtil {
033    
034            public static final String CACHE_NAME = PermissionCacheUtil.class.getName();
035    
036            public static void clearCache() {
037                    clearLocalCache();
038    
039                    _portalCache.removeAll();
040            }
041    
042            public static void clearLocalCache() {
043                    if (_localCacheAvailable) {
044                            Map<String, Object> localCache = _localCache.get();
045    
046                            localCache.clear();
047                    }
048            }
049    
050            public static PermissionCheckerBag getBag(long userId, long groupId) {
051                    PermissionCheckerBag bag = null;
052    
053                    String key = _encodeKey(userId, groupId);
054    
055                    if (_localCacheAvailable) {
056                            Map<String, Object> localCache = _localCache.get();
057    
058                            bag = (PermissionCheckerBag)localCache.get(key);
059                    }
060    
061                    if (bag == null) {
062                            bag = (PermissionCheckerBag)_portalCache.get(key);
063                    }
064    
065                    return bag;
066            }
067    
068            public static Boolean getPermission(
069                    long userId, long groupId, String name, String primKey,
070                    String actionId) {
071    
072                    Boolean value = null;
073    
074                    String key = _encodeKey(userId, groupId, name, primKey, actionId);
075    
076                    if (_localCacheAvailable) {
077                            Map<String, Object> localCache = _localCache.get();
078    
079                            value = (Boolean)localCache.get(key);
080                    }
081    
082                    if (value == null) {
083                            value = (Boolean)_portalCache.get(key);
084                    }
085    
086                    return value;
087            }
088    
089            public static PermissionCheckerBag putBag(
090                    long userId, long groupId, PermissionCheckerBag bag) {
091    
092                    if (bag != null) {
093                            String key = _encodeKey(userId, groupId);
094    
095                            if (_localCacheAvailable) {
096                                    Map<String, Object> localCache = _localCache.get();
097    
098                                    localCache.put(key, bag);
099                            }
100    
101                            _portalCache.put(key, bag);
102                    }
103    
104                    return bag;
105            }
106    
107            public static Boolean putPermission(
108                    long userId, long groupId, String name, String primKey, String actionId,
109                    Boolean value) {
110    
111                    if (value != null) {
112                            String key = _encodeKey(userId, groupId, name, primKey, actionId);
113    
114                            if (_localCacheAvailable) {
115                                    Map<String, Object> localCache = _localCache.get();
116    
117                                    localCache.put(key, value);
118                            }
119    
120                            _portalCache.put(key, value);
121                    }
122    
123                    return value;
124            }
125    
126            private static String _encodeKey(long userId, long groupId) {
127                    CacheKeyGenerator cacheKeyGenerator =
128                            CacheKeyGeneratorUtil.getCacheKeyGenerator(CACHE_NAME);
129    
130                    cacheKeyGenerator.append(String.valueOf(userId));
131                    cacheKeyGenerator.append(String.valueOf(groupId));
132    
133                    return cacheKeyGenerator.finish();
134            }
135    
136            private static String _encodeKey(
137                    long userId, long groupId, String name, String primKey,
138                    String actionId) {
139    
140                    CacheKeyGenerator cacheKeyGenerator =
141                            CacheKeyGeneratorUtil.getCacheKeyGenerator(CACHE_NAME);
142    
143                    cacheKeyGenerator.append(String.valueOf(userId));
144                    cacheKeyGenerator.append(String.valueOf(groupId));
145                    cacheKeyGenerator.append(name);
146                    cacheKeyGenerator.append(primKey);
147                    cacheKeyGenerator.append(actionId);
148    
149                    return cacheKeyGenerator.finish();
150            }
151    
152            private static ThreadLocal<LRUMap> _localCache;
153            private static boolean _localCacheAvailable;
154            private static PortalCache _portalCache = MultiVMPoolUtil.getCache(
155                    CACHE_NAME, PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
156    
157            static {
158                    if (PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE > 0) {
159                            _localCache = new AutoResetThreadLocal<LRUMap>(
160                                    PermissionCacheUtil.class + "._localCache",
161                                    new LRUMap(
162                                            PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE));
163                            _localCacheAvailable = true;
164                    }
165            }
166    
167    }