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