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                    if (roleIds.length == 0) {
634                            return false;
635                    }
636    
637                    // Iterate the list of resources in reverse order to test permissions
638                    // from company scope to individual scope because it is more likely that
639                    // a permission is assigned at a higher scope. Optimizing this method to
640                    // one SQL call may actually slow things down since most of the calls
641                    // will pull from the cache after the first request.
642    
643                    for (int i = resources.size() - 1; i >= 0; i--) {
644                            Resource resource = resources.get(i);
645    
646                            if (hasResourcePermission(
647                                            resource.getCompanyId(), resource.getName(),
648                                            resource.getScope(), resource.getPrimKey(), roleIds,
649                                            actionId)) {
650    
651                                    return true;
652                            }
653                    }
654    
655                    return false;
656            }
657    
658            /**
659             * Returns <code>true</code> if the role has permission at the scope to
660             * perform the action on resources of the type.
661             *
662             * <p>
663             * Depending on the scope, the value of <code>primKey</code> will have
664             * different meanings. For more information, see {@link
665             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
666             * </p>
667             *
668             * @param  companyId the primary key of the company
669             * @param  name the resource's name, which can be either a class name or a
670             *         portlet ID
671             * @param  scope the scope
672             * @param  primKey the primary key
673             * @param  roleId the primary key of the role
674             * @param  actionId the action ID
675             * @return <code>true</code> if the role has permission to perform the
676             *         action on the resource; <code>false</code> otherwise
677             * @throws PortalException if a role with the primary key or a resource
678             *         action with the name and action ID could not be found
679             * @throws SystemException if a system exception occurred
680             */
681            @Override
682            public boolean hasResourcePermission(
683                            long companyId, String name, int scope, String primKey, long roleId,
684                            String actionId)
685                    throws PortalException, SystemException {
686    
687                    ResourcePermission resourcePermission =
688                            resourcePermissionPersistence.fetchByC_N_S_P_R(
689                                    companyId, name, scope, primKey, roleId);
690    
691                    if (resourcePermission == null) {
692                            return false;
693                    }
694    
695                    ResourceAction resourceAction =
696                            resourceActionLocalService.getResourceAction(name, actionId);
697    
698                    if (hasActionId(resourcePermission, resourceAction)) {
699                            return true;
700                    }
701    
702                    return false;
703            }
704    
705            /**
706             * Returns <code>true</code> if the roles have permission at the scope to
707             * perform the action on resources of the type.
708             *
709             * <p>
710             * Depending on the scope, the value of <code>primKey</code> will have
711             * different meanings. For more information, see {@link
712             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
713             * </p>
714             *
715             * @param  companyId the primary key of the company
716             * @param  name the resource's name, which can be either a class name or a
717             *         portlet ID
718             * @param  scope the scope
719             * @param  primKey the primary key
720             * @param  roleIds the primary keys of the roles
721             * @param  actionId the action ID
722             * @return <code>true</code> if any one of the roles has permission to
723             *         perform the action on the resource; <code>false</code> otherwise
724             * @throws PortalException if any one of the roles with the primary keys
725             *         could not be found or if a resource action with the name and
726             *         action ID could not be found
727             * @throws SystemException if a system exception occurred
728             */
729            @Override
730            public boolean hasResourcePermission(
731                            long companyId, String name, int scope, String primKey,
732                            long[] roleIds, String actionId)
733                    throws PortalException, SystemException {
734    
735                    if (roleIds.length == 0) {
736                            return false;
737                    }
738    
739                    ResourceAction resourceAction =
740                            resourceActionLocalService.getResourceAction(name, actionId);
741    
742                    DB db = DBFactoryUtil.getDB();
743    
744                    String dbType = db.getType();
745    
746                    if ((roleIds.length >
747                                    PropsValues.
748                                            PERMISSIONS_ROLE_RESOURCE_PERMISSION_QUERY_THRESHOLD) &&
749                            !dbType.equals(DB.TYPE_DERBY) &&
750                            !dbType.equals(DB.TYPE_JDATASTORE) &&
751                            !dbType.equals(DB.TYPE_SAP)) {
752    
753                            int count = resourcePermissionFinder.countByC_N_S_P_R_A(
754                                    companyId, name, scope, primKey, roleIds,
755                                    resourceAction.getBitwiseValue());
756    
757                            if (count > 0) {
758                                    return true;
759                            }
760                    }
761                    else {
762                            List<ResourcePermission> resourcePermissions =
763                                    resourcePermissionPersistence.findByC_N_S_P_R(
764                                            companyId, name, scope, primKey, roleIds);
765    
766                            if (resourcePermissions.isEmpty()) {
767                                    return false;
768                            }
769    
770                            for (ResourcePermission resourcePermission : resourcePermissions) {
771                                    if (hasActionId(resourcePermission, resourceAction)) {
772                                            return true;
773                                    }
774                            }
775                    }
776    
777                    return false;
778            }
779    
780            @Override
781            public boolean[] hasResourcePermissions(
782                            long companyId, String name, int scope, String primKey,
783                            long[] roleIds, String actionId)
784                    throws PortalException, SystemException {
785    
786                    boolean[] hasResourcePermissions = new boolean[roleIds.length];
787    
788                    if (roleIds.length == 0) {
789                            return hasResourcePermissions;
790                    }
791    
792                    ResourceAction resourceAction =
793                            resourceActionLocalService.getResourceAction(name, actionId);
794    
795                    List<ResourcePermission> resourcePermissions =
796                            resourcePermissionPersistence.findByC_N_S_P_R(
797                                    companyId, name, scope, primKey, roleIds);
798    
799                    if (resourcePermissions.isEmpty()) {
800                            return hasResourcePermissions;
801                    }
802    
803                    for (ResourcePermission resourcePermission : resourcePermissions) {
804                            if (hasActionId(resourcePermission, resourceAction)) {
805                                    long roleId = resourcePermission.getRoleId();
806    
807                                    for (int i = 0; i < roleIds.length; i++) {
808                                            if (roleIds[i] == roleId) {
809                                                    hasResourcePermissions[i] = true;
810                                            }
811                                    }
812                            }
813                    }
814    
815                    return hasResourcePermissions;
816            }
817    
818            /**
819             * Returns <code>true</code> if the role has permission at the scope to
820             * perform the action on the resource.
821             *
822             * <p>
823             * Depending on the scope, the value of <code>primKey</code> will have
824             * different meanings. For more information, see {@link
825             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
826             * </p>
827             *
828             * @param  companyId the primary key of the company
829             * @param  name the resource's name, which can be either a class name or a
830             *         portlet ID
831             * @param  scope the scope
832             * @param  roleId the primary key of the role
833             * @param  actionId the action ID
834             * @return <code>true</code> if the role has permission to perform the
835             *         action on the resource; <code>false</code> otherwise
836             * @throws PortalException if a role with the primary key or a resource
837             *         action with the name and action ID could not be found
838             * @throws SystemException if a system exception occurred
839             */
840            @Override
841            public boolean hasScopeResourcePermission(
842                            long companyId, String name, int scope, long roleId,
843                            String actionId)
844                    throws PortalException, SystemException {
845    
846                    List<ResourcePermission> resourcePermissions =
847                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
848    
849                    for (ResourcePermission resourcePermission : resourcePermissions) {
850                            if (hasResourcePermission(
851                                            companyId, name, scope, resourcePermission.getPrimKey(),
852                                            roleId, actionId)) {
853    
854                                    return true;
855                            }
856                    }
857    
858                    return false;
859            }
860    
861            /**
862             * Reassigns all the resource permissions from the source role to the
863             * destination role, and deletes the source role.
864             *
865             * @param  fromRoleId the primary key of the source role
866             * @param  toRoleId the primary key of the destination role
867             * @throws PortalException if a role with the primary key could not be found
868             * @throws SystemException if a system exception occurred
869             */
870            @Override
871            public void mergePermissions(long fromRoleId, long toRoleId)
872                    throws PortalException, SystemException {
873    
874                    Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
875                    Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
876    
877                    if (fromRole.getType() != toRole.getType()) {
878                            throw new PortalException("Role types are mismatched");
879                    }
880                    else if (PortalUtil.isSystemRole(toRole.getName())) {
881                            throw new PortalException("Cannot move permissions to system role");
882                    }
883                    else if (PortalUtil.isSystemRole(fromRole.getName())) {
884                            throw new PortalException(
885                                    "Cannot move permissions from system role");
886                    }
887    
888                    List<ResourcePermission> resourcePermissions =
889                            getRoleResourcePermissions(fromRoleId);
890    
891                    for (ResourcePermission resourcePermission : resourcePermissions) {
892                            resourcePermission.setRoleId(toRoleId);
893    
894                            resourcePermissionPersistence.update(resourcePermission);
895                    }
896    
897                    roleLocalService.deleteRole(fromRoleId);
898    
899                    PermissionCacheUtil.clearCache();
900            }
901    
902            /**
903             * Grants the role default permissions to all the resources of the type and
904             * at the scope stored in the resource permission, deletes the resource
905             * permission, and deletes the resource permission's role if it has no
906             * permissions remaining.
907             *
908             * @param  resourcePermissionId the primary key of the resource permission
909             * @param  toRoleId the primary key of the role
910             * @throws PortalException if a resource permission or role with the primary
911             *         key could not be found
912             * @throws SystemException if a system exception occurred
913             */
914            @Override
915            public void reassignPermissions(long resourcePermissionId, long toRoleId)
916                    throws PortalException, SystemException {
917    
918                    ResourcePermission resourcePermission = getResourcePermission(
919                            resourcePermissionId);
920    
921                    long companyId = resourcePermission.getCompanyId();
922                    String name = resourcePermission.getName();
923                    int scope = resourcePermission.getScope();
924                    String primKey = resourcePermission.getPrimKey();
925                    long fromRoleId = resourcePermission.getRoleId();
926    
927                    Role toRole = roleLocalService.getRole(toRoleId);
928    
929                    List<String> actionIds = null;
930    
931                    if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
932                            actionIds = ResourceActionsUtil.getModelResourceActions(name);
933                    }
934                    else {
935                            actionIds = ResourceActionsUtil.getModelResourceGroupDefaultActions(
936                                    name);
937                    }
938    
939                    setResourcePermissions(
940                            companyId, name, scope, primKey, toRoleId,
941                            actionIds.toArray(new String[actionIds.size()]));
942    
943                    resourcePermissionPersistence.remove(resourcePermissionId);
944    
945                    List<ResourcePermission> resourcePermissions =
946                            getRoleResourcePermissions(fromRoleId);
947    
948                    if (resourcePermissions.isEmpty()) {
949                            roleLocalService.deleteRole(fromRoleId);
950                    }
951            }
952    
953            /**
954             * Revokes permission at the scope from the role to perform the action on
955             * resources of the type. For example, this method could be used to revoke a
956             * group scope permission to edit blog posts.
957             *
958             * <p>
959             * Depending on the scope, the value of <code>primKey</code> will have
960             * different meanings. For more information, see {@link
961             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
962             * </p>
963             *
964             * @param  companyId the primary key of the company
965             * @param  name the resource's name, which can be either a class name or a
966             *         portlet ID
967             * @param  scope the scope
968             * @param  primKey the primary key
969             * @param  roleId the primary key of the role
970             * @param  actionId the action ID
971             * @throws PortalException if a role with the primary key or a resource
972             *         action with the name and action ID could not be found
973             * @throws SystemException if a system exception occurred
974             */
975            @Override
976            public void removeResourcePermission(
977                            long companyId, String name, int scope, String primKey, long roleId,
978                            String actionId)
979                    throws PortalException, SystemException {
980    
981                    updateResourcePermission(
982                            companyId, name, scope, primKey, roleId, 0, new String[] {actionId},
983                            ResourcePermissionConstants.OPERATOR_REMOVE);
984    
985                    PermissionCacheUtil.clearCache();
986            }
987    
988            /**
989             * Revokes all permissions at the scope from the role to perform the action
990             * on resources of the type. For example, this method could be used to
991             * revoke all individual scope permissions to edit blog posts from site
992             * members.
993             *
994             * @param  companyId the primary key of the company
995             * @param  name the resource's name, which can be either a class name or a
996             *         portlet ID
997             * @param  scope the scope
998             * @param  roleId the primary key of the role
999             * @param  actionId the action ID
1000             * @throws PortalException if a role with the primary key or a resource
1001             *         action with the name and action ID could not be found
1002             * @throws SystemException if a system exception occurred
1003             */
1004            @Override
1005            public void removeResourcePermissions(
1006                            long companyId, String name, int scope, long roleId,
1007                            String actionId)
1008                    throws PortalException, SystemException {
1009    
1010                    List<ResourcePermission> resourcePermissions =
1011                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
1012    
1013                    for (ResourcePermission resourcePermission : resourcePermissions) {
1014                            updateResourcePermission(
1015                                    companyId, name, scope, resourcePermission.getPrimKey(), roleId,
1016                                    0, new String[] {actionId},
1017                                    ResourcePermissionConstants.OPERATOR_REMOVE);
1018                    }
1019    
1020                    PermissionCacheUtil.clearCache();
1021            }
1022    
1023            /**
1024             * Updates the role's permissions at the scope, setting the actions that can
1025             * be performed on resources of the type, also setting the owner of any
1026             * newly created resource permissions. Existing actions are replaced.
1027             *
1028             * <p>
1029             * This method can be used to set permissions at any scope, but it is
1030             * generally only used at the individual scope. For example, it could be
1031             * used to set the guest permissions on a blog post.
1032             * </p>
1033             *
1034             * <p>
1035             * Depending on the scope, the value of <code>primKey</code> will have
1036             * different meanings. For more information, see {@link
1037             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1038             * </p>
1039             *
1040             * @param  companyId the primary key of the company
1041             * @param  name the resource's name, which can be either a class name or a
1042             *         portlet ID
1043             * @param  scope the scope
1044             * @param  primKey the primary key
1045             * @param  roleId the primary key of the role
1046             * @param  ownerId the primary key of the owner (generally the user that
1047             *         created the resource)
1048             * @param  actionIds the action IDs of the actions
1049             * @throws PortalException if a role with the primary key or a resource
1050             *         action with the name and action ID could not be found
1051             * @throws SystemException if a system exception occurred
1052             */
1053            @Override
1054            public void setOwnerResourcePermissions(
1055                            long companyId, String name, int scope, String primKey, long roleId,
1056                            long ownerId, String[] actionIds)
1057                    throws PortalException, SystemException {
1058    
1059                    updateResourcePermission(
1060                            companyId, name, scope, primKey, roleId, ownerId, actionIds,
1061                            ResourcePermissionConstants.OPERATOR_SET);
1062            }
1063    
1064            /**
1065             * Updates the role's permissions at the scope, setting the actions that can
1066             * be performed on resources of the type. Existing actions are replaced.
1067             *
1068             * <p>
1069             * This method can be used to set permissions at any scope, but it is
1070             * generally only used at the individual scope. For example, it could be
1071             * used to set the guest permissions on a blog post.
1072             * </p>
1073             *
1074             * <p>
1075             * Depending on the scope, the value of <code>primKey</code> will have
1076             * different meanings. For more information, see {@link
1077             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1078             * </p>
1079             *
1080             * @param  companyId the primary key of the company
1081             * @param  name the resource's name, which can be either a class name or a
1082             *         portlet ID
1083             * @param  scope the scope
1084             * @param  primKey the primary key
1085             * @param  roleId the primary key of the role
1086             * @param  actionIds the action IDs of the actions
1087             * @throws PortalException if a role with the primary key or a resource
1088             *         action with the name and action ID could not be found
1089             * @throws SystemException if a system exception occurred
1090             */
1091            @Override
1092            public void setResourcePermissions(
1093                            long companyId, String name, int scope, String primKey, long roleId,
1094                            String[] actionIds)
1095                    throws PortalException, SystemException {
1096    
1097                    updateResourcePermission(
1098                            companyId, name, scope, primKey, roleId, 0, actionIds,
1099                            ResourcePermissionConstants.OPERATOR_SET);
1100            }
1101    
1102            /**
1103             * Updates the role's permissions at the scope, setting the actions that can
1104             * be performed on resources of the type. Existing actions are replaced.
1105             *
1106             * <p>
1107             * This method can be used to set permissions at any scope, but it is
1108             * generally only used at the individual scope. For example, it could be
1109             * used to set the guest permissions on a blog post.
1110             * </p>
1111             *
1112             * <p>
1113             * Depending on the scope, the value of <code>primKey</code> will have
1114             * different meanings. For more information, see {@link
1115             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1116             * </p>
1117             *
1118             * @param  companyId the primary key of the company
1119             * @param  name the resource's name, which can be either a class name or a
1120             *         portlet ID
1121             * @param  scope the scope
1122             * @param  primKey the primary key
1123             * @param  roleIdsToActionIds a map of role IDs to action IDs of the actions
1124             * @throws PortalException if a role with the primary key or a resource
1125             *         action with the name and action ID could not be found
1126             * @throws SystemException if a system exception occurred
1127             */
1128            @Override
1129            public void setResourcePermissions(
1130                            long companyId, String name, int scope, String primKey,
1131                            Map<Long, String[]> roleIdsToActionIds)
1132                    throws PortalException, SystemException {
1133    
1134                    updateResourcePermission(
1135                            companyId, name, scope, primKey, 0, roleIdsToActionIds);
1136            }
1137    
1138            protected void doUpdateResourcePermission(
1139                            long companyId, String name, int scope, String primKey,
1140                            long ownerId, long roleId, String[] actionIds, int operator,
1141                            boolean fetch)
1142                    throws PortalException, SystemException {
1143    
1144                    ResourcePermission resourcePermission = null;
1145    
1146                    Map<Long, ResourcePermission> resourcePermissionsMap =
1147                            ResourcePermissionsThreadLocal.getResourcePermissions();
1148    
1149                    if (resourcePermissionsMap != null) {
1150                            resourcePermission = resourcePermissionsMap.get(roleId);
1151                    }
1152                    else if (fetch) {
1153                            resourcePermission = resourcePermissionPersistence.fetchByC_N_S_P_R(
1154                                    companyId, name, scope, primKey, roleId);
1155                    }
1156    
1157                    if (resourcePermission == null) {
1158                            if (((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1159                                     (operator == ResourcePermissionConstants.OPERATOR_SET)) &&
1160                                    (actionIds.length == 0)) {
1161    
1162                                    return;
1163                            }
1164    
1165                            if (operator == ResourcePermissionConstants.OPERATOR_REMOVE) {
1166                                    return;
1167                            }
1168    
1169                            long resourcePermissionId = counterLocalService.increment(
1170                                    ResourcePermission.class.getName());
1171    
1172                            resourcePermission = resourcePermissionPersistence.create(
1173                                    resourcePermissionId);
1174    
1175                            resourcePermission.setCompanyId(companyId);
1176                            resourcePermission.setName(name);
1177                            resourcePermission.setScope(scope);
1178                            resourcePermission.setPrimKey(primKey);
1179                            resourcePermission.setRoleId(roleId);
1180                            resourcePermission.setOwnerId(ownerId);
1181                    }
1182    
1183                    List<String> unsupportedActionIds = Collections.emptyList();
1184    
1185                    if (((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1186                             (operator == ResourcePermissionConstants.OPERATOR_SET)) &&
1187                            isGuestRoleId(companyId, roleId)) {
1188    
1189                            unsupportedActionIds =
1190                                    ResourceActionsUtil.getResourceGuestUnsupportedActions(
1191                                            name, name);
1192                    }
1193    
1194                    long actionIdsLong = resourcePermission.getActionIds();
1195    
1196                    if (operator == ResourcePermissionConstants.OPERATOR_SET) {
1197                            actionIdsLong = 0;
1198                    }
1199    
1200                    for (String actionId : actionIds) {
1201                            if (actionId == null) {
1202                                    break;
1203                            }
1204    
1205                            if (unsupportedActionIds.contains(actionId)) {
1206                                    throw new PrincipalException(
1207                                            actionId + "is not supported by role " + roleId);
1208                            }
1209    
1210                            ResourceAction resourceAction =
1211                                    resourceActionLocalService.getResourceAction(name, actionId);
1212    
1213                            if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1214                                    (operator == ResourcePermissionConstants.OPERATOR_SET)) {
1215    
1216                                    actionIdsLong |= resourceAction.getBitwiseValue();
1217                            }
1218                            else {
1219                                    actionIdsLong =
1220                                            actionIdsLong & (~resourceAction.getBitwiseValue());
1221                            }
1222                    }
1223    
1224                    resourcePermission.setActionIds(actionIdsLong);
1225    
1226                    resourcePermissionPersistence.update(resourcePermission);
1227    
1228                    PermissionCacheUtil.clearCache();
1229    
1230                    SearchEngineUtil.updatePermissionFields(name, primKey);
1231            }
1232    
1233            protected void doUpdateResourcePermission(
1234                            long companyId, String name, int scope, String primKey,
1235                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1236                    throws PortalException, SystemException {
1237    
1238                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
1239    
1240                    PermissionThreadLocal.setIndexEnabled(false);
1241    
1242                    try {
1243                            long[] roleIds = ArrayUtil.toLongArray(roleIdsToActionIds.keySet());
1244    
1245                            List<ResourcePermission> resourcePermissions =
1246                                    resourcePermissionPersistence.findByC_N_S_P_R(
1247                                            companyId, name, scope, primKey, roleIds);
1248    
1249                            for (ResourcePermission resourcePermission : resourcePermissions) {
1250                                    long roleId = resourcePermission.getRoleId();
1251                                    String[] actionIds = roleIdsToActionIds.remove(roleId);
1252    
1253                                    doUpdateResourcePermission(
1254                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1255                                            ResourcePermissionConstants.OPERATOR_SET, true);
1256                            }
1257    
1258                            if (roleIdsToActionIds.isEmpty()) {
1259                                    return;
1260                            }
1261    
1262                            for (Map.Entry<Long, String[]> entry :
1263                                            roleIdsToActionIds.entrySet()) {
1264    
1265                                    long roleId = entry.getKey();
1266                                    String[] actionIds = entry.getValue();
1267    
1268                                    doUpdateResourcePermission(
1269                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1270                                            ResourcePermissionConstants.OPERATOR_SET, false);
1271                            }
1272                    }
1273                    finally {
1274                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
1275    
1276                            PermissionCacheUtil.clearCache();
1277    
1278                            SearchEngineUtil.updatePermissionFields(name, primKey);
1279                    }
1280            }
1281    
1282            protected boolean isGuestRoleId(long companyId, long roleId)
1283                    throws PortalException, SystemException {
1284    
1285                    Role guestRole = roleLocalService.getRole(
1286                            companyId, RoleConstants.GUEST);
1287    
1288                    if (roleId == guestRole.getRoleId()) {
1289                            return true;
1290                    }
1291    
1292                    return false;
1293            }
1294    
1295            /**
1296             * Updates the role's permissions at the scope, either adding to, removing
1297             * from, or setting the actions that can be performed on resources of the
1298             * type. Automatically creates a new resource permission if none exists, or
1299             * deletes the existing resource permission if it no longer grants
1300             * permissions to perform any action.
1301             *
1302             * <p>
1303             * Depending on the scope, the value of <code>primKey</code> will have
1304             * different meanings. For more information, see {@link
1305             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1306             * </p>
1307             *
1308             * @param  companyId the primary key of the company
1309             * @param  name the resource's name, which can be either a class name or a
1310             *         portlet ID
1311             * @param  scope the scope
1312             * @param  primKey the primary key
1313             * @param  roleId the primary key of the role
1314             * @param  ownerId the primary key of the owner
1315             * @param  actionIds the action IDs of the actions
1316             * @param  operator whether to add to, remove from, or set/replace the
1317             *         existing actions. Possible values can be found in {@link
1318             *         ResourcePermissionConstants}.
1319             * @throws PortalException if a role with the primary key or a resource
1320             *         action with the name and action ID could not be found
1321             * @throws SystemException if a system exception occurred
1322             */
1323            protected void updateResourcePermission(
1324                            long companyId, String name, int scope, String primKey, long roleId,
1325                            long ownerId, String[] actionIds, int operator)
1326                    throws PortalException, SystemException {
1327    
1328                    DB db = DBFactoryUtil.getDB();
1329    
1330                    String dbType = db.getType();
1331    
1332                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1333                            doUpdateResourcePermission(
1334                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1335                                    operator, true);
1336    
1337                            return;
1338                    }
1339    
1340                    StringBundler sb = new StringBundler(9);
1341    
1342                    sb.append(companyId);
1343                    sb.append(StringPool.POUND);
1344                    sb.append(name);
1345                    sb.append(StringPool.POUND);
1346                    sb.append(scope);
1347                    sb.append(StringPool.POUND);
1348                    sb.append(primKey);
1349                    sb.append(StringPool.POUND);
1350                    sb.append(roleId);
1351    
1352                    Class<?> clazz = getClass();
1353    
1354                    String groupName = clazz.getName();
1355    
1356                    String key = sb.toString();
1357    
1358                    Lock lock = LockRegistry.allocateLock(groupName, key);
1359    
1360                    lock.lock();
1361    
1362                    try {
1363                            doUpdateResourcePermission(
1364                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1365                                    operator, true);
1366                    }
1367                    finally {
1368                            lock.unlock();
1369    
1370                            LockRegistry.freeLock(groupName, key);
1371                    }
1372            }
1373    
1374            /**
1375             * Updates the role's permissions at the scope, either adding to, removing
1376             * from, or setting the actions that can be performed on resources of the
1377             * type. Automatically creates a new resource permission if none exists, or
1378             * deletes the existing resource permission if it no longer grants
1379             * permissions to perform any action.
1380             *
1381             * <p>
1382             * Depending on the scope, the value of <code>primKey</code> will have
1383             * different meanings. For more information, see {@link
1384             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1385             * </p>
1386             *
1387             * @param  companyId the primary key of the company
1388             * @param  name the resource's name, which can be either a class name or a
1389             *         portlet ID
1390             * @param  scope the scope
1391             * @param  primKey the primary key
1392             * @param  ownerId the primary key of the owner
1393             * @throws PortalException if a role with the primary key or a resource
1394             *         action with the name and action ID could not be found
1395             * @throws SystemException if a system exception occurred
1396             */
1397            protected void updateResourcePermission(
1398                            long companyId, String name, int scope, String primKey,
1399                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1400                    throws PortalException, SystemException {
1401    
1402                    DB db = DBFactoryUtil.getDB();
1403    
1404                    String dbType = db.getType();
1405    
1406                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1407                            doUpdateResourcePermission(
1408                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1409    
1410                            return;
1411                    }
1412    
1413                    StringBundler sb = new StringBundler(9);
1414    
1415                    sb.append(companyId);
1416                    sb.append(StringPool.POUND);
1417                    sb.append(name);
1418                    sb.append(StringPool.POUND);
1419                    sb.append(scope);
1420                    sb.append(StringPool.POUND);
1421                    sb.append(primKey);
1422                    sb.append(StringPool.POUND);
1423                    sb.append(StringUtil.merge(roleIdsToActionIds.keySet()));
1424    
1425                    Class<?> clazz = getClass();
1426    
1427                    String groupName = clazz.getName();
1428    
1429                    String key = sb.toString();
1430    
1431                    Lock lock = LockRegistry.allocateLock(groupName, key);
1432    
1433                    lock.lock();
1434    
1435                    try {
1436                            doUpdateResourcePermission(
1437                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1438                    }
1439                    finally {
1440                            lock.unlock();
1441    
1442                            LockRegistry.freeLock(groupName, key);
1443                    }
1444            }
1445    
1446            private static final String _FIND_MISSING_RESOURCE_PERMISSIONS =
1447                    ResourcePermissionLocalServiceImpl.class.getName() +
1448                            ".findMissingResourcePermissions";
1449    
1450            private static final String _UPDATE_ACTION_IDS =
1451                    ResourcePermissionLocalServiceImpl.class.getName() + ".updateActionIds";
1452    
1453    }