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