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    
152            /**
153             * Grants the role permissions at the scope to perform the actions on all
154             * resources of the type. Existing actions are retained.
155             *
156             * <p>
157             * This method should only be used to add default permissions to existing
158             * resources en masse during upgrades or while verifying permissions. For
159             * example, this method could be used to grant site members individual scope
160             * permissions to view all blog posts.
161             * </p>
162             *
163             * @param  resourceName the resource's name, which can be either a class
164             *         name or a portlet ID
165             * @param  roleName the role's name
166             * @param  scope the scope
167             * @param  resourceActionBitwiseValue the bitwise IDs of the actions
168             * @throws SystemException if a system exception occurred
169             */
170            @Override
171            public void addResourcePermissions(
172                            String resourceName, String roleName, int scope,
173                            long resourceActionBitwiseValue)
174                    throws SystemException {
175    
176                    List<Role> roles = rolePersistence.findByName(roleName);
177    
178                    if (roles.isEmpty()) {
179                            return;
180                    }
181    
182                    Session session = resourcePermissionPersistence.openSession();
183    
184                    try {
185    
186                            // Update existing resource permissions
187    
188                            String sql = CustomSQLUtil.get(_UPDATE_ACTION_IDS);
189    
190                            sql = StringUtil.replace(
191                                    sql, "[$ROLE_ID$]",
192                                    ListUtil.toString(roles, Role.ROLE_ID_ACCESSOR));
193    
194                            SQLQuery sqlQuery = session.createSQLQuery(sql);
195    
196                            QueryPos qPos = QueryPos.getInstance(sqlQuery);
197    
198                            qPos.add(resourceActionBitwiseValue);
199                            qPos.add(resourceActionBitwiseValue);
200                            qPos.add(resourceName);
201                            qPos.add(scope);
202    
203                            sqlQuery.executeUpdate();
204    
205                            // Add missing resource permissions
206    
207                            sql = CustomSQLUtil.get(_FIND_MISSING_RESOURCE_PERMISSIONS);
208    
209                            sqlQuery = session.createSQLQuery(sql);
210    
211                            sqlQuery.addScalar("companyId", Type.LONG);
212                            sqlQuery.addScalar("name", Type.STRING);
213                            sqlQuery.addScalar("scope", Type.INTEGER);
214                            sqlQuery.addScalar("primKey", Type.STRING);
215                            sqlQuery.addScalar("roleId", Type.LONG);
216    
217                            qPos = QueryPos.getInstance(sqlQuery);
218    
219                            qPos.add(resourceName);
220                            qPos.add(scope);
221                            qPos.add(roleName);
222    
223                            List<Object[]> resourcePermissionArrays = sqlQuery.list(true);
224    
225                            if (resourcePermissionArrays.isEmpty()) {
226                                    return;
227                            }
228    
229                            for (Object[] resourcePermissionArray : resourcePermissionArrays) {
230                                    long resourcePermissionId = counterLocalService.increment(
231                                            ResourcePermission.class.getName());
232    
233                                    ResourcePermission resourcePermission =
234                                            resourcePermissionPersistence.create(resourcePermissionId);
235    
236                                    resourcePermission.setCompanyId(
237                                            (Long)resourcePermissionArray[0]);
238                                    resourcePermission.setName((String)resourcePermissionArray[1]);
239                                    resourcePermission.setScope(
240                                            (Integer)resourcePermissionArray[2]);
241                                    resourcePermission.setPrimKey(
242                                            (String)resourcePermissionArray[3]);
243                                    resourcePermission.setRoleId((Long)resourcePermissionArray[4]);
244                                    resourcePermission.setActionIds(resourceActionBitwiseValue);
245    
246                                    session.save(resourcePermission);
247    
248                                    PermissionCacheUtil.clearResourcePermissionCache(
249                                            resourcePermission.getScope(), resourcePermission.getName(),
250                                            resourcePermission.getPrimKey());
251                            }
252                    }
253                    catch (Exception e) {
254                            throw new SystemException(e);
255                    }
256                    finally {
257                            resourcePermissionPersistence.closeSession(session);
258    
259                            resourcePermissionPersistence.clearCache();
260                    }
261            }
262    
263            /**
264             * Deletes all resource permissions at the scope to resources of the type.
265             * This method should not be confused with any of the
266             * <code>removeResourcePermission</code> methods, as its purpose is very
267             * different. This method should only be used for deleting resource
268             * permissions that refer to a resource when that resource is deleted. For
269             * example this method could be used to delete all individual scope
270             * permissions to a blog post when it is deleted.
271             *
272             * <p>
273             * Depending on the scope, the value of <code>primKey</code> will have
274             * different meanings. For more information, see {@link
275             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
276             * </p>
277             *
278             * @param  companyId the primary key of the company
279             * @param  name the resource's name, which can be either a class name or a
280             *         portlet ID
281             * @param  scope the scope
282             * @param  primKey the primary key
283             * @throws PortalException if a portal exception occurred
284             * @throws SystemException if a system exception occurred
285             */
286            @Override
287            public void deleteResourcePermissions(
288                            long companyId, String name, int scope, long primKey)
289                    throws PortalException, SystemException {
290    
291                    deleteResourcePermissions(
292                            companyId, name, scope, String.valueOf(primKey));
293            }
294    
295            /**
296             * Deletes all resource permissions at the scope to resources of the type.
297             * This method should not be confused with any of the
298             * <code>removeResourcePermission</code> methods, as its purpose is very
299             * different. This method should only be used for deleting resource
300             * permissions that refer to a resource when that resource is deleted. For
301             * example this method could be used to delete all individual scope
302             * permissions to a blog post when it is deleted.
303             *
304             * <p>
305             * Depending on the scope, the value of <code>primKey</code> will have
306             * different meanings. For more information, see {@link
307             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
308             * </p>
309             *
310             * @param  companyId the primary key of the company
311             * @param  name the resource's name, which can be either a class name or a
312             *         portlet ID
313             * @param  scope the scope
314             * @param  primKey the primary key
315             * @throws PortalException if a portal exception occurred
316             * @throws SystemException if a system exception occurred
317             */
318            @Override
319            public void deleteResourcePermissions(
320                            long companyId, String name, int scope, String primKey)
321                    throws PortalException, SystemException {
322    
323                    List<ResourcePermission> resourcePermissions =
324                            resourcePermissionPersistence.findByC_N_S_P(
325                                    companyId, name, scope, primKey);
326    
327                    for (ResourcePermission resourcePermission : resourcePermissions) {
328                            deleteResourcePermission(
329                                    resourcePermission.getResourcePermissionId());
330                    }
331            }
332    
333            @Override
334            public ResourcePermission fetchResourcePermission(
335                            long companyId, String name, int scope, String primKey, long roleId)
336                    throws SystemException {
337    
338                    return resourcePermissionPersistence.fetchByC_N_S_P_R(
339                            companyId, name, scope, primKey, roleId);
340            }
341    
342            /**
343             * Returns the intersection of action IDs the role has permission at the
344             * scope to perform on resources of the type.
345             *
346             * @param  companyId he primary key of the company
347             * @param  name the resource's name, which can be either a class name or a
348             *         portlet ID
349             * @param  scope the scope
350             * @param  primKey the primary key
351             * @param  roleId the primary key of the role
352             * @param  actionIds the action IDs
353             * @return the intersection of action IDs the role has permission at the
354             *         scope to perform on resources of the type
355             * @throws PortalException if a resouce action could not be found for any
356             *         one of the actions on the resource
357             * @throws SystemException if a system exception occurred
358             */
359            @Override
360            public List<String> getAvailableResourcePermissionActionIds(
361                            long companyId, String name, int scope, String primKey, long roleId,
362                            Collection<String> actionIds)
363                    throws PortalException, SystemException {
364    
365                    ResourcePermission resourcePermission =
366                            resourcePermissionPersistence.fetchByC_N_S_P_R(
367                                    companyId, name, scope, primKey, roleId);
368    
369                    if (resourcePermission == null) {
370                            return Collections.emptyList();
371                    }
372    
373                    List<String> availableActionIds = new ArrayList<String>(
374                            actionIds.size());
375    
376                    for (String actionId : actionIds) {
377                            ResourceAction resourceAction =
378                                    resourceActionLocalService.getResourceAction(name, actionId);
379    
380                            if (hasActionId(resourcePermission, resourceAction)) {
381                                    availableActionIds.add(actionId);
382                            }
383                    }
384    
385                    return availableActionIds;
386            }
387    
388            @Override
389            public Map<Long, Set<String>> getAvailableResourcePermissionActionIds(
390                            long companyId, String name, int scope, String primKey,
391                            long[] roleIds, Collection<String> actionIds)
392                    throws PortalException, SystemException {
393    
394                    List<ResourcePermission> resourcePermissions =
395                            resourcePermissionPersistence.findByC_N_S_P_R(
396                                    companyId, name, scope, primKey, roleIds);
397    
398                    if (resourcePermissions.isEmpty()) {
399                            return Collections.emptyMap();
400                    }
401    
402                    Map<Long, Set<String>> roleIdsToActionIds =
403                            new HashMap<Long, Set<String>>();
404    
405                    for (ResourcePermission resourcePermission : resourcePermissions) {
406                            long roleId = resourcePermission.getRoleId();
407    
408                            Set<String> availableActionIds = roleIdsToActionIds.get(roleId);
409    
410                            if (availableActionIds != null) {
411                                    continue;
412                            }
413    
414                            availableActionIds = new HashSet<String>();
415    
416                            roleIdsToActionIds.put(roleId, availableActionIds);
417    
418                            for (String actionId : actionIds) {
419                                    ResourceAction resourceAction =
420                                            resourceActionLocalService.getResourceAction(
421                                                    name, actionId);
422    
423                                    if (hasActionId(resourcePermission, resourceAction)) {
424                                            availableActionIds.add(actionId);
425                                    }
426                            }
427                    }
428    
429                    return roleIdsToActionIds;
430            }
431    
432            /**
433             * Returns the resource permission for the role at the scope to perform the
434             * actions on resources of the type.
435             *
436             * @param  companyId the primary key of the company
437             * @param  name the resource's name, which can be either a class name or a
438             *         portlet ID
439             * @param  scope the scope
440             * @param  primKey the primary key
441             * @param  roleId the primary key of the role
442             * @return the resource permission for the role at the scope to perform the
443             *         actions on resources of the type
444             * @throws PortalException if no matching resources could be found
445             * @throws SystemException if a system exception occurred
446             */
447            @Override
448            public ResourcePermission getResourcePermission(
449                            long companyId, String name, int scope, String primKey, long roleId)
450                    throws PortalException, SystemException {
451    
452                    return resourcePermissionPersistence.findByC_N_S_P_R(
453                            companyId, name, scope, primKey, roleId);
454            }
455    
456            /**
457             * Returns all the resource permissions at the scope of the type.
458             *
459             * @param  companyId the primary key of the company
460             * @param  name the resource's name, which can be either a class name or a
461             *         portlet ID
462             * @param  scope the scope
463             * @param  primKey the primary key
464             * @return the resource permissions at the scope of the type
465             * @throws SystemException if a system exception occurred
466             */
467            @Override
468            public List<ResourcePermission> getResourcePermissions(
469                            long companyId, String name, int scope, String primKey)
470                    throws SystemException {
471    
472                    return resourcePermissionPersistence.findByC_N_S_P(
473                            companyId, name, scope, primKey);
474            }
475    
476            /**
477             * Returns the number of resource permissions at the scope of the type.
478             *
479             * @param  companyId the primary key of the company
480             * @param  name the resource's name, which can be either a class name or a
481             *         portlet ID
482             * @param  scope the scope
483             * @param  primKey the primary key
484             * @return the number of resource permissions at the scope of the type
485             * @throws SystemException if a system exception occurred
486             */
487            @Override
488            public int getResourcePermissionsCount(
489                            long companyId, String name, int scope, String primKey)
490                    throws SystemException {
491    
492                    return resourcePermissionPersistence.countByC_N_S_P(
493                            companyId, name, scope, primKey);
494            }
495    
496            /**
497             * Returns the resource permissions that apply to the resource.
498             *
499             * @param  companyId the primary key of the resource's company
500             * @param  groupId the primary key of the resource's group
501             * @param  name the resource's name, which can be either a class name or a
502             *         portlet ID
503             * @param  primKey the primary key of the resource
504             * @return the resource permissions associated with the resource
505             * @throws SystemException if a system exception occurred
506             */
507            @Override
508            public List<ResourcePermission> getResourceResourcePermissions(
509                            long companyId, long groupId, String name, String primKey)
510                    throws SystemException {
511    
512                    return resourcePermissionFinder.findByResource(
513                            companyId, groupId, name, primKey);
514            }
515    
516            /**
517             * Returns all the resource permissions for the role.
518             *
519             * @param  roleId the primary key of the role
520             * @return the resource permissions for the role
521             * @throws SystemException if a system exception occurred
522             */
523            @Override
524            public List<ResourcePermission> getRoleResourcePermissions(long roleId)
525                    throws SystemException {
526    
527                    return resourcePermissionPersistence.findByRoleId(roleId);
528            }
529    
530            /**
531             * Returns a range of all the resource permissions for the role at the
532             * scopes.
533             *
534             * <p>
535             * Useful when paginating results. Returns a maximum of <code>end -
536             * start</code> instances. <code>start</code> and <code>end</code> are not
537             * primary keys, they are indexes in the result set. Thus, <code>0</code>
538             * refers to the first result in the set. Setting both <code>start</code>
539             * and <code>end</code> to {@link
540             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
541             * result set.
542             * </p>
543             *
544             * @param  roleId the primary key of the role
545             * @param  scopes the scopes
546             * @param  start the lower bound of the range of results
547             * @param  end the upper bound of the range of results (not inclusive)
548             * @return the range of resource permissions for the role at the scopes
549             * @throws SystemException if a system exception occurred
550             */
551            @Override
552            public List<ResourcePermission> getRoleResourcePermissions(
553                            long roleId, int[] scopes, int start, int end)
554                    throws SystemException {
555    
556                    return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
557            }
558    
559            /**
560             * Returns all the resource permissions where scope = any &#63;.
561             *
562             * <p>
563             * Useful when paginating results. Returns a maximum of <code>end -
564             * start</code> instances. <code>start</code> and <code>end</code> are not
565             * primary keys, they are indexes in the result set. Thus, <code>0</code>
566             * refers to the first result in the set. Setting both <code>start</code>
567             * and <code>end</code> to {@link
568             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
569             * result set.
570             * </p>
571             *
572             * @param  scopes the scopes
573             * @return the resource permissions where scope = any &#63;
574             * @throws SystemException if a system exception occurred
575             */
576            @Override
577            public List<ResourcePermission> getScopeResourcePermissions(int[] scopes)
578                    throws SystemException {
579    
580                    return resourcePermissionPersistence.findByScope(scopes);
581            }
582    
583            /**
584             * Returns <code>true</code> if the resource permission grants permission to
585             * perform the resource action. Note that this method does not ensure that
586             * the resource permission refers to the same type of resource as the
587             * resource action.
588             *
589             * @param  resourcePermission the resource permission
590             * @param  resourceAction the resource action
591             * @return <code>true</code> if the resource permission grants permission to
592             *         perform the resource action
593             */
594            @Override
595            public boolean hasActionId(
596                    ResourcePermission resourcePermission, ResourceAction resourceAction) {
597    
598                    long actionIds = resourcePermission.getActionIds();
599                    long bitwiseValue = resourceAction.getBitwiseValue();
600    
601                    if ((actionIds & bitwiseValue) == bitwiseValue) {
602                            return true;
603                    }
604                    else {
605                            return false;
606                    }
607            }
608    
609            /**
610             * Returns <code>true</code> if the roles have permission at the scope to
611             * perform the action on the resources.
612             *
613             * <p>
614             * Depending on the scope, the value of <code>primKey</code> will have
615             * different meanings. For more information, see {@link
616             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
617             * </p>
618             *
619             * @param  resources the resources
620             * @param  roleIds the primary keys of the roles
621             * @param  actionId the action ID
622             * @return <code>true</code> if any one of the roles has permission to
623             *         perform the action on any one of the resources;
624             *         <code>false</code> otherwise
625             * @throws PortalException if any one of the roles with the primary keys
626             *         could not be found or if a resource action with the name and
627             *         action ID could not be found
628             * @throws SystemException if a system exception occurred
629             */
630            @Override
631            public boolean hasResourcePermission(
632                            List<Resource> resources, long[] roleIds, String actionId)
633                    throws PortalException, SystemException {
634    
635                    if (roleIds.length == 0) {
636                            return false;
637                    }
638    
639                    // Iterate the list of resources in reverse order to test permissions
640                    // from company scope to individual scope because it is more likely that
641                    // a permission is assigned at a higher scope. Optimizing this method to
642                    // one SQL call may actually slow things down since most of the calls
643                    // will pull from the cache after the first request.
644    
645                    for (int i = resources.size() - 1; i >= 0; i--) {
646                            Resource resource = resources.get(i);
647    
648                            if (hasResourcePermission(
649                                            resource.getCompanyId(), resource.getName(),
650                                            resource.getScope(), resource.getPrimKey(), roleIds,
651                                            actionId)) {
652    
653                                    return true;
654                            }
655                    }
656    
657                    return false;
658            }
659    
660            /**
661             * Returns <code>true</code> if the role has permission at the scope to
662             * perform the action on resources of the type.
663             *
664             * <p>
665             * Depending on the scope, the value of <code>primKey</code> will have
666             * different meanings. For more information, see {@link
667             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
668             * </p>
669             *
670             * @param  companyId the primary key of the company
671             * @param  name the resource's name, which can be either a class name or a
672             *         portlet ID
673             * @param  scope the scope
674             * @param  primKey the primary key
675             * @param  roleId the primary key of the role
676             * @param  actionId the action ID
677             * @return <code>true</code> if the role has permission to perform the
678             *         action on the resource; <code>false</code> otherwise
679             * @throws PortalException if a role with the primary key or a resource
680             *         action with the name and action ID could not be found
681             * @throws SystemException if a system exception occurred
682             */
683            @Override
684            public boolean hasResourcePermission(
685                            long companyId, String name, int scope, String primKey, long roleId,
686                            String actionId)
687                    throws PortalException, SystemException {
688    
689                    ResourcePermission resourcePermission =
690                            resourcePermissionPersistence.fetchByC_N_S_P_R(
691                                    companyId, name, scope, primKey, roleId);
692    
693                    if (resourcePermission == null) {
694                            return false;
695                    }
696    
697                    ResourceAction resourceAction =
698                            resourceActionLocalService.getResourceAction(name, actionId);
699    
700                    if (hasActionId(resourcePermission, resourceAction)) {
701                            return true;
702                    }
703    
704                    return false;
705            }
706    
707            /**
708             * Returns <code>true</code> if the roles have permission at the scope to
709             * perform the action on resources of the type.
710             *
711             * <p>
712             * Depending on the scope, the value of <code>primKey</code> will have
713             * different meanings. For more information, see {@link
714             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
715             * </p>
716             *
717             * @param  companyId the primary key of the company
718             * @param  name the resource's name, which can be either a class name or a
719             *         portlet ID
720             * @param  scope the scope
721             * @param  primKey the primary key
722             * @param  roleIds the primary keys of the roles
723             * @param  actionId the action ID
724             * @return <code>true</code> if any one of the roles has permission to
725             *         perform the action on the resource; <code>false</code> otherwise
726             * @throws PortalException if any one of the roles with the primary keys
727             *         could not be found or if a resource action with the name and
728             *         action ID could not be found
729             * @throws SystemException if a system exception occurred
730             */
731            @Override
732            public boolean hasResourcePermission(
733                            long companyId, String name, int scope, String primKey,
734                            long[] roleIds, String actionId)
735                    throws PortalException, SystemException {
736    
737                    if (roleIds.length == 0) {
738                            return false;
739                    }
740    
741                    ResourceAction resourceAction =
742                            resourceActionLocalService.getResourceAction(name, actionId);
743    
744                    DB db = DBFactoryUtil.getDB();
745    
746                    String dbType = db.getType();
747    
748                    if ((roleIds.length >
749                                    PropsValues.
750                                            PERMISSIONS_ROLE_RESOURCE_PERMISSION_QUERY_THRESHOLD) &&
751                            !dbType.equals(DB.TYPE_DERBY) &&
752                            !dbType.equals(DB.TYPE_JDATASTORE) &&
753                            !dbType.equals(DB.TYPE_SAP)) {
754    
755                            int count = resourcePermissionFinder.countByC_N_S_P_R_A(
756                                    companyId, name, scope, primKey, roleIds,
757                                    resourceAction.getBitwiseValue());
758    
759                            if (count > 0) {
760                                    return true;
761                            }
762                    }
763                    else {
764                            List<ResourcePermission> resourcePermissions =
765                                    resourcePermissionPersistence.findByC_N_S_P_R(
766                                            companyId, name, scope, primKey, roleIds);
767    
768                            if (resourcePermissions.isEmpty()) {
769                                    return false;
770                            }
771    
772                            for (ResourcePermission resourcePermission : resourcePermissions) {
773                                    if (hasActionId(resourcePermission, resourceAction)) {
774                                            return true;
775                                    }
776                            }
777                    }
778    
779                    return false;
780            }
781    
782            @Override
783            public boolean[] hasResourcePermissions(
784                            long companyId, String name, int scope, String primKey,
785                            long[] roleIds, String actionId)
786                    throws PortalException, SystemException {
787    
788                    boolean[] hasResourcePermissions = new boolean[roleIds.length];
789    
790                    if (roleIds.length == 0) {
791                            return hasResourcePermissions;
792                    }
793    
794                    ResourceAction resourceAction =
795                            resourceActionLocalService.getResourceAction(name, actionId);
796    
797                    List<ResourcePermission> resourcePermissions =
798                            resourcePermissionPersistence.findByC_N_S_P_R(
799                                    companyId, name, scope, primKey, roleIds);
800    
801                    if (resourcePermissions.isEmpty()) {
802                            return hasResourcePermissions;
803                    }
804    
805                    for (ResourcePermission resourcePermission : resourcePermissions) {
806                            if (hasActionId(resourcePermission, resourceAction)) {
807                                    long roleId = resourcePermission.getRoleId();
808    
809                                    for (int i = 0; i < roleIds.length; i++) {
810                                            if (roleIds[i] == roleId) {
811                                                    hasResourcePermissions[i] = true;
812                                            }
813                                    }
814                            }
815                    }
816    
817                    return hasResourcePermissions;
818            }
819    
820            /**
821             * Returns <code>true</code> if the role has permission at the scope to
822             * perform the action on the resource.
823             *
824             * <p>
825             * Depending on the scope, the value of <code>primKey</code> will have
826             * different meanings. For more information, see {@link
827             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
828             * </p>
829             *
830             * @param  companyId the primary key of the company
831             * @param  name the resource's name, which can be either a class name or a
832             *         portlet ID
833             * @param  scope the scope
834             * @param  roleId the primary key of the role
835             * @param  actionId the action ID
836             * @return <code>true</code> if the role has permission to perform the
837             *         action on the resource; <code>false</code> otherwise
838             * @throws PortalException if a role with the primary key or a resource
839             *         action with the name and action ID could not be found
840             * @throws SystemException if a system exception occurred
841             */
842            @Override
843            public boolean hasScopeResourcePermission(
844                            long companyId, String name, int scope, long roleId,
845                            String actionId)
846                    throws PortalException, SystemException {
847    
848                    List<ResourcePermission> resourcePermissions =
849                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
850    
851                    for (ResourcePermission resourcePermission : resourcePermissions) {
852                            if (hasResourcePermission(
853                                            companyId, name, scope, resourcePermission.getPrimKey(),
854                                            roleId, actionId)) {
855    
856                                    return true;
857                            }
858                    }
859    
860                    return false;
861            }
862    
863            /**
864             * Reassigns all the resource permissions from the source role to the
865             * destination role, and deletes the source role.
866             *
867             * @param  fromRoleId the primary key of the source role
868             * @param  toRoleId the primary key of the destination role
869             * @throws PortalException if a role with the primary key could not be found
870             * @throws SystemException if a system exception occurred
871             */
872            @Override
873            public void mergePermissions(long fromRoleId, long toRoleId)
874                    throws PortalException, SystemException {
875    
876                    Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
877                    Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
878    
879                    if (fromRole.getType() != toRole.getType()) {
880                            throw new PortalException("Role types are mismatched");
881                    }
882                    else if (PortalUtil.isSystemRole(toRole.getName())) {
883                            throw new PortalException("Cannot move permissions to system role");
884                    }
885                    else if (PortalUtil.isSystemRole(fromRole.getName())) {
886                            throw new PortalException(
887                                    "Cannot move permissions from system role");
888                    }
889    
890                    List<ResourcePermission> resourcePermissions =
891                            getRoleResourcePermissions(fromRoleId);
892    
893                    for (ResourcePermission resourcePermission : resourcePermissions) {
894                            resourcePermission.setRoleId(toRoleId);
895    
896                            resourcePermissionPersistence.update(resourcePermission);
897                    }
898    
899                    roleLocalService.deleteRole(fromRoleId);
900    
901                    PermissionCacheUtil.clearCache();
902            }
903    
904            /**
905             * Grants the role default permissions to all the resources of the type and
906             * at the scope stored in the resource permission, deletes the resource
907             * permission, and deletes the resource permission's role if it has no
908             * permissions remaining.
909             *
910             * @param  resourcePermissionId the primary key of the resource permission
911             * @param  toRoleId the primary key of the role
912             * @throws PortalException if a resource permission or role with the primary
913             *         key could not be found
914             * @throws SystemException if a system exception occurred
915             */
916            @Override
917            public void reassignPermissions(long resourcePermissionId, long toRoleId)
918                    throws PortalException, SystemException {
919    
920                    ResourcePermission resourcePermission = getResourcePermission(
921                            resourcePermissionId);
922    
923                    long companyId = resourcePermission.getCompanyId();
924                    String name = resourcePermission.getName();
925                    int scope = resourcePermission.getScope();
926                    String primKey = resourcePermission.getPrimKey();
927                    long fromRoleId = resourcePermission.getRoleId();
928    
929                    Role toRole = roleLocalService.getRole(toRoleId);
930    
931                    List<String> actionIds = null;
932    
933                    if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
934                            actionIds = ResourceActionsUtil.getModelResourceActions(name);
935                    }
936                    else {
937                            actionIds = ResourceActionsUtil.getModelResourceGroupDefaultActions(
938                                    name);
939                    }
940    
941                    setResourcePermissions(
942                            companyId, name, scope, primKey, toRoleId,
943                            actionIds.toArray(new String[actionIds.size()]));
944    
945                    resourcePermissionPersistence.remove(resourcePermissionId);
946    
947                    List<ResourcePermission> resourcePermissions =
948                            getRoleResourcePermissions(fromRoleId);
949    
950                    if (resourcePermissions.isEmpty()) {
951                            roleLocalService.deleteRole(fromRoleId);
952                    }
953    
954                    PermissionCacheUtil.clearCache();
955            }
956    
957            /**
958             * Revokes permission at the scope from the role to perform the action on
959             * resources of the type. For example, this method could be used to revoke a
960             * group scope permission to edit blog posts.
961             *
962             * <p>
963             * Depending on the scope, the value of <code>primKey</code> will have
964             * different meanings. For more information, see {@link
965             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
966             * </p>
967             *
968             * @param  companyId the primary key of the company
969             * @param  name the resource's name, which can be either a class name or a
970             *         portlet ID
971             * @param  scope the scope
972             * @param  primKey the primary key
973             * @param  roleId the primary key of the role
974             * @param  actionId the action ID
975             * @throws PortalException if a role with the primary key or a resource
976             *         action with the name and action ID could not be found
977             * @throws SystemException if a system exception occurred
978             */
979            @Override
980            public void removeResourcePermission(
981                            long companyId, String name, int scope, String primKey, long roleId,
982                            String actionId)
983                    throws PortalException, SystemException {
984    
985                    updateResourcePermission(
986                            companyId, name, scope, primKey, roleId, 0, new String[] {actionId},
987                            ResourcePermissionConstants.OPERATOR_REMOVE);
988            }
989    
990            /**
991             * Revokes all permissions at the scope from the role to perform the action
992             * on resources of the type. For example, this method could be used to
993             * revoke all individual scope permissions to edit blog posts from site
994             * members.
995             *
996             * @param  companyId the primary key of the company
997             * @param  name the resource's name, which can be either a class name or a
998             *         portlet ID
999             * @param  scope the scope
1000             * @param  roleId the primary key of the role
1001             * @param  actionId the action ID
1002             * @throws PortalException if a role with the primary key or a resource
1003             *         action with the name and action ID could not be found
1004             * @throws SystemException if a system exception occurred
1005             */
1006            @Override
1007            public void removeResourcePermissions(
1008                            long companyId, String name, int scope, long roleId,
1009                            String actionId)
1010                    throws PortalException, SystemException {
1011    
1012                    List<ResourcePermission> resourcePermissions =
1013                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
1014    
1015                    for (ResourcePermission resourcePermission : resourcePermissions) {
1016                            updateResourcePermission(
1017                                    companyId, name, scope, resourcePermission.getPrimKey(), roleId,
1018                                    0, new String[] {actionId},
1019                                    ResourcePermissionConstants.OPERATOR_REMOVE);
1020                    }
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                    SearchEngineUtil.updatePermissionFields(name, primKey);
1229            }
1230    
1231            protected void doUpdateResourcePermission(
1232                            long companyId, String name, int scope, String primKey,
1233                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1234                    throws PortalException, SystemException {
1235    
1236                    boolean flushResourcePermissionEnabled =
1237                            PermissionThreadLocal.isFlushResourcePermissionEnabled(
1238                                    name, primKey);
1239    
1240                    PermissionThreadLocal.setFlushResourcePermissionEnabled(
1241                            name, primKey, false);
1242    
1243                    try {
1244                            long[] roleIds = ArrayUtil.toLongArray(roleIdsToActionIds.keySet());
1245    
1246                            List<ResourcePermission> resourcePermissions =
1247                                    resourcePermissionPersistence.findByC_N_S_P_R(
1248                                            companyId, name, scope, primKey, roleIds);
1249    
1250                            for (ResourcePermission resourcePermission : resourcePermissions) {
1251                                    long roleId = resourcePermission.getRoleId();
1252                                    String[] actionIds = roleIdsToActionIds.remove(roleId);
1253    
1254                                    doUpdateResourcePermission(
1255                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1256                                            ResourcePermissionConstants.OPERATOR_SET, true);
1257                            }
1258    
1259                            if (roleIdsToActionIds.isEmpty()) {
1260                                    return;
1261                            }
1262    
1263                            for (Map.Entry<Long, String[]> entry :
1264                                            roleIdsToActionIds.entrySet()) {
1265    
1266                                    long roleId = entry.getKey();
1267                                    String[] actionIds = entry.getValue();
1268    
1269                                    doUpdateResourcePermission(
1270                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1271                                            ResourcePermissionConstants.OPERATOR_SET, false);
1272                            }
1273                    }
1274                    finally {
1275                            PermissionThreadLocal.setFlushResourcePermissionEnabled(
1276                                    name, primKey, flushResourcePermissionEnabled);
1277    
1278                            PermissionCacheUtil.clearResourcePermissionCache(
1279                                    scope, name, primKey);
1280    
1281                            SearchEngineUtil.updatePermissionFields(name, primKey);
1282                    }
1283            }
1284    
1285            protected boolean isGuestRoleId(long companyId, long roleId)
1286                    throws PortalException, SystemException {
1287    
1288                    Role guestRole = roleLocalService.getRole(
1289                            companyId, RoleConstants.GUEST);
1290    
1291                    if (roleId == guestRole.getRoleId()) {
1292                            return true;
1293                    }
1294    
1295                    return false;
1296            }
1297    
1298            /**
1299             * Updates the role's permissions at the scope, either adding to, removing
1300             * from, or setting the actions that can be performed on resources of the
1301             * type. Automatically creates a new resource permission if none exists, or
1302             * deletes the existing resource permission if it no longer grants
1303             * permissions to perform any action.
1304             *
1305             * <p>
1306             * Depending on the scope, the value of <code>primKey</code> will have
1307             * different meanings. For more information, see {@link
1308             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1309             * </p>
1310             *
1311             * @param  companyId the primary key of the company
1312             * @param  name the resource's name, which can be either a class name or a
1313             *         portlet ID
1314             * @param  scope the scope
1315             * @param  primKey the primary key
1316             * @param  roleId the primary key of the role
1317             * @param  ownerId the primary key of the owner
1318             * @param  actionIds the action IDs of the actions
1319             * @param  operator whether to add to, remove from, or set/replace the
1320             *         existing actions. Possible values can be found in {@link
1321             *         ResourcePermissionConstants}.
1322             * @throws PortalException if a role with the primary key or a resource
1323             *         action with the name and action ID could not be found
1324             * @throws SystemException if a system exception occurred
1325             */
1326            protected void updateResourcePermission(
1327                            long companyId, String name, int scope, String primKey, long roleId,
1328                            long ownerId, String[] actionIds, int operator)
1329                    throws PortalException, SystemException {
1330    
1331                    DB db = DBFactoryUtil.getDB();
1332    
1333                    String dbType = db.getType();
1334    
1335                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1336                            doUpdateResourcePermission(
1337                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1338                                    operator, true);
1339    
1340                            return;
1341                    }
1342    
1343                    StringBundler sb = new StringBundler(9);
1344    
1345                    sb.append(companyId);
1346                    sb.append(StringPool.POUND);
1347                    sb.append(name);
1348                    sb.append(StringPool.POUND);
1349                    sb.append(scope);
1350                    sb.append(StringPool.POUND);
1351                    sb.append(primKey);
1352                    sb.append(StringPool.POUND);
1353                    sb.append(roleId);
1354    
1355                    Class<?> clazz = getClass();
1356    
1357                    String groupName = clazz.getName();
1358    
1359                    String key = sb.toString();
1360    
1361                    Lock lock = LockRegistry.allocateLock(groupName, key);
1362    
1363                    lock.lock();
1364    
1365                    try {
1366                            doUpdateResourcePermission(
1367                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1368                                    operator, true);
1369                    }
1370                    finally {
1371                            lock.unlock();
1372    
1373                            LockRegistry.freeLock(groupName, key);
1374                    }
1375            }
1376    
1377            /**
1378             * Updates the role's permissions at the scope, either adding to, removing
1379             * from, or setting the actions that can be performed on resources of the
1380             * type. Automatically creates a new resource permission if none exists, or
1381             * deletes the existing resource permission if it no longer grants
1382             * permissions to perform any action.
1383             *
1384             * <p>
1385             * Depending on the scope, the value of <code>primKey</code> will have
1386             * different meanings. For more information, see {@link
1387             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1388             * </p>
1389             *
1390             * @param  companyId the primary key of the company
1391             * @param  name the resource's name, which can be either a class name or a
1392             *         portlet ID
1393             * @param  scope the scope
1394             * @param  primKey the primary key
1395             * @param  ownerId the primary key of the owner
1396             * @throws PortalException if a role with the primary key or a resource
1397             *         action with the name and action ID could not be found
1398             * @throws SystemException if a system exception occurred
1399             */
1400            protected void updateResourcePermission(
1401                            long companyId, String name, int scope, String primKey,
1402                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1403                    throws PortalException, SystemException {
1404    
1405                    DB db = DBFactoryUtil.getDB();
1406    
1407                    String dbType = db.getType();
1408    
1409                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1410                            doUpdateResourcePermission(
1411                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1412    
1413                            return;
1414                    }
1415    
1416                    StringBundler sb = new StringBundler(9);
1417    
1418                    sb.append(companyId);
1419                    sb.append(StringPool.POUND);
1420                    sb.append(name);
1421                    sb.append(StringPool.POUND);
1422                    sb.append(scope);
1423                    sb.append(StringPool.POUND);
1424                    sb.append(primKey);
1425                    sb.append(StringPool.POUND);
1426                    sb.append(StringUtil.merge(roleIdsToActionIds.keySet()));
1427    
1428                    Class<?> clazz = getClass();
1429    
1430                    String groupName = clazz.getName();
1431    
1432                    String key = sb.toString();
1433    
1434                    Lock lock = LockRegistry.allocateLock(groupName, key);
1435    
1436                    lock.lock();
1437    
1438                    try {
1439                            doUpdateResourcePermission(
1440                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1441                    }
1442                    finally {
1443                            lock.unlock();
1444    
1445                            LockRegistry.freeLock(groupName, key);
1446                    }
1447            }
1448    
1449            private static final String _FIND_MISSING_RESOURCE_PERMISSIONS =
1450                    ResourcePermissionLocalServiceImpl.class.getName() +
1451                            ".findMissingResourcePermissions";
1452    
1453            private static final String _UPDATE_ACTION_IDS =
1454                    ResourcePermissionLocalServiceImpl.class.getName() + ".updateActionIds";
1455    
1456    }