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.ExportImportThreadLocal;
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 (ExportImportThreadLocal.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                    BagKey bagKey = new BagKey(userId, groupId);
074    
075                    if (_localCacheAvailable) {
076                            Map<String, Object> localCache = _localCache.get();
077    
078                            bag = (PermissionCheckerBag)localCache.get(bagKey);
079                    }
080    
081                    if (bag == null) {
082                            bag = _permissionCheckerBagPortalCache.get(bagKey);
083                    }
084    
085                    return bag;
086            }
087    
088            public static Boolean getPermission(
089                    long userId, boolean signedIn, boolean checkGuest, long groupId,
090                    String name, String primKey, String actionId) {
091    
092                    Boolean value = null;
093    
094                    PermissionKey permissionKey = new PermissionKey(
095                            userId, signedIn, checkGuest, groupId, name, primKey, actionId);
096    
097                    if (_localCacheAvailable) {
098                            Map<String, Object> localCache = _localCache.get();
099    
100                            value = (Boolean)localCache.get(permissionKey);
101                    }
102    
103                    if (value == null) {
104                            value = _permissionPortalCache.get(permissionKey);
105                    }
106    
107                    return value;
108            }
109    
110            public static ResourceBlockIdsBag getResourceBlockIdsBag(
111                    long companyId, long groupId, long userId, String name,
112                    boolean checkGuest) {
113    
114                    ResourceBlockIdsBag resourceBlockIdsBag = null;
115    
116                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
117                            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(
124                                    resourceBlockIdsBagKey);
125                    }
126    
127                    if (resourceBlockIdsBag == null) {
128                            resourceBlockIdsBag = _resourceBlockIdsBagCache.get(
129                                    resourceBlockIdsBagKey);
130                    }
131    
132                    return resourceBlockIdsBag;
133            }
134    
135            public static PermissionCheckerBag putBag(
136                    long userId, long groupId, PermissionCheckerBag bag) {
137    
138                    if (bag == null) {
139                            return null;
140                    }
141    
142                    BagKey bagKey = new BagKey(userId, groupId);
143    
144                    if (_localCacheAvailable) {
145                            Map<Serializable, Object> localCache = _localCache.get();
146    
147                            localCache.put(bagKey, bag);
148                    }
149    
150                    _permissionCheckerBagPortalCache.put(bagKey, bag);
151    
152                    return bag;
153            }
154    
155            public static Boolean putPermission(
156                    long userId, boolean signedIn, boolean checkGuest, long groupId,
157                    String name, String primKey, String actionId, Boolean value) {
158    
159                    if (value == null) {
160                            return null;
161                    }
162    
163                    PermissionKey permissionKey = new PermissionKey(
164                            userId, signedIn, checkGuest, groupId, name, primKey, actionId);
165    
166                    if (_localCacheAvailable) {
167                            Map<Serializable, Object> localCache = _localCache.get();
168    
169                            localCache.put(permissionKey, value);
170                    }
171    
172                    _permissionPortalCache.put(permissionKey, value);
173    
174                    return value;
175            }
176    
177            public static ResourceBlockIdsBag putResourceBlockIdsBag(
178                    long companyId, long groupId, long userId, String name,
179                    boolean checkGuest, ResourceBlockIdsBag resourceBlockIdsBag) {
180    
181                    if (resourceBlockIdsBag == null) {
182                            return null;
183                    }
184    
185                    ResourceBlockIdsBagKey resourceBlockIdsBagKey =
186                            new ResourceBlockIdsBagKey(
187                                    companyId, groupId, userId, name, checkGuest);
188    
189                    if (_localCacheAvailable) {
190                            Map<Serializable, Object> localCache = _localCache.get();
191    
192                            localCache.put(resourceBlockIdsBagKey, resourceBlockIdsBag);
193                    }
194    
195                    _resourceBlockIdsBagCache.put(
196                            resourceBlockIdsBagKey, resourceBlockIdsBag);
197    
198                    return resourceBlockIdsBag;
199            }
200    
201            private static ThreadLocal<LRUMap> _localCache;
202            private static boolean _localCacheAvailable;
203            private static PortalCache<BagKey, PermissionCheckerBag>
204                    _permissionCheckerBagPortalCache = MultiVMPoolUtil.getCache(
205                            PERMISSION_CHECKER_BAG_CACHE_NAME,
206                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
207            private static PortalCache<PermissionKey, Boolean> _permissionPortalCache =
208                    MultiVMPoolUtil.getCache(
209                            PERMISSION_CACHE_NAME,
210                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
211            private static PortalCache<ResourceBlockIdsBagKey, ResourceBlockIdsBag>
212                    _resourceBlockIdsBagCache = MultiVMPoolUtil.getCache(
213                            RESOURCE_BLOCK_IDS_BAG_CACHE_NAME,
214                            PropsValues.PERMISSIONS_OBJECT_BLOCKING_CACHE);
215    
216            private static class BagKey implements Serializable {
217    
218                    public BagKey(long userId, long groupId) {
219                            _userId = userId;
220                            _groupId = groupId;
221                    }
222    
223                    @Override
224                    public boolean equals(Object obj) {
225                            BagKey bagKey = (BagKey)obj;
226    
227                            if ((bagKey._userId == _userId) && (bagKey._groupId == _groupId)) {
228                                    return true;
229                            }
230                            else {
231                                    return false;
232                            }
233                    }
234    
235                    @Override
236                    public int hashCode() {
237                            return (int)(_userId * 11 + _groupId);
238                    }
239    
240                    private static final long serialVersionUID = 1L;
241    
242                    private final long _groupId;
243                    private final long _userId;
244    
245            }
246    
247            private static class PermissionKey implements Serializable {
248    
249                    public PermissionKey(
250                            long userId, boolean signedIn, boolean checkGuest, long groupId,
251                            String name, String primKey, String actionId) {
252    
253                            _userId = userId;
254                            _signedIn = signedIn;
255                            _checkGuest = checkGuest;
256                            _groupId = groupId;
257                            _name = name;
258                            _primKey = primKey;
259                            _actionId = actionId;
260                    }
261    
262                    @Override
263                    public boolean equals(Object obj) {
264                            PermissionKey permissionKey = (PermissionKey)obj;
265    
266                            if ((permissionKey._userId == _userId) &&
267                                    (permissionKey._signedIn == _signedIn) &&
268                                    (permissionKey._checkGuest == _checkGuest) &&
269                                    (permissionKey._groupId == _groupId) &&
270                                    Validator.equals(permissionKey._name, _name) &&
271                                    Validator.equals(permissionKey._primKey, _primKey) &&
272                                    Validator.equals(permissionKey._actionId, _actionId)) {
273    
274                                    return true;
275                            }
276                            else {
277                                    return false;
278                            }
279                    }
280    
281                    @Override
282                    public int hashCode() {
283                            int hashCode = HashUtil.hash(0, _userId);
284    
285                            hashCode = HashUtil.hash(hashCode, _signedIn);
286                            hashCode = HashUtil.hash(hashCode, _checkGuest);
287                            hashCode = HashUtil.hash(hashCode, _groupId);
288                            hashCode = HashUtil.hash(hashCode, _name);
289                            hashCode = HashUtil.hash(hashCode, _primKey);
290                            hashCode = HashUtil.hash(hashCode, _actionId);
291    
292                            return hashCode;
293                    }
294    
295                    private static final long serialVersionUID = 1L;
296    
297                    private final String _actionId;
298                    private final boolean _checkGuest;
299                    private final long _groupId;
300                    private final String _name;
301                    private final String _primKey;
302                    private final boolean _signedIn;
303                    private final long _userId;
304    
305            }
306    
307            private static class ResourceBlockIdsBagKey implements Serializable {
308    
309                    public ResourceBlockIdsBagKey(
310                            long companyId, long groupId, long userId, String name,
311                            boolean checkGuest) {
312    
313                            _companyId = companyId;
314                            _groupId = groupId;
315                            _userId = userId;
316                            _name = name;
317                            _checkGuest = checkGuest;
318                    }
319    
320                    @Override
321                    public boolean equals(Object obj) {
322                            ResourceBlockIdsBagKey resourceBlockIdsKey =
323                                    (ResourceBlockIdsBagKey)obj;
324    
325                            if ((resourceBlockIdsKey._companyId == _companyId) &&
326                                    (resourceBlockIdsKey._groupId == _groupId) &&
327                                    (resourceBlockIdsKey._userId == _userId) &&
328                                    (resourceBlockIdsKey._checkGuest == _checkGuest) &&
329                                    Validator.equals(resourceBlockIdsKey._name, _name)) {
330    
331                                    return true;
332                            }
333                            else {
334                                    return false;
335                            }
336                    }
337    
338                    @Override
339                    public int hashCode() {
340                            int hashCode = HashUtil.hash(0, _companyId);
341    
342                            hashCode = HashUtil.hash(hashCode, _groupId);
343                            hashCode = HashUtil.hash(hashCode, _userId);
344                            hashCode = HashUtil.hash(hashCode, _name);
345                            hashCode = HashUtil.hash(hashCode, _checkGuest);
346    
347                            return hashCode;
348                    }
349    
350                    private static final long serialVersionUID = 1L;
351    
352                    private final boolean _checkGuest;
353                    private final long _companyId;
354                    private final long _groupId;
355                    private final String _name;
356                    private final long _userId;
357    
358            }
359    
360            static {
361                    if (PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE > 0) {
362                            _localCache = new AutoResetThreadLocal<LRUMap>(
363                                    PermissionCacheUtil.class + "._localCache",
364                                    new LRUMap(
365                                            PropsValues.PERMISSIONS_THREAD_LOCAL_CACHE_MAX_SIZE));
366                            _localCacheAvailable = true;
367                    }
368            }
369    
370    }