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