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            /**
332             * Returns the intersection of action IDs the role has permission at the
333             * scope to perform on resources of the type.
334             *
335             * @param  companyId he primary key of the company
336             * @param  name the resource's name, which can be either a class name or a
337             *         portlet ID
338             * @param  scope the scope
339             * @param  primKey the primary key
340             * @param  roleId the primary key of the role
341             * @param  actionIds the action IDs
342             * @return the intersection of action IDs the role has permission at the
343             *         scope to perform on resources of the type
344             * @throws PortalException if a resouce action could not be found for any
345             *         one of the actions on the resource
346             * @throws SystemException if a system exception occurred
347             */
348            @Override
349            public List<String> getAvailableResourcePermissionActionIds(
350                            long companyId, String name, int scope, String primKey, long roleId,
351                            Collection<String> actionIds)
352                    throws PortalException, SystemException {
353    
354                    ResourcePermission resourcePermission =
355                            resourcePermissionPersistence.fetchByC_N_S_P_R(
356                                    companyId, name, scope, primKey, roleId);
357    
358                    if (resourcePermission == null) {
359                            return Collections.emptyList();
360                    }
361    
362                    List<String> availableActionIds = new ArrayList<String>(
363                            actionIds.size());
364    
365                    for (String actionId : actionIds) {
366                            ResourceAction resourceAction =
367                                    resourceActionLocalService.getResourceAction(name, actionId);
368    
369                            if (hasActionId(resourcePermission, resourceAction)) {
370                                    availableActionIds.add(actionId);
371                            }
372                    }
373    
374                    return availableActionIds;
375            }
376    
377            @Override
378            public Map<Long, Set<String>> getAvailableResourcePermissionActionIds(
379                            long companyId, String name, int scope, String primKey,
380                            long[] roleIds, Collection<String> actionIds)
381                    throws PortalException, SystemException {
382    
383                    List<ResourcePermission> resourcePermissions =
384                            resourcePermissionPersistence.findByC_N_S_P_R(
385                                    companyId, name, scope, primKey, roleIds);
386    
387                    if (resourcePermissions.isEmpty()) {
388                            return Collections.emptyMap();
389                    }
390    
391                    Map<Long, Set<String>> roleIdsToActionIds =
392                            new HashMap<Long, Set<String>>();
393    
394                    for (ResourcePermission resourcePermission : resourcePermissions) {
395                            long roleId = resourcePermission.getRoleId();
396    
397                            Set<String> availableActionIds = roleIdsToActionIds.get(roleId);
398    
399                            if (availableActionIds != null) {
400                                    continue;
401                            }
402    
403                            availableActionIds = new HashSet<String>();
404    
405                            roleIdsToActionIds.put(roleId, availableActionIds);
406    
407                            for (String actionId : actionIds) {
408                                    ResourceAction resourceAction =
409                                            resourceActionLocalService.getResourceAction(
410                                                    name, actionId);
411    
412                                    if (hasActionId(resourcePermission, resourceAction)) {
413                                            availableActionIds.add(actionId);
414                                    }
415                            }
416                    }
417    
418                    return roleIdsToActionIds;
419            }
420    
421            /**
422             * Returns the resource permission for the role at the scope to perform the
423             * actions on resources of the type.
424             *
425             * @param  companyId the primary key of the company
426             * @param  name the resource's name, which can be either a class name or a
427             *         portlet ID
428             * @param  scope the scope
429             * @param  primKey the primary key
430             * @param  roleId the primary key of the role
431             * @return the resource permission for the role at the scope to perform the
432             *         actions on resources of the type
433             * @throws PortalException if no matching resources could be found
434             * @throws SystemException if a system exception occurred
435             */
436            @Override
437            public ResourcePermission getResourcePermission(
438                            long companyId, String name, int scope, String primKey, long roleId)
439                    throws PortalException, SystemException {
440    
441                    return resourcePermissionPersistence.findByC_N_S_P_R(
442                            companyId, name, scope, primKey, roleId);
443            }
444    
445            /**
446             * Returns all the resource permissions at the scope of the type.
447             *
448             * @param  companyId the primary key of the company
449             * @param  name the resource's name, which can be either a class name or a
450             *         portlet ID
451             * @param  scope the scope
452             * @param  primKey the primary key
453             * @return the resource permissions at the scope of the type
454             * @throws SystemException if a system exception occurred
455             */
456            @Override
457            public List<ResourcePermission> getResourcePermissions(
458                            long companyId, String name, int scope, String primKey)
459                    throws SystemException {
460    
461                    return resourcePermissionPersistence.findByC_N_S_P(
462                            companyId, name, scope, primKey);
463            }
464    
465            /**
466             * Returns the number of resource permissions at the scope of the type.
467             *
468             * @param  companyId the primary key of the company
469             * @param  name the resource's name, which can be either a class name or a
470             *         portlet ID
471             * @param  scope the scope
472             * @param  primKey the primary key
473             * @return the number of resource permissions at the scope of the type
474             * @throws SystemException if a system exception occurred
475             */
476            @Override
477            public int getResourcePermissionsCount(
478                            long companyId, String name, int scope, String primKey)
479                    throws SystemException {
480    
481                    return resourcePermissionPersistence.countByC_N_S_P(
482                            companyId, name, scope, primKey);
483            }
484    
485            /**
486             * Returns the resource permissions that apply to the resource.
487             *
488             * @param  companyId the primary key of the resource's company
489             * @param  groupId the primary key of the resource's group
490             * @param  name the resource's name, which can be either a class name or a
491             *         portlet ID
492             * @param  primKey the primary key of the resource
493             * @return the resource permissions associated with the resource
494             * @throws SystemException if a system exception occurred
495             */
496            @Override
497            public List<ResourcePermission> getResourceResourcePermissions(
498                            long companyId, long groupId, String name, String primKey)
499                    throws SystemException {
500    
501                    return resourcePermissionFinder.findByResource(
502                            companyId, groupId, name, primKey);
503            }
504    
505            /**
506             * Returns all the resource permissions for the role.
507             *
508             * @param  roleId the primary key of the role
509             * @return the resource permissions for the role
510             * @throws SystemException if a system exception occurred
511             */
512            @Override
513            public List<ResourcePermission> getRoleResourcePermissions(long roleId)
514                    throws SystemException {
515    
516                    return resourcePermissionPersistence.findByRoleId(roleId);
517            }
518    
519            /**
520             * Returns a range of all the resource permissions for the role at the
521             * scopes.
522             *
523             * <p>
524             * Useful when paginating results. Returns a maximum of <code>end -
525             * start</code> instances. <code>start</code> and <code>end</code> are not
526             * primary keys, they are indexes in the result set. Thus, <code>0</code>
527             * refers to the first result in the set. Setting both <code>start</code>
528             * and <code>end</code> to {@link
529             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
530             * result set.
531             * </p>
532             *
533             * @param  roleId the primary key of the role
534             * @param  scopes the scopes
535             * @param  start the lower bound of the range of results
536             * @param  end the upper bound of the range of results (not inclusive)
537             * @return the range of resource permissions for the role at the scopes
538             * @throws SystemException if a system exception occurred
539             */
540            @Override
541            public List<ResourcePermission> getRoleResourcePermissions(
542                            long roleId, int[] scopes, int start, int end)
543                    throws SystemException {
544    
545                    return resourcePermissionFinder.findByR_S(roleId, scopes, start, end);
546            }
547    
548            /**
549             * Returns all the resource permissions where scope = any &#63;.
550             *
551             * <p>
552             * Useful when paginating results. Returns a maximum of <code>end -
553             * start</code> instances. <code>start</code> and <code>end</code> are not
554             * primary keys, they are indexes in the result set. Thus, <code>0</code>
555             * refers to the first result in the set. Setting both <code>start</code>
556             * and <code>end</code> to {@link
557             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
558             * result set.
559             * </p>
560             *
561             * @param  scopes the scopes
562             * @return the resource permissions where scope = any &#63;
563             * @throws SystemException if a system exception occurred
564             */
565            @Override
566            public List<ResourcePermission> getScopeResourcePermissions(int[] scopes)
567                    throws SystemException {
568    
569                    return resourcePermissionPersistence.findByScope(scopes);
570            }
571    
572            /**
573             * Returns <code>true</code> if the resource permission grants permission to
574             * perform the resource action. Note that this method does not ensure that
575             * the resource permission refers to the same type of resource as the
576             * resource action.
577             *
578             * @param  resourcePermission the resource permission
579             * @param  resourceAction the resource action
580             * @return <code>true</code> if the resource permission grants permission to
581             *         perform the resource action
582             */
583            @Override
584            public boolean hasActionId(
585                    ResourcePermission resourcePermission, ResourceAction resourceAction) {
586    
587                    long actionIds = resourcePermission.getActionIds();
588                    long bitwiseValue = resourceAction.getBitwiseValue();
589    
590                    if ((actionIds & bitwiseValue) == bitwiseValue) {
591                            return true;
592                    }
593                    else {
594                            return false;
595                    }
596            }
597    
598            /**
599             * Returns <code>true</code> if the roles have permission at the scope to
600             * perform the action on the resources.
601             *
602             * <p>
603             * Depending on the scope, the value of <code>primKey</code> will have
604             * different meanings. For more information, see {@link
605             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
606             * </p>
607             *
608             * @param  resources the resources
609             * @param  roleIds the primary keys of the roles
610             * @param  actionId the action ID
611             * @return <code>true</code> if any one of the roles has permission to
612             *         perform the action on any one of the resources;
613             *         <code>false</code> otherwise
614             * @throws PortalException if any one of the roles with the primary keys
615             *         could not be found or if a resource action with the name and
616             *         action ID could not be found
617             * @throws SystemException if a system exception occurred
618             */
619            @Override
620            public boolean hasResourcePermission(
621                            List<Resource> resources, long[] roleIds, String actionId)
622                    throws PortalException, SystemException {
623    
624                    // Iterate the list of resources in reverse order to test permissions
625                    // from company scope to individual scope because it is more likely that
626                    // a permission is assigned at a higher scope. Optimizing this method to
627                    // one SQL call may actually slow things down since most of the calls
628                    // will pull from the cache after the first request.
629    
630                    for (int i = resources.size() - 1; i >= 0; i--) {
631                            Resource resource = resources.get(i);
632    
633                            if (hasResourcePermission(
634                                            resource.getCompanyId(), resource.getName(),
635                                            resource.getScope(), resource.getPrimKey(), roleIds,
636                                            actionId)) {
637    
638                                    return true;
639                            }
640                    }
641    
642                    return false;
643            }
644    
645            /**
646             * Returns <code>true</code> if the role has permission at the scope to
647             * perform the action on resources of the type.
648             *
649             * <p>
650             * Depending on the scope, the value of <code>primKey</code> will have
651             * different meanings. For more information, see {@link
652             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
653             * </p>
654             *
655             * @param  companyId the primary key of the company
656             * @param  name the resource's name, which can be either a class name or a
657             *         portlet ID
658             * @param  scope the scope
659             * @param  primKey the primary key
660             * @param  roleId the primary key of the role
661             * @param  actionId the action ID
662             * @return <code>true</code> if the role has permission to perform the
663             *         action on the resource; <code>false</code> otherwise
664             * @throws PortalException if a role with the primary key or a resource
665             *         action with the name and action ID could not be found
666             * @throws SystemException if a system exception occurred
667             */
668            @Override
669            public boolean hasResourcePermission(
670                            long companyId, String name, int scope, String primKey, long roleId,
671                            String actionId)
672                    throws PortalException, SystemException {
673    
674                    ResourcePermission resourcePermission =
675                            resourcePermissionPersistence.fetchByC_N_S_P_R(
676                                    companyId, name, scope, primKey, roleId);
677    
678                    if (resourcePermission == null) {
679                            return false;
680                    }
681    
682                    ResourceAction resourceAction =
683                            resourceActionLocalService.getResourceAction(name, actionId);
684    
685                    if (hasActionId(resourcePermission, resourceAction)) {
686                            return true;
687                    }
688    
689                    return false;
690            }
691    
692            /**
693             * Returns <code>true</code> if the roles have permission at the scope to
694             * perform the action on resources of the type.
695             *
696             * <p>
697             * Depending on the scope, the value of <code>primKey</code> will have
698             * different meanings. For more information, see {@link
699             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
700             * </p>
701             *
702             * @param  companyId the primary key of the company
703             * @param  name the resource's name, which can be either a class name or a
704             *         portlet ID
705             * @param  scope the scope
706             * @param  primKey the primary key
707             * @param  roleIds the primary keys of the roles
708             * @param  actionId the action ID
709             * @return <code>true</code> if any one of the roles has permission to
710             *         perform the action on the resource; <code>false</code> otherwise
711             * @throws PortalException if any one of the roles with the primary keys
712             *         could not be found or if a resource action with the name and
713             *         action ID could not be found
714             * @throws SystemException if a system exception occurred
715             */
716            @Override
717            public boolean hasResourcePermission(
718                            long companyId, String name, int scope, String primKey,
719                            long[] roleIds, String actionId)
720                    throws PortalException, SystemException {
721    
722                    ResourceAction resourceAction =
723                            resourceActionLocalService.getResourceAction(name, actionId);
724    
725                    DB db = DBFactoryUtil.getDB();
726    
727                    String dbType = db.getType();
728    
729                    if ((roleIds.length >
730                                    PropsValues.
731                                            PERMISSIONS_ROLE_RESOURCE_PERMISSION_QUERY_THRESHOLD) &&
732                            !dbType.equals(DB.TYPE_DERBY) &&
733                            !dbType.equals(DB.TYPE_JDATASTORE) &&
734                            !dbType.equals(DB.TYPE_SAP)) {
735    
736                            int count = resourcePermissionFinder.countByC_N_S_P_R_A(
737                                    companyId, name, scope, primKey, roleIds,
738                                    resourceAction.getBitwiseValue());
739    
740                            if (count > 0) {
741                                    return true;
742                            }
743                    }
744                    else {
745                            List<ResourcePermission> resourcePermissions =
746                                    resourcePermissionPersistence.findByC_N_S_P_R(
747                                            companyId, name, scope, primKey, roleIds);
748    
749                            if (resourcePermissions.isEmpty()) {
750                                    return false;
751                            }
752    
753                            for (ResourcePermission resourcePermission : resourcePermissions) {
754                                    if (hasActionId(resourcePermission, resourceAction)) {
755                                            return true;
756                                    }
757                            }
758    
759                    }
760    
761                    return false;
762            }
763    
764            @Override
765            public boolean[] hasResourcePermissions(
766                            long companyId, String name, int scope, String primKey,
767                            long[] roleIds, String actionId)
768                    throws PortalException, SystemException {
769    
770                    ResourceAction resourceAction =
771                            resourceActionLocalService.getResourceAction(name, actionId);
772    
773                    List<ResourcePermission> resourcePermissions =
774                            resourcePermissionPersistence.findByC_N_S_P_R(
775                                    companyId, name, scope, primKey, roleIds);
776    
777                    boolean[] hasResourcePermissions = new boolean[roleIds.length];
778    
779                    if (resourcePermissions.isEmpty()) {
780                            return hasResourcePermissions;
781                    }
782    
783                    for (ResourcePermission resourcePermission : resourcePermissions) {
784                            if (hasActionId(resourcePermission, resourceAction)) {
785                                    long roleId = resourcePermission.getRoleId();
786    
787                                    for (int i = 0; i < roleIds.length; i++) {
788                                            if (roleIds[i] == roleId) {
789                                                    hasResourcePermissions[i] = true;
790                                            }
791                                    }
792                            }
793                    }
794    
795                    return hasResourcePermissions;
796            }
797    
798            /**
799             * Returns <code>true</code> if the role has permission at the scope to
800             * perform the action on the resource.
801             *
802             * <p>
803             * Depending on the scope, the value of <code>primKey</code> will have
804             * different meanings. For more information, see {@link
805             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
806             * </p>
807             *
808             * @param  companyId the primary key of the company
809             * @param  name the resource's name, which can be either a class name or a
810             *         portlet ID
811             * @param  scope the scope
812             * @param  roleId the primary key of the role
813             * @param  actionId the action ID
814             * @return <code>true</code> if the role has permission to perform the
815             *         action on the resource; <code>false</code> otherwise
816             * @throws PortalException if a role with the primary key or a resource
817             *         action with the name and action ID could not be found
818             * @throws SystemException if a system exception occurred
819             */
820            @Override
821            public boolean hasScopeResourcePermission(
822                            long companyId, String name, int scope, long roleId,
823                            String actionId)
824                    throws PortalException, SystemException {
825    
826                    List<ResourcePermission> resourcePermissions =
827                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
828    
829                    for (ResourcePermission resourcePermission : resourcePermissions) {
830                            if (hasResourcePermission(
831                                            companyId, name, scope, resourcePermission.getPrimKey(),
832                                            roleId, actionId)) {
833    
834                                    return true;
835                            }
836                    }
837    
838                    return false;
839            }
840    
841            /**
842             * Reassigns all the resource permissions from the source role to the
843             * destination role, and deletes the source role.
844             *
845             * @param  fromRoleId the primary key of the source role
846             * @param  toRoleId the primary key of the destination role
847             * @throws PortalException if a role with the primary key could not be found
848             * @throws SystemException if a system exception occurred
849             */
850            @Override
851            public void mergePermissions(long fromRoleId, long toRoleId)
852                    throws PortalException, SystemException {
853    
854                    Role fromRole = rolePersistence.findByPrimaryKey(fromRoleId);
855                    Role toRole = rolePersistence.findByPrimaryKey(toRoleId);
856    
857                    if (fromRole.getType() != toRole.getType()) {
858                            throw new PortalException("Role types are mismatched");
859                    }
860                    else if (PortalUtil.isSystemRole(toRole.getName())) {
861                            throw new PortalException("Cannot move permissions to system role");
862                    }
863                    else if (PortalUtil.isSystemRole(fromRole.getName())) {
864                            throw new PortalException(
865                                    "Cannot move permissions from system role");
866                    }
867    
868                    List<ResourcePermission> resourcePermissions =
869                            getRoleResourcePermissions(fromRoleId);
870    
871                    for (ResourcePermission resourcePermission : resourcePermissions) {
872                            resourcePermission.setRoleId(toRoleId);
873    
874                            resourcePermissionPersistence.update(resourcePermission);
875                    }
876    
877                    roleLocalService.deleteRole(fromRoleId);
878    
879                    PermissionCacheUtil.clearCache();
880            }
881    
882            /**
883             * Grants the role default permissions to all the resources of the type and
884             * at the scope stored in the resource permission, deletes the resource
885             * permission, and deletes the resource permission's role if it has no
886             * permissions remaining.
887             *
888             * @param  resourcePermissionId the primary key of the resource permission
889             * @param  toRoleId the primary key of the role
890             * @throws PortalException if a resource permission or role with the primary
891             *         key could not be found
892             * @throws SystemException if a system exception occurred
893             */
894            @Override
895            public void reassignPermissions(long resourcePermissionId, long toRoleId)
896                    throws PortalException, SystemException {
897    
898                    ResourcePermission resourcePermission = getResourcePermission(
899                            resourcePermissionId);
900    
901                    long companyId = resourcePermission.getCompanyId();
902                    String name = resourcePermission.getName();
903                    int scope = resourcePermission.getScope();
904                    String primKey = resourcePermission.getPrimKey();
905                    long fromRoleId = resourcePermission.getRoleId();
906    
907                    Role toRole = roleLocalService.getRole(toRoleId);
908    
909                    List<String> actionIds = null;
910    
911                    if (toRole.getType() == RoleConstants.TYPE_REGULAR) {
912                            actionIds = ResourceActionsUtil.getModelResourceActions(name);
913                    }
914                    else {
915                            actionIds = ResourceActionsUtil.getModelResourceGroupDefaultActions(
916                                    name);
917                    }
918    
919                    setResourcePermissions(
920                            companyId, name, scope, primKey, toRoleId,
921                            actionIds.toArray(new String[actionIds.size()]));
922    
923                    resourcePermissionPersistence.remove(resourcePermissionId);
924    
925                    List<ResourcePermission> resourcePermissions =
926                            getRoleResourcePermissions(fromRoleId);
927    
928                    if (resourcePermissions.isEmpty()) {
929                            roleLocalService.deleteRole(fromRoleId);
930                    }
931            }
932    
933            /**
934             * Revokes permission at the scope from the role to perform the action on
935             * resources of the type. For example, this method could be used to revoke a
936             * group scope permission to edit blog posts.
937             *
938             * <p>
939             * Depending on the scope, the value of <code>primKey</code> will have
940             * different meanings. For more information, see {@link
941             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
942             * </p>
943             *
944             * @param  companyId the primary key of the company
945             * @param  name the resource's name, which can be either a class name or a
946             *         portlet ID
947             * @param  scope the scope
948             * @param  primKey the primary key
949             * @param  roleId the primary key of the role
950             * @param  actionId the action ID
951             * @throws PortalException if a role with the primary key or a resource
952             *         action with the name and action ID could not be found
953             * @throws SystemException if a system exception occurred
954             */
955            @Override
956            public void removeResourcePermission(
957                            long companyId, String name, int scope, String primKey, long roleId,
958                            String actionId)
959                    throws PortalException, SystemException {
960    
961                    updateResourcePermission(
962                            companyId, name, scope, primKey, roleId, 0, new String[] {actionId},
963                            ResourcePermissionConstants.OPERATOR_REMOVE);
964    
965                    PermissionCacheUtil.clearCache();
966            }
967    
968            /**
969             * Revokes all permissions at the scope from the role to perform the action
970             * on resources of the type. For example, this method could be used to
971             * revoke all individual scope permissions to edit blog posts from site
972             * members.
973             *
974             * @param  companyId the primary key of the company
975             * @param  name the resource's name, which can be either a class name or a
976             *         portlet ID
977             * @param  scope the scope
978             * @param  roleId the primary key of the role
979             * @param  actionId the action ID
980             * @throws PortalException if a role with the primary key or a resource
981             *         action with the name and action ID could not be found
982             * @throws SystemException if a system exception occurred
983             */
984            @Override
985            public void removeResourcePermissions(
986                            long companyId, String name, int scope, long roleId,
987                            String actionId)
988                    throws PortalException, SystemException {
989    
990                    List<ResourcePermission> resourcePermissions =
991                            resourcePermissionPersistence.findByC_N_S(companyId, name, scope);
992    
993                    for (ResourcePermission resourcePermission : resourcePermissions) {
994                            updateResourcePermission(
995                                    companyId, name, scope, resourcePermission.getPrimKey(), roleId,
996                                    0, new String[] {actionId},
997                                    ResourcePermissionConstants.OPERATOR_REMOVE);
998                    }
999    
1000                    PermissionCacheUtil.clearCache();
1001            }
1002    
1003            /**
1004             * Updates the role's permissions at the scope, setting the actions that can
1005             * be performed on resources of the type, also setting the owner of any
1006             * newly created resource permissions. Existing actions are replaced.
1007             *
1008             * <p>
1009             * This method can be used to set permissions at any scope, but it is
1010             * generally only used at the individual scope. For example, it could be
1011             * used to set the guest permissions on a blog post.
1012             * </p>
1013             *
1014             * <p>
1015             * Depending on the scope, the value of <code>primKey</code> will have
1016             * different meanings. For more information, see {@link
1017             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1018             * </p>
1019             *
1020             * @param  companyId the primary key of the company
1021             * @param  name the resource's name, which can be either a class name or a
1022             *         portlet ID
1023             * @param  scope the scope
1024             * @param  primKey the primary key
1025             * @param  roleId the primary key of the role
1026             * @param  ownerId the primary key of the owner (generally the user that
1027             *         created the resource)
1028             * @param  actionIds the action IDs of the actions
1029             * @throws PortalException if a role with the primary key or a resource
1030             *         action with the name and action ID could not be found
1031             * @throws SystemException if a system exception occurred
1032             */
1033            @Override
1034            public void setOwnerResourcePermissions(
1035                            long companyId, String name, int scope, String primKey, long roleId,
1036                            long ownerId, String[] actionIds)
1037                    throws PortalException, SystemException {
1038    
1039                    updateResourcePermission(
1040                            companyId, name, scope, primKey, roleId, ownerId, actionIds,
1041                            ResourcePermissionConstants.OPERATOR_SET);
1042            }
1043    
1044            /**
1045             * Updates the role's permissions at the scope, setting the actions that can
1046             * be performed on resources of the type. Existing actions are replaced.
1047             *
1048             * <p>
1049             * This method can be used to set permissions at any scope, but it is
1050             * generally only used at the individual scope. For example, it could be
1051             * used to set the guest permissions on a blog post.
1052             * </p>
1053             *
1054             * <p>
1055             * Depending on the scope, the value of <code>primKey</code> will have
1056             * different meanings. For more information, see {@link
1057             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1058             * </p>
1059             *
1060             * @param  companyId the primary key of the company
1061             * @param  name the resource's name, which can be either a class name or a
1062             *         portlet ID
1063             * @param  scope the scope
1064             * @param  primKey the primary key
1065             * @param  roleId the primary key of the role
1066             * @param  actionIds the action IDs of the actions
1067             * @throws PortalException if a role with the primary key or a resource
1068             *         action with the name and action ID could not be found
1069             * @throws SystemException if a system exception occurred
1070             */
1071            @Override
1072            public void setResourcePermissions(
1073                            long companyId, String name, int scope, String primKey, long roleId,
1074                            String[] actionIds)
1075                    throws PortalException, SystemException {
1076    
1077                    updateResourcePermission(
1078                            companyId, name, scope, primKey, roleId, 0, actionIds,
1079                            ResourcePermissionConstants.OPERATOR_SET);
1080            }
1081    
1082            /**
1083             * Updates the role's permissions at the scope, setting the actions that can
1084             * be performed on resources of the type. Existing actions are replaced.
1085             *
1086             * <p>
1087             * This method can be used to set permissions at any scope, but it is
1088             * generally only used at the individual scope. For example, it could be
1089             * used to set the guest permissions on a blog post.
1090             * </p>
1091             *
1092             * <p>
1093             * Depending on the scope, the value of <code>primKey</code> will have
1094             * different meanings. For more information, see {@link
1095             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1096             * </p>
1097             *
1098             * @param  companyId the primary key of the company
1099             * @param  name the resource's name, which can be either a class name or a
1100             *         portlet ID
1101             * @param  scope the scope
1102             * @param  primKey the primary key
1103             * @param  roleIdsToActionIds a map of role IDs to action IDs of the actions
1104             * @throws PortalException if a role with the primary key or a resource
1105             *         action with the name and action ID could not be found
1106             * @throws SystemException if a system exception occurred
1107             */
1108            @Override
1109            public void setResourcePermissions(
1110                            long companyId, String name, int scope, String primKey,
1111                            Map<Long, String[]> roleIdsToActionIds)
1112                    throws PortalException, SystemException {
1113    
1114                    updateResourcePermission(
1115                            companyId, name, scope, primKey, 0, roleIdsToActionIds);
1116            }
1117    
1118            protected void doUpdateResourcePermission(
1119                            long companyId, String name, int scope, String primKey,
1120                            long ownerId, long roleId, String[] actionIds, int operator,
1121                            boolean fetch)
1122                    throws PortalException, SystemException {
1123    
1124                    ResourcePermission resourcePermission = null;
1125    
1126                    Map<Long, ResourcePermission> resourcePermissionsMap =
1127                            ResourcePermissionsThreadLocal.getResourcePermissions();
1128    
1129                    if (resourcePermissionsMap != null) {
1130                            resourcePermission = resourcePermissionsMap.get(roleId);
1131                    }
1132                    else if (fetch) {
1133                            resourcePermission = resourcePermissionPersistence.fetchByC_N_S_P_R(
1134                                    companyId, name, scope, primKey, roleId);
1135                    }
1136    
1137                    if (resourcePermission == null) {
1138                            if (((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1139                                     (operator == ResourcePermissionConstants.OPERATOR_SET)) &&
1140                                    (actionIds.length == 0)) {
1141    
1142                                    return;
1143                            }
1144    
1145                            if (operator == ResourcePermissionConstants.OPERATOR_REMOVE) {
1146                                    return;
1147                            }
1148    
1149                            long resourcePermissionId = counterLocalService.increment(
1150                                    ResourcePermission.class.getName());
1151    
1152                            resourcePermission = resourcePermissionPersistence.create(
1153                                    resourcePermissionId);
1154    
1155                            resourcePermission.setCompanyId(companyId);
1156                            resourcePermission.setName(name);
1157                            resourcePermission.setScope(scope);
1158                            resourcePermission.setPrimKey(primKey);
1159                            resourcePermission.setRoleId(roleId);
1160                            resourcePermission.setOwnerId(ownerId);
1161                    }
1162    
1163                    List<String> unsupportedActionIds = Collections.emptyList();
1164    
1165                    if (((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1166                             (operator == ResourcePermissionConstants.OPERATOR_SET)) &&
1167                            isGuestRoleId(companyId, roleId)) {
1168    
1169                            unsupportedActionIds =
1170                                    ResourceActionsUtil.getResourceGuestUnsupportedActions(
1171                                            name, name);
1172                    }
1173    
1174                    long actionIdsLong = resourcePermission.getActionIds();
1175    
1176                    if (operator == ResourcePermissionConstants.OPERATOR_SET) {
1177                            actionIdsLong = 0;
1178                    }
1179    
1180                    for (String actionId : actionIds) {
1181                            if (actionId == null) {
1182                                    break;
1183                            }
1184    
1185                            if (unsupportedActionIds.contains(actionId)) {
1186                                    throw new PrincipalException(
1187                                            actionId + "is not supported by role " + roleId);
1188                            }
1189    
1190                            ResourceAction resourceAction =
1191                                    resourceActionLocalService.getResourceAction(name, actionId);
1192    
1193                            if ((operator == ResourcePermissionConstants.OPERATOR_ADD) ||
1194                                    (operator == ResourcePermissionConstants.OPERATOR_SET)) {
1195    
1196                                    actionIdsLong |= resourceAction.getBitwiseValue();
1197                            }
1198                            else {
1199                                    actionIdsLong =
1200                                            actionIdsLong & (~resourceAction.getBitwiseValue());
1201                            }
1202                    }
1203    
1204                    resourcePermission.setActionIds(actionIdsLong);
1205    
1206                    resourcePermissionPersistence.update(resourcePermission);
1207    
1208                    PermissionCacheUtil.clearCache();
1209    
1210                    SearchEngineUtil.updatePermissionFields(name, primKey);
1211            }
1212    
1213            protected void doUpdateResourcePermission(
1214                            long companyId, String name, int scope, String primKey,
1215                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1216                    throws PortalException, SystemException {
1217    
1218                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
1219    
1220                    PermissionThreadLocal.setIndexEnabled(false);
1221    
1222                    try {
1223                            long[] roleIds = ArrayUtil.toLongArray(roleIdsToActionIds.keySet());
1224    
1225                            List<ResourcePermission> resourcePermissions =
1226                                    resourcePermissionPersistence.findByC_N_S_P_R(
1227                                            companyId, name, scope, primKey, roleIds);
1228    
1229                            for (ResourcePermission resourcePermission : resourcePermissions) {
1230                                    long roleId = resourcePermission.getRoleId();
1231                                    String[] actionIds = roleIdsToActionIds.remove(roleId);
1232    
1233                                    doUpdateResourcePermission(
1234                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1235                                            ResourcePermissionConstants.OPERATOR_SET, true);
1236                            }
1237    
1238                            if (roleIdsToActionIds.isEmpty()) {
1239                                    return;
1240                            }
1241    
1242                            for (Map.Entry<Long, String[]> entry :
1243                                            roleIdsToActionIds.entrySet()) {
1244    
1245                                    long roleId = entry.getKey();
1246                                    String[] actionIds = entry.getValue();
1247    
1248                                    doUpdateResourcePermission(
1249                                            companyId, name, scope, primKey, ownerId, roleId, actionIds,
1250                                            ResourcePermissionConstants.OPERATOR_SET, false);
1251                            }
1252                    }
1253                    finally {
1254                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
1255    
1256                            PermissionCacheUtil.clearCache();
1257    
1258                            SearchEngineUtil.updatePermissionFields(name, primKey);
1259                    }
1260            }
1261    
1262            protected boolean isGuestRoleId(long companyId, long roleId)
1263                    throws PortalException, SystemException {
1264    
1265                    Role guestRole = roleLocalService.getRole(
1266                            companyId, RoleConstants.GUEST);
1267    
1268                    if (roleId == guestRole.getRoleId()) {
1269                            return true;
1270                    }
1271    
1272                    return false;
1273            }
1274    
1275            /**
1276             * Updates the role's permissions at the scope, either adding to, removing
1277             * from, or setting the actions that can be performed on resources of the
1278             * type. Automatically creates a new resource permission if none exists, or
1279             * deletes the existing resource permission if it no longer grants
1280             * permissions to perform any action.
1281             *
1282             * <p>
1283             * Depending on the scope, the value of <code>primKey</code> will have
1284             * different meanings. For more information, see {@link
1285             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1286             * </p>
1287             *
1288             * @param  companyId the primary key of the company
1289             * @param  name the resource's name, which can be either a class name or a
1290             *         portlet ID
1291             * @param  scope the scope
1292             * @param  primKey the primary key
1293             * @param  roleId the primary key of the role
1294             * @param  ownerId the primary key of the owner
1295             * @param  actionIds the action IDs of the actions
1296             * @param  operator whether to add to, remove from, or set/replace the
1297             *         existing actions. Possible values can be found in {@link
1298             *         ResourcePermissionConstants}.
1299             * @throws PortalException if a role with the primary key or a resource
1300             *         action with the name and action ID could not be found
1301             * @throws SystemException if a system exception occurred
1302             */
1303            protected void updateResourcePermission(
1304                            long companyId, String name, int scope, String primKey, long roleId,
1305                            long ownerId, String[] actionIds, int operator)
1306                    throws PortalException, SystemException {
1307    
1308                    DB db = DBFactoryUtil.getDB();
1309    
1310                    String dbType = db.getType();
1311    
1312                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1313                            doUpdateResourcePermission(
1314                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1315                                    operator, true);
1316    
1317                            return;
1318                    }
1319    
1320                    StringBundler sb = new StringBundler(9);
1321    
1322                    sb.append(companyId);
1323                    sb.append(StringPool.POUND);
1324                    sb.append(name);
1325                    sb.append(StringPool.POUND);
1326                    sb.append(scope);
1327                    sb.append(StringPool.POUND);
1328                    sb.append(primKey);
1329                    sb.append(StringPool.POUND);
1330                    sb.append(roleId);
1331    
1332                    Class<?> clazz = getClass();
1333    
1334                    String groupName = clazz.getName();
1335    
1336                    String key = sb.toString();
1337    
1338                    Lock lock = LockRegistry.allocateLock(groupName, key);
1339    
1340                    lock.lock();
1341    
1342                    try {
1343                            doUpdateResourcePermission(
1344                                    companyId, name, scope, primKey, ownerId, roleId, actionIds,
1345                                    operator, true);
1346                    }
1347                    finally {
1348                            lock.unlock();
1349    
1350                            LockRegistry.freeLock(groupName, key);
1351                    }
1352            }
1353    
1354            /**
1355             * Updates the role's permissions at the scope, either adding to, removing
1356             * from, or setting the actions that can be performed on resources of the
1357             * type. Automatically creates a new resource permission if none exists, or
1358             * deletes the existing resource permission if it no longer grants
1359             * permissions to perform any action.
1360             *
1361             * <p>
1362             * Depending on the scope, the value of <code>primKey</code> will have
1363             * different meanings. For more information, see {@link
1364             * com.liferay.portal.model.impl.ResourcePermissionImpl}.
1365             * </p>
1366             *
1367             * @param  companyId the primary key of the company
1368             * @param  name the resource's name, which can be either a class name or a
1369             *         portlet ID
1370             * @param  scope the scope
1371             * @param  primKey the primary key
1372             * @param  ownerId the primary key of the owner
1373             * @throws PortalException if a role with the primary key or a resource
1374             *         action with the name and action ID could not be found
1375             * @throws SystemException if a system exception occurred
1376             */
1377            protected void updateResourcePermission(
1378                            long companyId, String name, int scope, String primKey,
1379                            long ownerId, Map<Long, String[]> roleIdsToActionIds)
1380                    throws PortalException, SystemException {
1381    
1382                    DB db = DBFactoryUtil.getDB();
1383    
1384                    String dbType = db.getType();
1385    
1386                    if (!dbType.equals(DB.TYPE_HYPERSONIC)) {
1387                            doUpdateResourcePermission(
1388                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1389    
1390                            return;
1391                    }
1392    
1393                    StringBundler sb = new StringBundler(9);
1394    
1395                    sb.append(companyId);
1396                    sb.append(StringPool.POUND);
1397                    sb.append(name);
1398                    sb.append(StringPool.POUND);
1399                    sb.append(scope);
1400                    sb.append(StringPool.POUND);
1401                    sb.append(primKey);
1402                    sb.append(StringPool.POUND);
1403                    sb.append(StringUtil.merge(roleIdsToActionIds.keySet()));
1404    
1405                    Class<?> clazz = getClass();
1406    
1407                    String groupName = clazz.getName();
1408    
1409                    String key = sb.toString();
1410    
1411                    Lock lock = LockRegistry.allocateLock(groupName, key);
1412    
1413                    lock.lock();
1414    
1415                    try {
1416                            doUpdateResourcePermission(
1417                                    companyId, name, scope, primKey, ownerId, roleIdsToActionIds);
1418                    }
1419                    finally {
1420                            lock.unlock();
1421    
1422                            LockRegistry.freeLock(groupName, key);
1423                    }
1424            }
1425    
1426            private static final String _FIND_MISSING_RESOURCE_PERMISSIONS =
1427                    ResourcePermissionLocalServiceImpl.class.getName() +
1428                            ".findMissingResourcePermissions";
1429    
1430            private static final String _UPDATE_ACTION_IDS =
1431                    ResourcePermissionLocalServiceImpl.class.getName() + ".updateActionIds";
1432    
1433    }