001    /**
002     * Copyright (c) 2000-2012 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.service.impl;
016    
017    import com.liferay.portal.NoSuchResourcePermissionException;
018    import com.liferay.portal.kernel.concurrent.LockRegistry;
019    import com.liferay.portal.kernel.dao.db.DB;
020    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
021    import com.liferay.portal.kernel.dao.orm.QueryPos;
022    import com.liferay.portal.kernel.dao.orm.SQLQuery;
023    import com.liferay.portal.kernel.dao.orm.Session;
024    import com.liferay.portal.kernel.dao.orm.Type;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.search.SearchEngineUtil;
028    import com.liferay.portal.kernel.util.ListUtil;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.StringUtil;
032    import com.liferay.portal.model.Resource;
033    import com.liferay.portal.model.ResourceAction;
034    import com.liferay.portal.model.ResourceConstants;
035    import com.liferay.portal.model.ResourcePermission;
036    import com.liferay.portal.model.ResourcePermissionConstants;
037    import com.liferay.portal.model.Role;
038    import com.liferay.portal.model.RoleConstants;
039    import com.liferay.portal.security.permission.PermissionCacheUtil;
040    import com.liferay.portal.security.permission.PermissionThreadLocal;
041    import com.liferay.portal.security.permission.ResourceActionsUtil;
042    import com.liferay.portal.service.base.ResourcePermissionLocalServiceBaseImpl;
043    import com.liferay.portal.util.PortalUtil;
044    import com.liferay.portal.util.PropsValues;
045    import com.liferay.portal.util.ResourcePermissionsThreadLocal;
046    import com.liferay.util.dao.orm.CustomSQLUtil;
047    
048    import java.util.ArrayList;
049    import java.util.Collection;
050    import java.util.Collections;
051    import java.util.HashMap;
052    import java.util.HashSet;
053    import java.util.List;
054    import java.util.Map;
055    import java.util.Set;
056    import java.util.concurrent.locks.Lock;
057    
058    /**
059     * Manages the creation and upkeep of resource permissions, and provides methods
060     * for granting, revoking, and checking permissions.
061     *
062     * <p>
063     * Before attempting to read any of the documentation for this class, first read
064     * {@link com.liferay.portal.model.impl.ResourcePermissionImpl} for an
065     * explanation of scoping.
066     * </p>
067     *
068     * @author Brian Wing Shun Chan
069     * @author Raymond Augé
070     * @author Connor McKay
071     */
072    public class ResourcePermissionLocalServiceImpl
073            extends ResourcePermissionLocalServiceBaseImpl {
074    
075            /**
076             * @see com.liferay.portal.verify.VerifyPermission#fixOrganizationRolePermissions
077             */
078            public static final String[] EMPTY_ACTION_IDS = {null};
079    
080            /**
081             * Grants the role permission at the scope to perform the action on
082             * resources of the type. Existing actions are retained.
083             *
084             * <p>
085             * This method cannot be used to grant individual scope permissions, but is
086             * only intended for adding permissions at the company, group, and
087             * group-template scopes. For example, this method could be used to grant a
088             * company scope permission to edit message board posts.
089             * </p>
090             *
091             * <p>
092             * If a company scope permission is granted to resources that the role
093             * already had group scope permissions to, the group scope permissions are
094             * deleted. Likewise, if a group scope permission is granted to resources
095             * that the role already had company scope permissions to, the company scope
096             * permissions are deleted. Be aware that this latter behavior can result in
097             * an overall reduction in permissions for the role.
098             * </p>
099             *
100             * <p>
101             * Depending on the scope, the value of <code>primKey</code> will have
102             * different meanings. For more information, see {@link
103             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
104             * </p>
105             *
106             * @param  companyId the primary key of the company
107             * @param  name the resource's name, which can be either a class name or a
108             *         portlet ID
109             * @param  scope the scope. This method only supports company, group, and
110             *         group-template scope.
111             * @param  primKey the primary key
112             * @param  roleId the primary key of the role
113             * @param  actionId the action ID
114             * @throws PortalException if scope was set to individual scope or if a role
115             *         with the primary key or a resource action with the name and
116             *         action ID could not be found
117             * @throws SystemException if a system exception occurred
118             */
119            public void addResourcePermission(
120                            long companyId, String name, int scope, String primKey, long roleId,
121                            String actionId)
122                    throws PortalException, SystemException {
123    
124                    if (scope == ResourceConstants.SCOPE_COMPANY) {
125    
126                            // Remove group permission
127    
128                            removeResourcePermissions(
129                                    companyId, name, ResourceConstants.SCOPE_GROUP, roleId,
130                                    actionId);
131                    }
132                    else if (scope == ResourceConstants.SCOPE_GROUP) {
133    
134                            // Remove company permission
135    
136                            removeResourcePermissions(
137                                    companyId, name, ResourceConstants.SCOPE_COMPANY, roleId,
138                                    actionId);
139                    }
140                    else if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
141                            throw new NoSuchResourcePermissionException();
142                    }
143    
144                    updateResourcePermission(
145                            companyId, name, scope, primKey, roleId, 0, new String[] {actionId},
146                            ResourcePermissionConstants.OPERATOR_ADD);
147    
148                    PermissionCacheUtil.clearCache();
149            }
150    
151            /**
152             * Grants the role permissions at the scope to perform the actions on all
153             * resources of the type. Existing actions are retained.
154             *
155             * <p>
156             * This method should only be used to add default permissions to existing
157             * resources en masse during upgrades or while verifying permissions. For
158             * example, this method could be used to grant site members individual scope
159             * permissions to view all blog posts.
160             * </p>
161             *
162             * @param  resourceName the resource's name, which can be either a class
163             *         name or a portlet ID
164             * @param  roleName the role's name
165             * @param  scope the scope
166             * @param  resourceActionBitwiseValue the bitwise IDs of the actions
167             * @throws SystemException if a system exception occurred
168             */
169            public void addResourcePermissions(
170                            String resourceName, String roleName, int scope,
171                            long resourceActionBitwiseValue)
172                    throws SystemException {
173    
174                    List<Role> roles = rolePersistence.findByName(roleName);
175    
176                    if (roles.isEmpty()) {
177                            return;
178                    }
179    
180                    Session session = resourcePermissionPersistence.openSession();
181    
182                    try {
183    
184                            // Update existing resource permissions
185    
186                            String sql = CustomSQLUtil.get(_UPDATE_ACTION_IDS);
187    
188                            sql = StringUtil.replace(
189                                    sql, "[$ROLE_ID$]",
190                                    ListUtil.toString(roles, Role.ROLE_ID_ACCESSOR));
191    
192                            SQLQuery sqlQuery = session.createSQLQuery(sql);
193    
194                            QueryPos qPos = QueryPos.getInstance(sqlQuery);
195    
196                            qPos.add(resourceActionBitwiseValue);
197                            qPos.add(resourceActionBitwiseValue);
198                            qPos.add(resourceName);
199                            qPos.add(scope);
200    
201                            sqlQuery.executeUpdate();
202    
203                            // Add missing resource permissions
204    
205                            sql = CustomSQLUtil.get(_FIND_MISSING_RESOURCE_PERMISSIONS);
206    
207                            sqlQuery = session.createSQLQuery(sql);
208    
209                            sqlQuery.addScalar("TEMP_TABLE.companyId", Type.LONG);
210                            sqlQuery.addScalar("TEMP_TABLE.name", Type.STRING);
211                            sqlQuery.addScalar("TEMP_TABLE.scope", Type.INTEGER);
212                            sqlQuery.addScalar("TEMP_TABLE.primKey", Type.STRING);
213                            sqlQuery.addScalar("Role_.roleId", Type.LONG);
214    
215                            qPos = QueryPos.getInstance(sqlQuery);
216    
217                            qPos.add(resourceName);
218                            qPos.add(scope);
219                            qPos.add(roleName);
220    
221                            List<Object[]> resourcePermissionArrays = sqlQuery.list(true);
222    
223                            if (resourcePermissionArrays.isEmpty()) {
224                                    return;
225                            }
226    
227                            for (Object[] resourcePermissionArray : resourcePermissionArrays) {
228                                    long resourcePermissionId = counterLocalService.increment(
229                                            ResourcePermission.class.getName());
230    
231                                    ResourcePermission resourcePermission =
232                                            resourcePermissionPersistence.create(resourcePermissionId);
233    
234                                    resourcePermission.setCompanyId(
235                                            (Long)resourcePermissionArray[0]);
236                                    resourcePermission.setName((String)resourcePermissionArray[1]);
237                                    resourcePermission.setScope(
238                                            (Integer)resourcePermissionArray[2]);
239                                    resourcePermission.setPrimKey(
240                                            (String)resourcePermissionArray[3]);
241                                    resourcePermission.setRoleId((Long)resourcePermissionArray[4]);
242                                    resourcePermission.setActionIds(resourceActionBitwiseValue);
243    
244                                    session.save(resourcePermission);
245                            }
246                    }
247                    catch (Exception e) {
248                            throw new SystemException(e);
249                    }
250                    finally {
251                            resourcePermissionPersistence.closeSession(session);
252    
253                            resourcePermissionPersistence.clearCache();
254                    }
255            }
256    
257            /**
258             * Deletes all resource permissions at the scope to resources of the type.
259             * This method should not be confused with any of the
260             * <code>removeResourcePermission</code> methods, as its purpose is very
261             * different. This method should only be used for deleting resource
262             * permissions that refer to a resource when that resource is deleted. For
263             * example this method could be used to delete all individual scope
264             * permissions to a blog post when it is deleted.
265             *
266             * <p>
267             * Depending on the scope, the value of <code>primKey</code> will have
268             * different meanings. For more information, see {@link
269             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
270             * </p>
271             *
272             * @param  companyId the primary key of the company
273             * @param  name the resource's name, which can be either a class name or a
274             *         portlet ID
275             * @param  scope the scope
276             * @param  primKey the primary key
277             * @throws PortalException if a portal exception occurred
278             * @throws SystemException if a system exception occurred
279             */
280            public void deleteResourcePermissions(
281                            long companyId, String name, int scope, long primKey)
282                    throws PortalException, SystemException {
283    
284                    deleteResourcePermissions(
285                            companyId, name, scope, String.valueOf(primKey));
286            }
287    
288            /**
289             * Deletes all resource permissions at the scope to resources of the type.
290             * This method should not be confused with any of the
291             * <code>removeResourcePermission</code> methods, as its purpose is very
292             * different. This method should only be used for deleting resource
293             * permissions that refer to a resource when that resource is deleted. For
294             * example this method could be used to delete all individual scope
295             * permissions to a blog post when it is deleted.
296             *
297             * <p>
298             * Depending on the scope, the value of <code>primKey</code> will have
299             * different meanings. For more information, see {@link
300             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
301             * </p>
302             *
303             * @param  companyId the primary key of the company
304             * @param  name the resource's name, which can be either a class name or a
305             *         portlet ID
306             * @param  scope the scope
307             * @param  primKey the primary key
308             * @throws PortalException if a portal exception occurred
309             * @throws SystemException if a system exception occurred
310             */
311            public void deleteResourcePermissions(
312                            long companyId, String name, int scope, String primKey)
313                    throws PortalException, SystemException {
314    
315                    List<ResourcePermission> resourcePermissions =
316                            resourcePermissionPersistence.findByC_N_S_P(
317                                    companyId, name, scope, primKey);
318    
319                    for (ResourcePermission resourcePermission : resourcePermissions) {
320                            deleteResourcePermission(
321                                    resourcePermission.getResourcePermissionId());
322                    }
323            }
324    
325            /**
326             * Returns the intersection of action IDs the role has permission at the
327             * scope to perform on resources of the type.
328             *
329             * @param  companyId he primary key of the company
330             * @param  name the resource's name, which can be either a class name or a
331             *         portlet ID
332             * @param  scope the scope
333             * @param  primKey the primary key
334             * @param  roleId the primary key of the role
335             * @param  actionIds the action IDs
336             * @return the intersection of action IDs the role has permission at the
337             *         scope to perform on resources of the type
338             * @throws PortalException if a resouce action could not be found for any
339             *         one of the actions on the resource
340             * @throws SystemException if a system exception occurred
341             */
342            public List<String> getAvailableResourcePermissionActionIds(
343                            long companyId, String name, int scope, String primKey, long roleId,
344                            Collection<String> actionIds)
345                    throws PortalException, SystemException {
346    
347                    ResourcePermission resourcePermission =
348                            resourcePermissionPersistence.fetchByC_N_S_P_R(
349                                    companyId, name, scope, primKey, roleId);
350    
351                    if (resourcePermission == null) {
352                            return Collections.emptyList();
353                    }
354    
355                    List<String> availableActionIds = new ArrayList<String>(
356                            actionIds.size());
357    
358                    for (String actionId : actionIds) {
359                            ResourceAction resourceAction =
360                                    resourceActionLocalService.getResourceAction(name, actionId);
361    
362                            if (hasActionId(resourcePermission, resourceAction)) {
363                                    availableActionIds.add(actionId);
364                            }
365                    }
366    
367                    return availableActionIds;
368            }
369    
370            public Map<Long, Set<String>> getAvailableResourcePermissionActionIds(
371                            long companyId, String name, int scope, String primKey,
372                            long[] roleIds, Collection<String> actionIds)
373                    throws PortalException, SystemException {
374    
375                    List<ResourcePermission> resourcePermissions =
376                            resourcePermissionPersistence.findByC_N_S_P_R(
377                                    companyId, name, scope, primKey, roleIds);
378    
379                    if (resourcePermissions.isEmpty()) {
380                            return Collections.emptyMap();
381                    }
382    
383                    Map<Long, Set<String>> roleIdsToActionIds =
384                            new HashMap<Long, Set<String>>();
385    
386                    for (ResourcePermission resourcePermission : resourcePermissions) {
387                            long roleId = resourcePermission.getRoleId();
388    
389                            Set<String> availableActionIds = roleIdsToActionIds.get(roleId);
390    
391                            if (availableActionIds != null) {
392                                    continue;
393                            }
394    
395                            availableActionIds = new HashSet<String>();
396    
397                            roleIdsToActionIds.put(roleId, availableActionIds);
398    
399                            for (String actionId : actionIds) {
400                                    ResourceAction resourceAction =
401                                            resourceActionLocalService.getResourceAction(
402                                                    name, actionId);
403    
404                                    if (hasActionId(resourcePermission, resourceAction)) {
405                                            availableActionIds.add(actionId);
406                                    }
407                            }
408                    }
409    
410                    return roleIdsToActionIds;
411            }
412    
413            /**
414             * Returns the resource permission for the role at the scope to perform the
415             * actions on resources of the type.
416             *
417             * @param  companyId the primary key of the company
418             * @param  name the resource's name, which can be either a class name or a
419             *         portlet ID
420             * @param  scope the scope
421             * @param  primKey the primary key
422             * @param  roleId the primary key of the role
423             * @return the resource permission for the role at the scope to perform the
424             *         actions on resources of the type
425             * @throws PortalException if no matching resources could be found
426             * @throws SystemException if a system exception occurred
427             */
428            public ResourcePermission getResourcePermission(
429                            long companyId, String name, int scope, String primKey, long roleId)
430                    throws PortalException, SystemException {
431    
432                    return resourcePermissionPersistence.findByC_N_S_P_R(
433                            companyId, name, scope, primKey, roleId);
434            }
435    
436            /**
437             * Returns all the resource permissions at the scope of the type.
438             *
439             * @param  companyId the primary key of the company
440             * @param  name the resource's name, which can be either a class name or a
441             *         portlet ID
442             * @param  scope the scope
443             * @param  primKey the primary key
444             * @return the resource permissions at the scope of the type
445             * @throws SystemException if a system exception occurred
446             */
447            public List<ResourcePermission> getResourcePermissions(
448                            long companyId, String name, int scope, String primKey)
449                    throws SystemException {
450    
451                    return resourcePermissionPersistence.findByC_N_S_P(
452                            companyId, name, scope, primKey);
453            }
454    
455            /**
456             * Returns the number of resource permissions at the scope of the type.
457             *
458             * @param  companyId the primary key of the company
459             * @param  name the resource's name, which can be either a class name or a
460             *         portlet ID
461             * @param  scope the scope
462             * @param  primKey the primary key
463             * @return the number of resource permissions at the scope of the type
464             * @throws SystemException if a system exception occurred
465             */
466            public int getResourcePermissionsCount(
467                            long companyId, String name, int scope, String primKey)
468                    throws SystemException {
469    
470                    return resourcePermissionPersistence.countByC_N_S_P(
471                            companyId, name, scope, primKey);
472            }
473    
474            /**
475             * Returns the resource permissions that apply to the resource.
476             *
477             * @param  companyId the primary key of the resource's company
478             * @param  groupId the primary key of the resource's group
479             * @param  name the resource's name, which can be either a class name or a
480             *         portlet ID
481             * @param  primKey the primary key of the resource
482             * @return the resource permissions associated with the resource
483             * @throws SystemException if a system exception occurred
484             */
485            public List<ResourcePermission> getResourceResourcePermissions(
486                            long companyId, long groupId, String name, String primKey)
487                    throws SystemException {
488    
489                    return resourcePermissionFinder.findByResource(
490                            companyId, groupId, name, primKey);
491            }
492    
493            /**
494             * Returns all the resource permissions for the role.
495             *
496             * @param  roleId the primary key of the role
497             * @return the resource permissions for the role
498             * @throws SystemException if a system exception occurred
499             */
500            public List<ResourcePermission> getRoleResourcePermissions(long roleId)
501                    throws SystemException {
502    
503                    return resourcePermissionPersistence.findByRoleId(roleId);
504            }
505    
506            /**
507             * Returns a range of all the resource permissions for the role at the
508             * scopes.
509             *
510             * <p>
511             * Useful when paginating results. Returns a maximum of <code>end -
512             * start</code> instances. <code>start</code> and <code>end</code> are not
513             * primary keys, they are indexes in the result set. Thus, <code>0</code>
514             * refers to the first result in the set. Setting both <code>start</code>
515             * and <code>end</code> to {@link
516             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
517             * result set.
518             * </p>
519             *
520             * @param  roleId the primary key of the role
521             * @param  scopes the scopes
522             * @param  start the lower bound of the range of results
523             * @param  end the upper bound of the range of results (not inclusive)
524             * @return the range of resource permissions for the role at the scopes
525             * @throws SystemException if a system exception occurred
526             */
527            public List<ResourcePermission> getRoleResourcePermissions(
528                            long roleId, int[] scopes, int start, int end)
529                    throws SystemException {
530    
531                    return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
532            }
533    
534            /**
535             * Returns all the resource permissions where scope = any &#63;.
536             *
537             * <p>
538             * Useful when paginating results. Returns a maximum of <code>end -
539             * start</code> instances. <code>start</code> and <code>end</code> are not
540             * primary keys, they are indexes in the result set. Thus, <code>0</code>
541             * refers to the first result in the set. Setting both <code>start</code>
542             * and <code>end</code> to {@link
543             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
544             * result set.
545             * </p>
546             *
547             * @param  scopes the scopes
548             * @return the resource permissions where scope = any &#63;
549             * @throws SystemException if a system exception occurred
550             */
551            public List<ResourcePermission> getScopeResourcePermissions(int[] scopes)
552                    throws SystemException {
553    
554                    return resourcePermissionPersistence.findByScope(scopes);
555            }
556    
557            /**
558             * Returns <code>true</code> if the resource permission grants permission to
559             * perform the resource action. Note that this method does not ensure that
560             * the resource permission refers to the same type of resource as the
561             * resource action.
562             *
563             * @param  resourcePermission the resource permission
564             * @param  resourceAction the resource action
565             * @return <code>true</code> if the resource permission grants permission to
566             *         perform the resource action
567             */
568            public boolean hasActionId(
569                    ResourcePermission resourcePermission, ResourceAction resourceAction) {
570    
571                    long actionIds = resourcePermission.getActionIds();
572                    long bitwiseValue = resourceAction.getBitwiseValue();
573    
574                    if ((actionIds & bitwiseValue) == bitwiseValue) {
575                            return true;
576                    }
577                    else {
578                            return false;
579                    }
580            }
581    
582            /**
583             * Returns <code>true</code> if the roles have permission at the scope to
584             * perform the action on the resources.
585             *
586             * <p>
587             * Depending on the scope, the value of <code>primKey</code> will have
588             * different meanings. For more information, see {@link
589             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
590             * </p>
591             *
592             * @param  resources the resources
593             * @param  roleIds the primary keys of the roles
594             * @param  actionId the action ID
595             * @return <code>true</code> if any one of the roles has permission to
596             *         perform the action on any one of the resources;
597             *         <code>false</code> otherwise
598             * @throws PortalException if any one of the roles with the primary keys
599             *         could not be found or if a resource action with the name and
600             *         action ID could not be found
601             * @throws SystemException if a system exception occurred
602             */
603            public boolean hasResourcePermission(
604                            List<Resource> resources, long[] roleIds, String actionId)
605                    throws PortalException, SystemException {
606    
607                    // Iterate the list of resources in reverse order to test permissions
608                    // from company scope to individual scope because it is more likely that
609                    // a permission is assigned at a higher scope. Optimizing this method
610                    // to one SQL call may actually slow things down since most of the calls
611                    // will pull from the cache after the first request.
612    
613                    for (int i = resources.size() - 1; i >= 0; i--) {
614                            Resource resource = resources.get(i);
615    
616                            if (hasResourcePermission(
617                                            resource.getCompanyId(), resource.getName(),
618                                            resource.getScope(), resource.getPrimKey(), roleIds,
619                                            actionId)) {
620    
621                                    return true;
622                            }
623                    }
624    
625                    return false;
626            }
627    
628            /**
629             * Returns <code>true</code> if the role has permission at the scope to
630             * perform the action on resources of the type.
631             *
632             * <p>
633             * Depending on the scope, the value of <code>primKey</code> will have
634             * different meanings. For more information, see {@link
635             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
636             * </p>
637             *
638             * @param  companyId the primary key of the company
639             * @param  name the resource's name, which can be either a class name or a
640             *         portlet ID
641             * @param  scope the scope
642             * @param  primKey the primary key
643             * @param  roleId the primary key of the role
644             * @param  actionId the action ID
645             * @return <code>true</code> if the role has permission to perform the
646             *         action on the resource; <code>false</code> otherwise
647             * @throws PortalException if a role with the primary key or a resource
648             *         action with the name and action ID could not be found
649             * @throws SystemException if a system exception occurred
650             */
651            public boolean hasResourcePermission(
652                            long companyId, String name, int scope, String primKey, long roleId,
653                            String actionId)
654                    throws PortalException, SystemException {
655    
656                    ResourcePermission resourcePermission =
657                            resourcePermissionPersistence.fetchByC_N_S_P_R(
658                                    companyId, name, scope, primKey, roleId);
659    
660                    if (resourcePermission == null) {
661                            return false;
662                    }
663    
664                    ResourceAction resourceAction =
665                            resourceActionLocalService.getResourceAction(name, actionId);
666    
667                    if (hasActionId(resourcePermission, resourceAction)) {
668                            return true;
669                    }
670    
671                    return false;
672            }
673    
674            /**
675             * Returns <code>true</code> if the roles have permission at the scope to
676             * perform the action on resources of the type.
677             *
678             * <p>
679             * Depending on the scope, the value of <code>primKey</code> will have
680             * different meanings. For more information, see {@link
681             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
682             * </p>
683             *
684             * @param  companyId the primary key of the company
685             * @param  name the resource's name, which can be either a class name or a
686             *         portlet ID
687             * @param  scope the scope
688             * @param  primKey the primary key
689             * @param  roleIds the primary keys of the roles
690             * @param  actionId the action ID
691             * @return <code>true</code> if any one of the roles has permission to
692             *         perform the action on the resource; <code>false</code> otherwise
693             * @throws PortalException if any one of the roles with the primary keys
694             *         could not be found or if a resource action with the name and
695             *         action ID could not be found
696             * @throws SystemException if a system exception occurred
697             */
698            public boolean hasResourcePermission(
699                            long companyId, String name, int scope, String primKey,
700                            long[] roleIds, String actionId)
701                    throws PortalException, SystemException {
702    
703                    ResourceAction resourceAction =
704                            resourceActionLocalService.getResourceAction(name, actionId);
705    
706                    DB db = DBFactoryUtil.getDB();
707    
708                    String dbType = db.getType();
709    
710                    if ((roleIds.length >
711                                    PropsValues.
712                                            PERMISSIONS_ROLE_RESOURCE_PERMISSION_QUERY_THRESHOLD) &&
713                            !dbType.equals(DB.TYPE_DERBY) &&
714                            !dbType.equals(DB.TYPE_JDATASTORE) &&
715                            !dbType.equals(DB.TYPE_SAP)) {
716    
717                            int count = resourcePermissionFinder.countByC_N_S_P_R_A(
718                                    companyId, name, scope, primKey, roleIds,
719                                    resourceAction.getBitwiseValue());
720    
721                            if (count > 0) {
722                                    return true;
723                            }
724                    }
725                    else {
726                            List<ResourcePermission> resourcePermissions =
727                                    resourcePermissionPersistence.findByC_N_S_P_R(
728                                            companyId, name, scope, primKey, roleIds);
729    
730                            if (resourcePermissions.isEmpty()) {
731                                    return false;
732                            }
733    
734                            for (ResourcePermission resourcePermission : resourcePermissions) {
735                                    if (hasActionId(resourcePermission, resourceAction)) {
736                                            return true;
737                                    }
738                            }
739    
740                    }
741    
742                    return false;
743            }
744    
745            public boolean[] hasResourcePermissions(
746                            long companyId, String name, int scope, String primKey,
747                            long[] roleIds, String actionId)
748                    throws PortalException, SystemException {
749    
750                    ResourceAction resourceAction =
751                            resourceActionLocalService.getResourceAction(name, actionId);
752    
753                    List<ResourcePermission> resourcePermissions =
754                            resourcePermissionPersistence.findByC_N_S_P_R(
755                                    companyId, name, scope, primKey, roleIds);
756    
757                    boolean[] hasResourcePermissions = new boolean[roleIds.length];
758    
759                    if (resourcePermissions.isEmpty()) {
760                            return hasResourcePermissions;
761                    }
762    
763                    for (ResourcePermission resourcePermission : resourcePermissions) {
764                            if (hasActionId(resourcePermission, resourceAction)) {
765                                    long roleId = resourcePermission.getRoleId();
766    
767                                    for (int i = 0; i < roleIds.length; i++) {
768                                            if (roleIds[i] == roleId) {
769                                                    hasResourcePermissions[i] = true;
770                                            }
771                                    }
772                            }
773                    }
774    
775                    return hasResourcePermissions;
776            }
777    
778            /**
779             * Returns <code>true</code> if the role has permission at the scope to
780             * perform the action on the resource.
781             *
782             * <p>
783             * Depending on the scope, the value of <code>primKey</code> will have
784             * different meanings. For more information, see {@link
785             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
786             * </p>
787             *
788             * @param  companyId the primary key of the company
789             * @param  name the resource's name, which can be either a class name or a
790             *         portlet ID
791             * @param  scope the scope
792             * @param  roleId the primary key of the role
793             * @param  actionId the action ID
794             * @return <code>true</code> if the role has permission to perform the
795             *         action on the resource; <code>false</code> otherwise
796             * @throws PortalException if a role with the primary key or a resource
797             *         action with the name and action ID could not be found
798             * @throws SystemException if a system exception occurred
799             */
800            public boolean hasScopeResourcePermission(
801                            long companyId, String name, int scope, long roleId,
802                            String actionId)
803                    throws PortalException, SystemException {
804    
805                    List<ResourcePermission> resourcePermissions =
806                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
807    
808                    for (ResourcePermission resourcePermission : resourcePermissions) {
809                            if (hasResourcePermission(
810                                            companyId, name, scope, resourcePermission.getPrimKey(),
811                                            roleId, actionId)) {
812    
813                                    return true;
814                            }
815                    }
816    
817                    return false;
818            }
819    
820            /**
821             * Reassigns all the resource permissions from the source role to the
822             * destination role, and deletes the source role.
823             *
824             * @param  fromRoleId the primary key of the source role
825             * @param  toRoleId the primary key of the destination role
826             * @throws PortalException if a role with the primary key could not be found
827             * @throws SystemException if a system exception occurred
828             */
829            public void mergePermissions(long fromRoleId, long toRoleId)
830                    throws PortalException, SystemException {
831    
832                    Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
833                    Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
834    
835                    if (fromRole.getType() != toRole.getType()) {
836                            throw new PortalException("Role types are mismatched");
837                    }
838                    else if (PortalUtil.isSystemRole(toRole.getName())) {
839                            throw new PortalException("Cannot move permissions to system role");
840                    }
841                    else if (PortalUtil.isSystemRole(fromRole.getName())) {
842                            throw new PortalException(
843                                    "Cannot move permissions from system role");
844                    }
845    
846                    List<ResourcePermission> resourcePermissions =
847                            getRoleResourcePermissions(fromRoleId);
848    
849                    for (ResourcePermission resourcePermission : resourcePermissions) {
850                            resourcePermission.setRoleId(toRoleId);
851    
852                            resourcePermissionPersistence.update(resourcePermission);
853                    }
854    
855                    roleLocalService.deleteRole(fromRoleId);
856    
857                    PermissionCacheUtil.clearCache();
858            }
859    
860            /**
861             * Grants the role default permissions to all the resources of the type and
862             * at the scope stored in the resource permission, deletes the resource
863             * permission, and deletes the resource permission's role if it has no
864             * permissions remaining.
865             *
866             * @param  resourcePermissionId the primary key of the resource permission
867             * @param  toRoleId the primary key of the role
868             * @throws PortalException if a resource permission or role with the primary
869             *         key could not be found
870             * @throws SystemException if a system exception occurred
871             */
872            public void reassignPermissions(long resourcePermissionId, long toRoleId)
873                    throws PortalException, SystemException {
874    
875                    ResourcePermission resourcePermission = getResourcePermission(
876                            resourcePermissionId);
877    
878                    long companyId = resourcePermission.getCompanyId();
879                    String name = resourcePermission.getName();
880                    int scope = resourcePermission.getScope();
881                    String primKey = resourcePermission.getPrimKey();
882                    long fromRoleId = resourcePermission.getRoleId();
883    
884                    Role toRole = roleLocalService.getRole(toRoleId);
885    
886                    List<String> actionIds = null;
887    
888                    if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
889                            actionIds = ResourceActionsUtil.getModelResourceActions(name);
890                    }
891                    else {
892                            actionIds = ResourceActionsUtil.getModelResourceGroupDefaultActions(
893                                    name);
894                    }
895    
896                    setResourcePermissions(
897                            companyId, name, scope, primKey, toRoleId,
898                            actionIds.toArray(new String[actionIds.size()]));
899    
900                    resourcePermissionPersistence.remove(resourcePermissionId);
901    
902                    List<ResourcePermission> resourcePermissions =
903                            getRoleResourcePermissions(fromRoleId);
904    
905                    if (resourcePermissions.isEmpty()) {
906                            roleLocalService.deleteRole(fromRoleId);
907                    }
908            }
909    
910            /**
911             * Revokes permission at the scope from the role to perform the action on
912             * resources of the type. For example, this method could be used to revoke a
913             * group scope permission to edit blog posts.
914             *
915             * <p>
916             * Depending on the scope, the value of <code>primKey</code> will have
917             * different meanings. For more information, see {@link
918             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
919             * </p>
920             *
921             * @param  companyId the primary key of the company
922             * @param  name the resource's name, which can be either a class name or a
923             *         portlet ID
924             * @param  scope the scope
925             * @param  primKey the primary key
926             * @param  roleId the primary key of the role
927             * @param  actionId the action ID
928             * @throws PortalException if a role with the primary key or a resource
929             *         action with the name and action ID could not be found
930             * @throws SystemException if a system exception occurred
931             */
932            public void removeResourcePermission(
933                            long companyId, String name, int scope, String primKey, long roleId,
934                            String actionId)
935                    throws PortalException, SystemException {
936    
937                    updateResourcePermission(
938                            companyId, name, scope, primKey, roleId, 0, new String[] {actionId},
939                            ResourcePermissionConstants.OPERATOR_REMOVE);
940    
941                    PermissionCacheUtil.clearCache();
942            }
943    
944            /**
945             * Revokes all permissions at the scope from the role to perform the action
946             * on resources of the type. For example, this method could be used to
947             * revoke all individual scope permissions to edit blog posts from site
948             * members.
949             *
950             * @param  companyId the primary key of the company
951             * @param  name the resource's name, which can be either a class name or a
952             *         portlet ID
953             * @param  scope the scope
954             * @param  roleId the primary key of the role
955             * @param  actionId the action ID
956             * @throws PortalException if a role with the primary key or a resource
957             *         action with the name and action ID could not be found
958             * @throws SystemException if a system exception occurred
959             */
960            public void removeResourcePermissions(
961                            long companyId, String name, int scope, long roleId,
962                            String actionId)
963                    throws PortalException, SystemException {
964    
965                    List<ResourcePermission> resourcePermissions =
966                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
967    
968                    for (ResourcePermission resourcePermission : resourcePermissions) {
969                            updateResourcePermission(
970                                    companyId, name, scope, resourcePermission.getPrimKey(), roleId,
971                                    0, new String[] {actionId},
972                                    ResourcePermissionConstants.OPERATOR_REMOVE);
973                    }
974    
975                    PermissionCacheUtil.clearCache();
976            }
977    
978            /**
979             * Updates the role's permissions at the scope, setting the actions that can
980             * be performed on resources of the type, also setting the owner of any
981             * newly created resource permissions. Existing actions are replaced.
982             *
983             * <p>
984             * This method can be used to set permissions at any scope, but it is
985             * generally only used at the individual scope. For example, it could be
986             * used to set the guest permissions on a blog post.
987             * </p>
988             *
989             * <p>
990             * Depending on the scope, the value of <code>primKey</code> will have
991             * different meanings. For more information, see {@link
992             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
993             * </p>
994             *
995             * @param  companyId the primary key of the company
996             * @param  name the resource's name, which can be either a class name or a
997             *         portlet ID
998             * @param  scope the scope
999             * @param  primKey the primary key
1000             * @param  roleId the primary key of the role
1001             * @param  ownerId the primary key of the owner (generally the user that
1002             *         created the resource)
1003             * @param  actionIds the action IDs of the actions
1004             * @throws PortalException if a role with the primary key or a resource
1005             *         action with the name and action ID could not be found
1006             * @throws SystemException if a system exception occurred
1007             */
1008            public void setOwnerResourcePermissions(
1009                            long companyId, String name, int scope, String primKey, long roleId,
1010                            long ownerId, String[] actionIds)
1011                    throws PortalException, SystemException {
1012    
1013                    updateResourcePermission(
1014                            companyId, name, scope, primKey, roleId, ownerId, actionIds,
1015                            ResourcePermissionConstants.OPERATOR_SET);
1016            }
1017    
1018            /**
1019             * Updates the role's permissions at the scope, setting the actions that can
1020             * be performed on resources of the type. Existing actions are replaced.
1021             *
1022             * <p>
1023             * This method can be used to set permissions at any scope, but it is
1024             * generally only used at the individual scope. For example, it could be
1025             * used to set the guest permissions on a blog post.
1026             * </p>
1027             *
1028             * <p>
1029             * Depending on the scope, the value of <code>primKey</code> will have
1030             * different meanings. For more information, see {@link
1031             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1032             * </p>
1033             *
1034             * @param  companyId the primary key of the company
1035             * @param  name the resource's name, which can be either a class name or a
1036             *         portlet ID
1037             * @param  scope the scope
1038             * @param  primKey the primary key
1039             * @param  roleId the primary key of the role
1040             * @param  actionIds the action IDs of the actions
1041             * @throws PortalException if a role with the primary key or a resource
1042             *         action with the name and action ID could not be found
1043             * @throws SystemException if a system exception occurred
1044             */
1045            public void setResourcePermissions(
1046                            long companyId, String name, int scope, String primKey, long roleId,
1047                            String[] actionIds)
1048                    throws PortalException, SystemException {
1049    
1050                    updateResourcePermission(
1051                            companyId, name, scope, primKey, roleId, 0, actionIds,
1052                            ResourcePermissionConstants.OPERATOR_SET);
1053            }
1054    
1055            /**
1056             * Updates the role's permissions at the scope, setting the actions that can
1057             * be performed on resources of the type. Existing actions are replaced.
1058             *
1059             * <p>
1060             * This method can be used to set permissions at any scope, but it is
1061             * generally only used at the individual scope. For example, it could be
1062             * used to set the guest permissions on a blog post.
1063             * </p>
1064             *
1065             * <p>
1066             * Depending on the scope, the value of <code>primKey</code> will have
1067             * different meanings. For more information, see {@link
1068             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1069             * </p>
1070             *
1071             * @param  companyId the primary key of the company
1072             * @param  name the resource's name, which can be either a class name or a
1073             *         portlet ID
1074             * @param  scope the scope
1075             * @param  primKey the primary key
1076             * @param  roleIdsToActionIds a map of role IDs to action IDs of the actions
1077             * @throws PortalException if a role with the primary key or a resource
1078             *         action with the name and action ID could not be found
1079             * @throws SystemException if a system exception occurred
1080             */
1081            public void setResourcePermissions(
1082                            long companyId, String name, int scope, String primKey,
1083                            Map<Long, String[]> roleIdsToActionIds)
1084                    throws PortalException, SystemException {
1085    
1086                    updateResourcePermission(
1087                            companyId, name, scope, primKey, 0, roleIdsToActionIds,
1088                            ResourcePermissionConstants.OPERATOR_SET);
1089            }
1090    
1091            protected void doUpdateResourcePermission(
1092                            long companyId, String name, int scope, String primKey,
1093                            long ownerId, long roleId, String[] actionIds, int operator)
1094                    throws PortalException, SystemException {
1095    
1096                    ResourcePermission resourcePermission = null;
1097    
1098                    Map<Long, ResourcePermission> resourcePermissionsMap =
1099                            ResourcePermissionsThreadLocal.getResourcePermissions();
1100    
1101                    if (resourcePermissionsMap != null) {
1102                            resourcePermission = resourcePermissionsMap.get(roleId);
1103                    }
1104                    else {
1105                            resourcePermission = resourcePermissionPersistence.fetchByC_N_S_P_R(
1106                                    companyId, name, scope, primKey, roleId);
1107                    }
1108    
1109                    if (resourcePermission == null) {
1110                            if (((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1111                                     (operator == ResourcePermissionConstants.OPERATOR_SET)) &&
1112                                    (actionIds.length == 0)) {
1113    
1114                                    return;
1115                            }
1116    
1117                            if (operator == ResourcePermissionConstants.OPERATOR_REMOVE) {
1118                                    return;
1119                            }
1120    
1121                            long resourcePermissionId = counterLocalService.increment(
1122                                    ResourcePermission.class.getName());
1123    
1124                            resourcePermission = resourcePermissionPersistence.create(
1125                                    resourcePermissionId);
1126    
1127                            resourcePermission.setCompanyId(companyId);
1128                            resourcePermission.setName(name);
1129                            resourcePermission.setScope(scope);
1130                            resourcePermission.setPrimKey(primKey);
1131                            resourcePermission.setRoleId(roleId);
1132                            resourcePermission.setOwnerId(ownerId);
1133                    }
1134    
1135                    long actionIdsLong = resourcePermission.getActionIds();
1136    
1137                    if (operator == ResourcePermissionConstants.OPERATOR_SET) {
1138                            actionIdsLong = 0;
1139                    }
1140    
1141                    for (String actionId : actionIds) {
1142                            if (actionId == null) {
1143                                    break;
1144                            }
1145    
1146                            ResourceAction resourceAction =
1147                                    resourceActionLocalService.getResourceAction(name, actionId);
1148    
1149                            if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1150                                    (operator == ResourcePermissionConstants.OPERATOR_SET)) {
1151    
1152                                    actionIdsLong |= resourceAction.getBitwiseValue();
1153                            }
1154                            else {
1155                                    actionIdsLong =
1156                                            actionIdsLong & (~resourceAction.getBitwiseValue());
1157                            }
1158                    }
1159    
1160                    resourcePermission.setActionIds(actionIdsLong);
1161    
1162                    resourcePermissionPersistence.update(resourcePermission);
1163    
1164                    PermissionCacheUtil.clearCache();
1165    
1166                    SearchEngineUtil.updatePermissionFields(name, primKey);
1167            }
1168    
1169            protected void doUpdateResourcePermission(
1170                            long companyId, String name, int scope, String primKey,
1171                            long ownerId, Map<Long, String[]> roleIdsToActionIds, int operator)
1172                    throws PortalException, SystemException {
1173    
1174                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
1175    
1176                    PermissionThreadLocal.setIndexEnabled(false);
1177    
1178                    try {
1179                            for (Map.Entry<Long, String[]> entry :
1180                                            roleIdsToActionIds.entrySet()) {
1181    
1182                                    long roleId = entry.getKey();
1183                                    String[] actionIds = entry.getValue();
1184    
1185                                    doUpdateResourcePermission(
1186                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1187                                            operator);
1188                            }
1189                    }
1190                    finally {
1191                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
1192    
1193                            PermissionCacheUtil.clearCache();
1194    
1195                            SearchEngineUtil.updatePermissionFields(name, primKey);
1196                    }
1197            }
1198    
1199            /**
1200             * Updates the role's permissions at the scope, either adding to, removing
1201             * from, or setting the actions that can be performed on resources of the
1202             * type. Automatically creates a new resource permission if none exists, or
1203             * deletes the existing resource permission if it no longer grants
1204             * permissions to perform any action.
1205             *
1206             * <p>
1207             * Depending on the scope, the value of <code>primKey</code> will have
1208             * different meanings. For more information, see {@link
1209             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1210             * </p>
1211             *
1212             * @param  companyId the primary key of the company
1213             * @param  name the resource's name, which can be either a class name or a
1214             *         portlet ID
1215             * @param  scope the scope
1216             * @param  primKey the primary key
1217             * @param  roleId the primary key of the role
1218             * @param  ownerId the primary key of the owner
1219             * @param  actionIds the action IDs of the actions
1220             * @param  operator whether to add to, remove from, or set/replace the
1221             *         existing actions. Possible values can be found in {@link
1222             *         ResourcePermissionConstants}.
1223             * @throws PortalException if a role with the primary key or a resource
1224             *         action with the name and action ID could not be found
1225             * @throws SystemException if a system exception occurred
1226             */
1227            protected void updateResourcePermission(
1228                            long companyId, String name, int scope, String primKey, long roleId,
1229                            long ownerId, String[] actionIds, int operator)
1230                    throws PortalException, SystemException {
1231    
1232                    DB db = DBFactoryUtil.getDB();
1233    
1234                    String dbType = db.getType();
1235    
1236                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1237                            doUpdateResourcePermission(
1238                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1239                                    operator);
1240    
1241                            return;
1242                    }
1243    
1244                    StringBundler sb = new StringBundler(9);
1245    
1246                    sb.append(companyId);
1247                    sb.append(StringPool.POUND);
1248                    sb.append(name);
1249                    sb.append(StringPool.POUND);
1250                    sb.append(scope);
1251                    sb.append(StringPool.POUND);
1252                    sb.append(primKey);
1253                    sb.append(StringPool.POUND);
1254                    sb.append(roleId);
1255    
1256                    Class<?> clazz = getClass();
1257    
1258                    String groupName = clazz.getName();
1259    
1260                    String key = sb.toString();
1261    
1262                    Lock lock = LockRegistry.allocateLock(groupName, key);
1263    
1264                    lock.lock();
1265    
1266                    try {
1267                            doUpdateResourcePermission(
1268                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1269                                    operator);
1270                    }
1271                    finally {
1272                            lock.unlock();
1273    
1274                            LockRegistry.freeLock(groupName, key);
1275                    }
1276            }
1277    
1278            /**
1279             * Updates the role's permissions at the scope, either adding to, removing
1280             * from, or setting the actions that can be performed on resources of the
1281             * type. Automatically creates a new resource permission if none exists, or
1282             * deletes the existing resource permission if it no longer grants
1283             * permissions to perform any action.
1284             *
1285             * <p>
1286             * Depending on the scope, the value of <code>primKey</code> will have
1287             * different meanings. For more information, see {@link
1288             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1289             * </p>
1290             *
1291             * @param  companyId the primary key of the company
1292             * @param  name the resource's name, which can be either a class name or a
1293             *         portlet ID
1294             * @param  scope the scope
1295             * @param  primKey the primary key
1296             * @param  ownerId the primary key of the owner
1297             * @param  operator whether to add to, remove from, or set/replace the
1298             *         existing actions. Possible values can be found in {@link
1299             *         ResourcePermissionConstants}.
1300             * @throws PortalException if a role with the primary key or a resource
1301             *         action with the name and action ID could not be found
1302             * @throws SystemException if a system exception occurred
1303             */
1304            protected void updateResourcePermission(
1305                            long companyId, String name, int scope, String primKey,
1306                            long ownerId, Map<Long, String[]> roleIdsToActionIds, int operator)
1307                    throws PortalException, SystemException {
1308    
1309                    DB db = DBFactoryUtil.getDB();
1310    
1311                    String dbType = db.getType();
1312    
1313                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1314                            doUpdateResourcePermission(
1315                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds,
1316                                    operator);
1317    
1318                            return;
1319                    }
1320    
1321                    StringBundler sb = new StringBundler(9);
1322    
1323                    sb.append(companyId);
1324                    sb.append(StringPool.POUND);
1325                    sb.append(name);
1326                    sb.append(StringPool.POUND);
1327                    sb.append(scope);
1328                    sb.append(StringPool.POUND);
1329                    sb.append(primKey);
1330                    sb.append(StringPool.POUND);
1331                    sb.append(StringUtil.merge(roleIdsToActionIds.keySet()));
1332    
1333                    Class<?> clazz = getClass();
1334    
1335                    String groupName = clazz.getName();
1336    
1337                    String key = sb.toString();
1338    
1339                    Lock lock = LockRegistry.allocateLock(groupName, key);
1340    
1341                    lock.lock();
1342    
1343                    try {
1344                            doUpdateResourcePermission(
1345                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds,
1346                                    operator);
1347                    }
1348                    finally {
1349                            lock.unlock();
1350    
1351                            LockRegistry.freeLock(groupName, key);
1352                    }
1353            }
1354    
1355            private static final String _FIND_MISSING_RESOURCE_PERMISSIONS =
1356                    ResourcePermissionLocalServiceImpl.class.getName() +
1357                            ".findMissingResourcePermissions";
1358    
1359            private static final String _UPDATE_ACTION_IDS =
1360                    ResourcePermissionLocalServiceImpl.class.getName() + ".updateActionIds";
1361    
1362    }