001    /**
002     * Copyright (c) 2000-2010 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.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.util.AutoResetThreadLocal;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
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                    StringBundler sb = new StringBundler(5);
128    
129                    sb.append(CACHE_NAME);
130                    sb.append(StringPool.POUND);
131                    sb.append(userId);
132                    sb.append(StringPool.POUND);
133                    sb.append(groupId);
134    
135                    return sb.toString();
136            }
137    
138            private static String _encodeKey(
139                    long userId, long groupId, String name, String primKey,
140                    String actionId) {
141    
142                    StringBundler sb = new StringBundler(11);
143    
144                    sb.append(CACHE_NAME);
145                    sb.append(StringPool.POUND);
146                    sb.append(userId);
147                    sb.append(StringPool.POUND);
148                    sb.append(groupId);
149                    sb.append(StringPool.POUND);
150                    sb.append(name);
151                    sb.append(StringPool.POUND);
152                    sb.append(primKey);
153                    sb.append(StringPool.POUND);
154                    sb.append(actionId);
155    
156                    return sb.toString();
157            }
158    
159            private static ThreadLocal<LRUMap> _localCache;
160            private static boolean _localCacheAvailable;
161            private static PortalCache _portalCache = MultiVMPoolUtil.getCache(
162                    CACHE_NAME, PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
163    
164            static {
165                    if (PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE > 0) {
166                            _localCache = new AutoResetThreadLocal<LRUMap>(
167                                    PermissionCacheUtil.class + "._localCache",
168                                    new LRUMap(
169                                            PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE));
170                            _localCacheAvailable = true;
171                    }
172            }
173    
174    }