001    /**
002     * Copyright (c) 2000-2013 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.lar.ImportExportThreadLocal;
020    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
021    import com.liferay.portal.kernel.util.HashUtil;
022    import com.liferay.portal.kernel.util.Validator;
023    import com.liferay.portal.util.PropsValues;
024    
025    import java.io.Serializable;
026    
027    import java.util.Map;
028    
029    import org.apache.commons.collections.map.LRUMap;
030    
031    /**
032     * @author Charles May
033     * @author Michael Young
034     * @author Shuyang Zhou
035     * @author Connor McKay
036     */
037    public class PermissionCacheUtil {
038    
039            public static final String PERMISSION_CACHE_NAME =
040                    PermissionCacheUtil.class.getName() + "_PERMISSION";
041    
042            public static final String PERMISSION_CHECKER_BAG_CACHE_NAME =
043                    PermissionCacheUtil.class.getName() + "_PERMISSION_CHECKER_BAG";
044    
045            public static final String RESOURCE_BLOCK_IDS_BAG_CACHE_NAME =
046                    PermissionCacheUtil.class.getName() + "_RESOURCE_BLOCK_IDS_BAG";
047    
048            public static void clearCache() {
049                    if (ImportExportThreadLocal.isImportInProcess() ||
050                            !PermissionThreadLocal.isFlushEnabled()) {
051    
052                            return;
053                    }
054    
055                    clearLocalCache();
056    
057                    _permissionCheckerBagPortalCache.removeAll();
058                    _permissionPortalCache.removeAll();
059                    _resourceBlockIdsBagCache.removeAll();
060            }
061    
062            public static void clearLocalCache() {
063                    if (_localCacheAvailable) {
064                            Map<String, Object> localCache = _localCache.get();
065    
066                            localCache.clear();
067                    }
068            }
069    
070            public static PermissionCheckerBag getBag(long userId, long groupId) {
071                    PermissionCheckerBag bag = null;
072    
073                    Serializable key = new BagKey(userId, groupId);
074    
075                    if (_localCacheAvailable) {
076                            Map<String, Object> localCache = _localCache.get();
077    
078                            bag = (PermissionCheckerBag)localCache.get(key);
079                    }
080    
081                    if (bag == null) {
082                            bag = (PermissionCheckerBag)_permissionCheckerBagPortalCache.get(
083                                    key);
084                    }
085    
086                    return bag;
087            }
088    
089            public static Boolean getPermission(
090                    long userId, boolean signedIn, boolean checkGuest, long groupId,
091                    String name, String primKey, String actionId) {
092    
093                    Boolean value = null;
094    
095                    Serializable key = new PermissionKey(
096                            userId, signedIn, checkGuest, groupId, name, primKey, actionId);
097    
098                    if (_localCacheAvailable) {
099                            Map<String, Object> localCache = _localCache.get();
100    
101                            value = (Boolean)localCache.get(key);
102                    }
103    
104                    if (value == null) {
105                            value = (Boolean)_permissionPortalCache.get(key);
106                    }
107    
108                    return value;
109            }
110    
111            public static ResourceBlockIdsBag getResourceBlockIdsBag(
112                    long companyId, long groupId, long userId, String name,
113                    boolean checkGuest) {
114    
115                    ResourceBlockIdsBag resourceBlockIdsBag = null;
116    
117                    Serializable key = new ResourceBlockIdsBagKey(
118                            companyId, groupId, userId, name, checkGuest);
119    
120                    if (_localCacheAvailable) {
121                            Map<String, Object> localCache = _localCache.get();
122    
123                            resourceBlockIdsBag = (ResourceBlockIdsBag)localCache.get(key);
124                    }
125    
126                    if (resourceBlockIdsBag == null) {
127                            resourceBlockIdsBag =
128                                    (ResourceBlockIdsBag)_resourceBlockIdsBagCache.get(key);
129                    }
130    
131                    return resourceBlockIdsBag;
132            }
133    
134            public static PermissionCheckerBag putBag(
135                    long userId, long groupId, PermissionCheckerBag bag) {
136    
137                    if (bag == null) {
138                            return null;
139                    }
140    
141                    Serializable key = new BagKey(userId, groupId);
142    
143                    if (_localCacheAvailable) {
144                            Map<Serializable, Object> localCache = _localCache.get();
145    
146                            localCache.put(key, bag);
147                    }
148    
149                    _permissionCheckerBagPortalCache.put(key, bag);
150    
151                    return bag;
152            }
153    
154            public static Boolean putPermission(
155                    long userId, boolean signedIn, boolean checkGuest, long groupId,
156                    String name, String primKey, String actionId, Boolean value) {
157    
158                    if (value == null) {
159                            return null;
160                    }
161    
162                    Serializable key = new PermissionKey(
163                            userId, signedIn, checkGuest, groupId, name, primKey, actionId);
164    
165                    if (_localCacheAvailable) {
166                            Map<Serializable, Object> localCache = _localCache.get();
167    
168                            localCache.put(key, value);
169                    }
170    
171                    _permissionPortalCache.put(key, value);
172    
173                    return value;
174            }
175    
176            public static ResourceBlockIdsBag putResourceBlockIdsBag(
177                    long companyId, long groupId, long userId, String name,
178                    boolean checkGuest, ResourceBlockIdsBag resourceBlockIdsBag) {
179    
180                    if (resourceBlockIdsBag == null) {
181                            return null;
182                    }
183    
184                    Serializable key = new ResourceBlockIdsBagKey(
185                            companyId, groupId, userId, name, checkGuest);
186    
187                    if (_localCacheAvailable) {
188                            Map<Serializable, Object> localCache = _localCache.get();
189    
190                            localCache.put(key, resourceBlockIdsBag);
191                    }
192    
193                    _resourceBlockIdsBagCache.put(key, resourceBlockIdsBag);
194    
195                    return resourceBlockIdsBag;
196            }
197    
198            private static ThreadLocal<LRUMap> _localCache;
199            private static boolean _localCacheAvailable;
200            private static PortalCache _permissionCheckerBagPortalCache =
201                    MultiVMPoolUtil.getCache(
202                            PERMISSION_CHECKER_BAG_CACHE_NAME,
203                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
204            private static PortalCache _permissionPortalCache =
205                    MultiVMPoolUtil.getCache(
206                            PERMISSION_CACHE_NAME,
207                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
208            private static PortalCache _resourceBlockIdsBagCache =
209                    MultiVMPoolUtil.getCache(
210                            RESOURCE_BLOCK_IDS_BAG_CACHE_NAME,
211                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
212    
213            private static class BagKey implements Serializable {
214    
215                    public BagKey(long userId, long groupId) {
216                            _userId = userId;
217                            _groupId = groupId;
218                    }
219    
220                    @Override
221                    public boolean equals(Object obj) {
222                            BagKey bagKey = (BagKey)obj;
223    
224                            if ((bagKey._userId == _userId) && (bagKey._groupId == _groupId)) {
225                                    return true;
226                            }
227                            else {
228                                    return false;
229                            }
230                    }
231    
232                    @Override
233                    public int hashCode() {
234                            return (int)(_userId * 11 + _groupId);
235                    }
236    
237                    private static final long serialVersionUID = 1L;
238    
239                    private final long _groupId;
240                    private final long _userId;
241    
242            }
243    
244            private static class PermissionKey implements Serializable {
245    
246                    public PermissionKey(
247                            long userId, boolean signedIn, boolean checkGuest, long groupId,
248                            String name, String primKey, String actionId) {
249    
250                            _userId = userId;
251                            _signedIn = signedIn;
252                            _checkGuest = checkGuest;
253                            _groupId = groupId;
254                            _name = name;
255                            _primKey = primKey;
256                            _actionId = actionId;
257                    }
258    
259                    @Override
260                    public boolean equals(Object obj) {
261                            PermissionKey permissionKey = (PermissionKey)obj;
262    
263                            if ((permissionKey._userId == _userId) &&
264                                    (permissionKey._signedIn == _signedIn) &&
265                                    (permissionKey._checkGuest == _checkGuest) &&
266                                    (permissionKey._groupId == _groupId) &&
267                                    Validator.equals(permissionKey._name, _name) &&
268                                    Validator.equals(permissionKey._primKey, _primKey) &&
269                                    Validator.equals(permissionKey._actionId, _actionId)) {
270    
271                                    return true;
272                            }
273                            else {
274                                    return false;
275                            }
276                    }
277    
278                    @Override
279                    public int hashCode() {
280                            int hashCode = HashUtil.hash(0, _userId);
281    
282                            hashCode = HashUtil.hash(hashCode, _signedIn);
283                            hashCode = HashUtil.hash(hashCode, _checkGuest);
284                            hashCode = HashUtil.hash(hashCode, _groupId);
285                            hashCode = HashUtil.hash(hashCode, _name);
286                            hashCode = HashUtil.hash(hashCode, _primKey);
287                            hashCode = HashUtil.hash(hashCode, _actionId);
288    
289                            return hashCode;
290                    }
291    
292                    private static final long serialVersionUID = 1L;
293    
294                    private final String _actionId;
295                    private final boolean _checkGuest;
296                    private final long _groupId;
297                    private final String _name;
298                    private final String _primKey;
299                    private final boolean _signedIn;
300                    private final long _userId;
301    
302            }
303    
304            private static class ResourceBlockIdsBagKey implements Serializable {
305    
306                    public ResourceBlockIdsBagKey(
307                            long companyId, long groupId, long userId, String name,
308                            boolean checkGuest) {
309    
310                            _companyId = companyId;
311                            _groupId = groupId;
312                            _userId = userId;
313                            _name = name;
314                            _checkGuest = checkGuest;
315                    }
316    
317                    @Override
318                    public boolean equals(Object obj) {
319                            ResourceBlockIdsBagKey resourceBlockIdsKey =
320                                    (ResourceBlockIdsBagKey)obj;
321    
322                            if ((resourceBlockIdsKey._companyId == _companyId) &&
323                                    (resourceBlockIdsKey._groupId == _groupId) &&
324                                    (resourceBlockIdsKey._userId == _userId) &&
325                                    (resourceBlockIdsKey._checkGuest == _checkGuest) &&
326                                    Validator.equals(resourceBlockIdsKey._name, _name)) {
327    
328                                    return true;
329                            }
330                            else {
331                                    return false;
332                            }
333                    }
334    
335                    @Override
336                    public int hashCode() {
337                            int hashCode = HashUtil.hash(0, _companyId);
338    
339                            hashCode = HashUtil.hash(hashCode, _groupId);
340                            hashCode = HashUtil.hash(hashCode, _userId);
341                            hashCode = HashUtil.hash(hashCode, _name);
342                            hashCode = HashUtil.hash(hashCode, _checkGuest);
343    
344                            return hashCode;
345                    }
346    
347                    private static final long serialVersionUID = 1L;
348    
349                    private final boolean _checkGuest;
350                    private final long _companyId;
351                    private final long _groupId;
352                    private final String _name;
353                    private final long _userId;
354    
355            }
356    
357            static {
358                    if (PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE > 0) {
359                            _localCache = new AutoResetThreadLocal<LRUMap>(
360                                    PermissionCacheUtil.class + "._localCache",
361                                    new LRUMap(
362                                            PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE));
363                            _localCacheAvailable = true;
364                    }
365            }
366    
367    }