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