001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateRoleException;
018    import com.liferay.portal.NoSuchRoleException;
019    import com.liferay.portal.RequiredRoleException;
020    import com.liferay.portal.RoleNameException;
021    import com.liferay.portal.kernel.cache.Lifecycle;
022    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
023    import com.liferay.portal.kernel.cache.ThreadLocalCache;
024    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.lar.ImportExportThreadLocal;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.spring.aop.Skip;
031    import com.liferay.portal.kernel.transaction.Propagation;
032    import com.liferay.portal.kernel.transaction.Transactional;
033    import com.liferay.portal.kernel.util.CharPool;
034    import com.liferay.portal.kernel.util.GetterUtil;
035    import com.liferay.portal.kernel.util.LocaleUtil;
036    import com.liferay.portal.kernel.util.OrderByComparator;
037    import com.liferay.portal.kernel.util.StringUtil;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.model.Company;
040    import com.liferay.portal.model.Group;
041    import com.liferay.portal.model.Layout;
042    import com.liferay.portal.model.ResourceAction;
043    import com.liferay.portal.model.ResourceConstants;
044    import com.liferay.portal.model.ResourcePermission;
045    import com.liferay.portal.model.Role;
046    import com.liferay.portal.model.RoleConstants;
047    import com.liferay.portal.model.Team;
048    import com.liferay.portal.model.User;
049    import com.liferay.portal.security.permission.ActionKeys;
050    import com.liferay.portal.security.permission.PermissionCacheUtil;
051    import com.liferay.portal.service.base.RoleLocalServiceBaseImpl;
052    import com.liferay.portal.util.PortalUtil;
053    import com.liferay.portal.util.PortletKeys;
054    import com.liferay.portal.util.PropsUtil;
055    import com.liferay.portal.util.PropsValues;
056    import com.liferay.portlet.usersadmin.util.UsersAdminUtil;
057    
058    import java.util.ArrayList;
059    import java.util.Arrays;
060    import java.util.Collections;
061    import java.util.HashMap;
062    import java.util.LinkedHashMap;
063    import java.util.List;
064    import java.util.Locale;
065    import java.util.Map;
066    
067    /**
068     * The implementation of the role local service.
069     *
070     * @author Brian Wing Shun Chan
071     * @author Marcellus Tavares
072     */
073    public class RoleLocalServiceImpl extends RoleLocalServiceBaseImpl {
074    
075            /**
076             * Adds a role. The user is reindexed after role is added.
077             *
078             * @param  userId the primary key of the user
079             * @param  companyId the primary key of the company
080             * @param  name the role's name
081             * @param  titleMap the role's localized titles (optionally
082             *         <code>null</code>)
083             * @param  descriptionMap the role's localized descriptions (optionally
084             *         <code>null</code>)
085             * @param  type the role's type (optionally <code>0</code>)
086             * @return the role
087             * @throws PortalException if the class name or the role name were invalid,
088             *         if the role is a duplicate, or if a user with the primary key
089             *         could not be found
090             * @throws SystemException if a system exception occurred
091             */
092            public Role addRole(
093                            long userId, long companyId, String name,
094                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
095                            int type)
096                    throws PortalException, SystemException {
097    
098                    return addRole(
099                            userId, companyId, name, titleMap, descriptionMap, type, null, 0);
100            }
101    
102            /**
103             * Adds a role with additional parameters. The user is reindexed after role
104             * is added.
105             *
106             * @param  userId the primary key of the user
107             * @param  companyId the primary key of the company
108             * @param  name the role's name
109             * @param  titleMap the role's localized titles (optionally
110             *         <code>null</code>)
111             * @param  descriptionMap the role's localized descriptions (optionally
112             *         <code>null</code>)
113             * @param  type the role's type (optionally <code>0</code>)
114             * @param  className the name of the class for which the role is created
115             *         (optionally <code>null</code>)
116             * @param  classPK the primary key of the class for which the role is
117             *         created (optionally <code>0</code>)
118             * @return the role
119             * @throws PortalException if the class name or the role name were invalid,
120             *         if the role is a duplicate, or if a user with the primary key
121             *         could not be found
122             * @throws SystemException if a system exception occurred
123             */
124            public Role addRole(
125                            long userId, long companyId, String name,
126                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
127                            int type, String className, long classPK)
128                    throws PortalException, SystemException {
129    
130                    // Role
131    
132                    className = GetterUtil.getString(className);
133                    long classNameId = PortalUtil.getClassNameId(className);
134    
135                    long roleId = counterLocalService.increment();
136    
137                    if ((classNameId <= 0) || className.equals(Role.class.getName())) {
138                            classNameId = PortalUtil.getClassNameId(Role.class);
139                            classPK = roleId;
140                    }
141    
142                    validate(0, companyId, classNameId, name);
143    
144                    Role role = rolePersistence.create(roleId);
145    
146                    role.setCompanyId(companyId);
147                    role.setClassNameId(classNameId);
148                    role.setClassPK(classPK);
149                    role.setName(name);
150                    role.setTitleMap(titleMap);
151                    role.setDescriptionMap(descriptionMap);
152                    role.setType(type);
153    
154                    rolePersistence.update(role, false);
155    
156                    // Resources
157    
158                    if (userId > 0) {
159                            resourceLocalService.addResources(
160                                    companyId, 0, userId, Role.class.getName(), role.getRoleId(),
161                                    false, false, false);
162    
163                            if (!ImportExportThreadLocal.isImportInProcess()) {
164                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
165                                            User.class);
166    
167                                    indexer.reindex(userId);
168                            }
169                    }
170    
171                    return role;
172            }
173    
174            /**
175             * Adds the roles to the user. The user is reindexed after the roles are
176             * added.
177             *
178             * @param  userId the primary key of the user
179             * @param  roleIds the primary keys of the roles
180             * @throws PortalException if a user with the primary key could not be found
181             * @throws SystemException if a system exception occurred
182             * @see    com.liferay.portal.service.persistence.UserPersistence#addRoles(
183             *         long, long[])
184             */
185            public void addUserRoles(long userId, long[] roleIds)
186                    throws PortalException, SystemException {
187    
188                    userPersistence.addRoles(userId, roleIds);
189    
190                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
191    
192                    indexer.reindex(userId);
193    
194                    PermissionCacheUtil.clearCache();
195            }
196    
197            /**
198             * Checks to ensure that the system roles map has appropriate default roles
199             * in each company.
200             *
201             * @throws PortalException if the current user did not have permission to
202             *         set applicable permissions on a role
203             * @throws SystemException if a system exception occurred
204             */
205            public void checkSystemRoles() throws PortalException, SystemException {
206                    List<Company> companies = companyLocalService.getCompanies();
207    
208                    for (Company company : companies) {
209                            checkSystemRoles(company.getCompanyId());
210                    }
211            }
212    
213            /**
214             * Checks to ensure that the system roles map has appropriate default roles
215             * in the company.
216             *
217             * @param  companyId the primary key of the company
218             * @throws PortalException if the current user did not have permission to
219             *         set applicable permissions on a role
220             * @throws SystemException if a system exception occurred
221             */
222            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
223            public void checkSystemRoles(long companyId)
224                    throws PortalException, SystemException {
225    
226                    String companyIdHexString = StringUtil.toHexString(companyId);
227    
228                    for (Role role : roleFinder.findBySystem(companyId)) {
229                            _systemRolesMap.put(
230                                    companyIdHexString.concat(role.getName()), role);
231                    }
232    
233                    // Regular roles
234    
235                    String[] systemRoles = PortalUtil.getSystemRoles();
236    
237                    for (String name : systemRoles) {
238                            String key =
239                                    "system.role." +
240                                            StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
241                                                    ".description";
242    
243                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
244    
245                            descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key));
246    
247                            int type = RoleConstants.TYPE_REGULAR;
248    
249                            checkSystemRole(companyId, name, descriptionMap, type);
250                    }
251    
252                    // Organization roles
253    
254                    String[] systemOrganizationRoles =
255                            PortalUtil.getSystemOrganizationRoles();
256    
257                    for (String name : systemOrganizationRoles) {
258                            String key =
259                                    "system.organization.role." +
260                                            StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
261                                                    ".description";
262    
263                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
264    
265                            descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key));
266    
267                            int type = RoleConstants.TYPE_ORGANIZATION;
268    
269                            checkSystemRole(companyId, name, descriptionMap, type);
270                    }
271    
272                    // Site roles
273    
274                    String[] systemSiteRoles = PortalUtil.getSystemSiteRoles();
275    
276                    for (String name : systemSiteRoles) {
277                            String key =
278                                    "system.site.role." +
279                                            StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
280                                                    ".description";
281    
282                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
283    
284                            descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key));
285    
286                            int type = RoleConstants.TYPE_SITE;
287    
288                            checkSystemRole(companyId, name, descriptionMap, type);
289                    }
290            }
291    
292            /**
293             * Deletes the role with the primary key and its associated permissions.
294             *
295             * @param  roleId the primary key of the role
296             * @throws PortalException if a role with the primary key could not be
297             *         found, if the role is a default system role, or if the role's
298             *         resource could not be found
299             * @throws SystemException if a system exception occurred
300             */
301            @Override
302            public Role deleteRole(long roleId)
303                    throws PortalException, SystemException {
304    
305                    Role role = rolePersistence.findByPrimaryKey(roleId);
306    
307                    return deleteRole(role);
308            }
309    
310            /**
311             * Deletes the role and its associated permissions.
312             *
313             * @param  role the role
314             * @throws PortalException if the role is a default system role or if the
315             *         role's resource could not be found
316             * @throws SystemException if a system exception occurred
317             */
318            @Override
319            public Role deleteRole(Role role) throws PortalException, SystemException {
320                    if (PortalUtil.isSystemRole(role.getName())) {
321                            throw new RequiredRoleException();
322                    }
323    
324                    // Resources
325    
326                    List<ResourcePermission> resourcePermissions =
327                            resourcePermissionPersistence.findByRoleId(role.getRoleId());
328    
329                    for (ResourcePermission resourcePermission : resourcePermissions) {
330                            resourcePermissionLocalService.deleteResourcePermission(
331                                    resourcePermission);
332                    }
333    
334                    String className = role.getClassName();
335                    long classNameId = role.getClassNameId();
336    
337                    if ((classNameId <= 0) || className.equals(Role.class.getName())) {
338                            resourceLocalService.deleteResource(
339                                    role.getCompanyId(), Role.class.getName(),
340                                    ResourceConstants.SCOPE_INDIVIDUAL, role.getRoleId());
341                    }
342    
343                    if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
344                            (role.getType() == RoleConstants.TYPE_SITE)) {
345    
346                            userGroupRoleLocalService.deleteUserGroupRolesByRoleId(
347                                    role.getRoleId());
348    
349                            userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByRoleId(
350                                    role.getRoleId());
351                    }
352    
353                    // Role
354    
355                    rolePersistence.remove(role);
356    
357                    // Permission cache
358    
359                    PermissionCacheUtil.clearCache();
360    
361                    return role;
362            }
363    
364            /**
365             * Returns the role with the name in the company.
366             *
367             * <p>
368             * The method searches the system roles map first for default roles. If a
369             * role with the name is not found, then the method will query the database.
370             * </p>
371             *
372             * @param  companyId the primary key of the company
373             * @param  name the role's name
374             * @return Returns the role with the name or <code>null</code> if a role
375             *         with the name could not be found in the company
376             * @throws SystemException if a system exception occurred
377             */
378            @Skip
379            public Role fetchRole(long companyId, String name) throws SystemException {
380                    String companyIdHexString = StringUtil.toHexString(companyId);
381    
382                    Role role = _systemRolesMap.get(companyIdHexString.concat(name));
383    
384                    if (role != null) {
385                            return role;
386                    }
387    
388                    return roleLocalService.loadFetchRole(companyId, name);
389            }
390    
391            /**
392             * Returns the default role for the group with the primary key.
393             *
394             * <p>
395             * If the group is a site, then the default role is {@link
396             * com.liferay.portal.model.RoleConstants#SITE_MEMBER}. If the group is an
397             * organization, then the default role is {@link
398             * com.liferay.portal.model.RoleConstants#ORGANIZATION_USER}. If the group
399             * is a user or user group, then the default role is {@link
400             * com.liferay.portal.model.RoleConstants#POWER_USER}. For all other group
401             * types, the default role is {@link
402             * com.liferay.portal.model.RoleConstants#USER}.
403             * </p>
404             *
405             * @param  groupId the primary key of the group
406             * @return the default role for the group with the primary key
407             * @throws PortalException if a group with the primary key could not be
408             *         found, or if a default role could not be found for the group
409             * @throws SystemException if a system exception occurred
410             */
411            public Role getDefaultGroupRole(long groupId)
412                    throws PortalException, SystemException {
413    
414                    Group group = groupPersistence.findByPrimaryKey(groupId);
415    
416                    if (group.isLayout()) {
417                            Layout layout = layoutLocalService.getLayout(group.getClassPK());
418    
419                            group = layout.getGroup();
420                    }
421    
422                    if (group.isStagingGroup()) {
423                            group = group.getLiveGroup();
424                    }
425    
426                    Role role = null;
427    
428                    if (group.isCompany()) {
429                            role = getRole(group.getCompanyId(), RoleConstants.USER);
430                    }
431                    else if (group.isLayoutPrototype() || group.isLayoutSetPrototype() ||
432                                     group.isRegularSite() || group.isSite()) {
433    
434                            role = getRole(group.getCompanyId(), RoleConstants.SITE_MEMBER);
435                    }
436                    else if (group.isOrganization()) {
437                            role = getRole(
438                                    group.getCompanyId(), RoleConstants.ORGANIZATION_USER);
439                    }
440                    else if (group.isUser() || group.isUserGroup()) {
441                            role = getRole(group.getCompanyId(), RoleConstants.POWER_USER);
442                    }
443                    else {
444                            role = getRole(group.getCompanyId(), RoleConstants.USER);
445                    }
446    
447                    return role;
448            }
449    
450            /**
451             * Returns all the roles associated with the group.
452             *
453             * @param  groupId the primary key of the group
454             * @return the roles associated with the group
455             * @throws SystemException if a system exception occurred
456             */
457            public List<Role> getGroupRoles(long groupId) throws SystemException {
458                    return groupPersistence.getRoles(groupId);
459            }
460    
461            public List<Role> getResourceBlockRoles(
462                            long resourceBlockId, String className, String actionId)
463                    throws SystemException {
464    
465                    return roleFinder.findByR_N_A(resourceBlockId, className, actionId);
466            }
467    
468            /**
469             * Returns a map of role names to associated action IDs for the named
470             * resource in the company within the permission scope.
471             *
472             * @param  companyId the primary key of the company
473             * @param  name the resource name
474             * @param  scope the permission scope
475             * @param  primKey the primary key of the resource's class
476             * @return the role names and action IDs
477             * @throws SystemException if a system exception occurred
478             * @see    com.liferay.portal.service.persistence.RoleFinder#findByC_N_S_P(
479             *         long, String, int, String)
480             */
481            public Map<String, List<String>> getResourceRoles(
482                            long companyId, String name, int scope, String primKey)
483                    throws SystemException {
484    
485                    return roleFinder.findByC_N_S_P(companyId, name, scope, primKey);
486            }
487    
488            /**
489             * Returns all the roles associated with the action ID in the company within
490             * the permission scope.
491             *
492             * @param  companyId the primary key of the company
493             * @param  name the resource name
494             * @param  scope the permission scope
495             * @param  primKey the primary key of the resource's class
496             * @param  actionId the name of the resource action
497             * @return the roles
498             * @throws SystemException if a system exception occurred
499             * @see    com.liferay.portal.service.persistence.RoleFinder#findByC_N_S_P_A(
500             *         long, String, int, String, String)
501             */
502            public List<Role> getResourceRoles(
503                            long companyId, String name, int scope, String primKey,
504                            String actionId)
505                    throws SystemException {
506    
507                    return roleFinder.findByC_N_S_P_A(
508                            companyId, name, scope, primKey, actionId);
509            }
510    
511            /**
512             * Returns the role with the name in the company.
513             *
514             * <p>
515             * The method searches the system roles map first for default roles. If a
516             * role with the name is not found, then the method will query the database.
517             * </p>
518             *
519             * @param  companyId the primary key of the company
520             * @param  name the role's name
521             * @return the role with the name
522             * @throws PortalException if a role with the name could not be found in the
523             *         company
524             * @throws SystemException if a system exception occurred
525             */
526            @Skip
527            public Role getRole(long companyId, String name)
528                    throws PortalException, SystemException {
529    
530                    String companyIdHexString = StringUtil.toHexString(companyId);
531    
532                    Role role = _systemRolesMap.get(companyIdHexString.concat(name));
533    
534                    if (role != null) {
535                            return role;
536                    }
537    
538                    return roleLocalService.loadGetRole(companyId, name);
539            }
540    
541            /**
542             * Returns all the roles of the type and subtype.
543             *
544             * @param  type the role's type (optionally <code>0</code>)
545             * @param  subtype the role's subtype (optionally <code>null</code>)
546             * @return the roles of the type and subtype
547             * @throws SystemException if a system exception occurred
548             */
549            public List<Role> getRoles(int type, String subtype)
550                    throws SystemException {
551    
552                    return rolePersistence.findByT_S(type, subtype);
553            }
554    
555            /**
556             * Returns all the roles in the company.
557             *
558             * @param  companyId the primary key of the company
559             * @return the roles in the company
560             * @throws SystemException if a system exception occurred
561             */
562            public List<Role> getRoles(long companyId) throws SystemException {
563                    return rolePersistence.findByCompanyId(companyId);
564            }
565    
566            /**
567             * Returns all the roles with the primary keys.
568             *
569             * @param  roleIds the primary keys of the roles
570             * @return the roles with the primary keys
571             * @throws PortalException if any one of the roles with the primary keys
572             *         could not be found
573             * @throws SystemException if a system exception occurred
574             */
575            public List<Role> getRoles(long[] roleIds)
576                    throws PortalException, SystemException {
577    
578                    List<Role> roles = new ArrayList<Role>(roleIds.length);
579    
580                    for (long roleId : roleIds) {
581                            Role role = getRole(roleId);
582    
583                            roles.add(role);
584                    }
585    
586                    return roles;
587            }
588    
589            /**
590             * Returns all the roles of the subtype.
591             *
592             * @param  subtype the role's subtype (optionally <code>null</code>)
593             * @return the roles of the subtype
594             * @throws SystemException if a system exception occurred
595             */
596            public List<Role> getSubtypeRoles(String subtype) throws SystemException {
597                    return rolePersistence.findBySubtype(subtype);
598            }
599    
600            /**
601             * Returns the number of roles of the subtype.
602             *
603             * @param  subtype the role's subtype (optionally <code>null</code>)
604             * @return the number of roles of the subtype
605             * @throws SystemException if a system exception occurred
606             */
607            public int getSubtypeRolesCount(String subtype) throws SystemException {
608                    return rolePersistence.countBySubtype(subtype);
609            }
610    
611            /**
612             * Returns the team role in the company.
613             *
614             * @param  companyId the primary key of the company
615             * @param  teamId the primary key of the team
616             * @return the team role in the company
617             * @throws PortalException if a role could not be found in the team and
618             *         company
619             * @throws SystemException if a system exception occurred
620             */
621            public Role getTeamRole(long companyId, long teamId)
622                    throws PortalException, SystemException {
623    
624                    long classNameId = PortalUtil.getClassNameId(Team.class);
625    
626                    return rolePersistence.findByC_C_C(companyId, classNameId, teamId);
627            }
628    
629            /**
630             * Returns all the user's roles within the user group.
631             *
632             * @param  userId the primary key of the user
633             * @param  groupId the primary key of the group
634             * @return the user's roles within the user group
635             * @throws SystemException if a system exception occurred
636             * @see    com.liferay.portal.service.persistence.RoleFinder#findByUserGroupGroupRole(
637             *         long, long)
638             */
639            public List<Role> getUserGroupGroupRoles(long userId, long groupId)
640                    throws SystemException {
641    
642                    return roleFinder.findByUserGroupGroupRole(userId, groupId);
643            }
644    
645            /**
646             * Returns all the user's roles within the user group.
647             *
648             * @param  userId the primary key of the user
649             * @param  groupId the primary key of the group
650             * @return the user's roles within the user group
651             * @throws SystemException if a system exception occurred
652             * @see    com.liferay.portal.service.persistence.RoleFinder#findByUserGroupRole(
653             *         long, long)
654             */
655            public List<Role> getUserGroupRoles(long userId, long groupId)
656                    throws SystemException {
657    
658                    return roleFinder.findByUserGroupRole(userId, groupId);
659            }
660    
661            /**
662             * Returns the union of all the user's roles within the groups.
663             *
664             * @param  userId the primary key of the user
665             * @param  groups the groups (optionally <code>null</code>)
666             * @return the union of all the user's roles within the groups
667             * @throws SystemException if a system exception occurred
668             * @see    com.liferay.portal.service.persistence.RoleFinder#findByU_G(
669             *         long, List)
670             */
671            public List<Role> getUserRelatedRoles(long userId, List<Group> groups)
672                    throws SystemException {
673    
674                    if ((groups == null) || groups.isEmpty()) {
675                            return Collections.emptyList();
676                    }
677    
678                    return roleFinder.findByU_G(userId, groups);
679            }
680    
681            /**
682             * Returns all the user's roles within the group.
683             *
684             * @param  userId the primary key of the user
685             * @param  groupId the primary key of the group
686             * @return the user's roles within the group
687             * @throws SystemException if a system exception occurred
688             * @see    com.liferay.portal.service.persistence.RoleFinder#findByU_G(
689             *         long, long)
690             */
691            public List<Role> getUserRelatedRoles(long userId, long groupId)
692                    throws SystemException {
693    
694                    return roleFinder.findByU_G(userId, groupId);
695            }
696    
697            /**
698             * Returns the union of all the user's roles within the groups.
699             *
700             * @param  userId the primary key of the user
701             * @param  groupIds the primary keys of the groups
702             * @return the union of all the user's roles within the groups
703             * @throws SystemException if a system exception occurred
704             * @see    com.liferay.portal.service.persistence.RoleFinder#findByU_G(
705             *         long, long[])
706             */
707            public List<Role> getUserRelatedRoles(long userId, long[] groupIds)
708                    throws SystemException {
709    
710                    return roleFinder.findByU_G(userId, groupIds);
711            }
712    
713            /**
714             * Returns all the roles associated with the user.
715             *
716             * @param  userId the primary key of the user
717             * @return the roles associated with the user
718             * @throws SystemException if a system exception occurred
719             */
720            public List<Role> getUserRoles(long userId) throws SystemException {
721                    return userPersistence.getRoles(userId);
722            }
723    
724            /**
725             * Returns <code>true</code> if the user is associated with the role.
726             *
727             * @param  userId the primary key of the user
728             * @param  roleId the primary key of the role
729             * @return <code>true</code> if the user is associated with the role;
730             *         <code>false</code> otherwise
731             * @throws SystemException if a system exception occurred
732             */
733            public boolean hasUserRole(long userId, long roleId)
734                    throws SystemException {
735    
736                    return userPersistence.containsRole(userId, roleId);
737            }
738    
739            /**
740             * Returns <code>true</code> if the user is associated with the named
741             * regular role.
742             *
743             * @param  userId the primary key of the user
744             * @param  companyId the primary key of the company
745             * @param  name the name of the role
746             * @param  inherited whether to include the user's inherited roles in the
747             *         search
748             * @return <code>true</code> if the user is associated with the regular
749             *         role; <code>false</code> otherwise
750             * @throws PortalException if a role with the name could not be found in the
751             *         company or if a default user for the company could not be found
752             * @throws SystemException if a system exception occurred
753             */
754            @ThreadLocalCachable
755            public boolean hasUserRole(
756                            long userId, long companyId, String name, boolean inherited)
757                    throws PortalException, SystemException {
758    
759                    Role role = rolePersistence.findByC_N(companyId, name);
760    
761                    if (role.getType() != RoleConstants.TYPE_REGULAR) {
762                            throw new IllegalArgumentException(name + " is not a regular role");
763                    }
764    
765                    long defaultUserId = userLocalService.getDefaultUserId(companyId);
766    
767                    if (userId == defaultUserId) {
768                            if (name.equals(RoleConstants.GUEST)) {
769                                    return true;
770                            }
771                            else {
772                                    return false;
773                            }
774                    }
775    
776                    if (inherited) {
777                            if (userPersistence.containsRole(userId, role.getRoleId())) {
778                                    return true;
779                            }
780    
781                            ThreadLocalCache<Integer> threadLocalCache =
782                                    ThreadLocalCacheManager.getThreadLocalCache(
783                                            Lifecycle.REQUEST, RoleLocalServiceImpl.class.getName());
784    
785                            String key = String.valueOf(role.getRoleId()).concat(
786                                    String.valueOf(userId));
787    
788                            Integer value = threadLocalCache.get(key);
789    
790                            if (value == null) {
791                                    value = roleFinder.countByR_U(role.getRoleId(), userId);
792    
793                                    threadLocalCache.put(key, value);
794                            }
795    
796                            if (value > 0) {
797                                    return true;
798                            }
799                            else {
800                                    return false;
801                            }
802                    }
803                    else {
804                            return userPersistence.containsRole(userId, role.getRoleId());
805                    }
806            }
807    
808            /**
809             * Returns <code>true</code> if the user has any one of the named regular
810             * roles.
811             *
812             * @param  userId the primary key of the user
813             * @param  companyId the primary key of the company
814             * @param  names the names of the roles
815             * @param  inherited whether to include the user's inherited roles in the
816             *         search
817             * @return <code>true</code> if the user has any one of the regular roles;
818             *         <code>false</code> otherwise
819             * @throws PortalException if any one of the roles with the names could not
820             *         be found in the company or if the default user for the company
821             *         could not be found
822             * @throws SystemException if a system exception occurred
823             */
824            public boolean hasUserRoles(
825                            long userId, long companyId, String[] names, boolean inherited)
826                    throws PortalException, SystemException {
827    
828                    for (String name : names) {
829                            if (hasUserRole(userId, companyId, name, inherited)) {
830                                    return true;
831                            }
832                    }
833    
834                    return false;
835            }
836    
837            /**
838             * Returns a role with the name in the company.
839             *
840             * @param  companyId the primary key of the company
841             * @param  name the role's name (optionally <code>null</code>)
842             * @return the role with the name, or <code>null</code> if a role with the
843             *         name could not be found in the company
844             * @throws SystemException if a system exception occurred
845             */
846            public Role loadFetchRole(long companyId, String name)
847                    throws SystemException {
848    
849                    return rolePersistence.fetchByC_N(companyId, name);
850            }
851    
852            /**
853             * Returns a role with the name in the company.
854             *
855             * @param  companyId the primary key of the company
856             * @param  name the role's name
857             * @return the role with the name in the company
858             * @throws PortalException if a role with the name could not be found in the
859             *         company
860             * @throws SystemException if a system exception occurred
861             */
862            public Role loadGetRole(long companyId, String name)
863                    throws PortalException, SystemException {
864    
865                    return rolePersistence.findByC_N(companyId, name);
866            }
867    
868            /**
869             * Returns an ordered range of all the roles that match the keywords and
870             * types.
871             *
872             * <p>
873             * Useful when paginating results. Returns a maximum of <code>end -
874             * start</code> instances. <code>start</code> and <code>end</code> are not
875             * primary keys, they are indexes in the result set. Thus, <code>0</code>
876             * refers to the first result in the set. Setting both <code>start</code>
877             * and <code>end</code> to {@link
878             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
879             * result set.
880             * </p>
881             *
882             * @param  companyId the primary key of the company
883             * @param  keywords the keywords (space separated), which may occur in the
884             *         role's name or description (optionally <code>null</code>)
885             * @param  types the role types (optionally <code>null</code>)
886             * @param  start the lower bound of the range of roles to return
887             * @param  end the upper bound of the range of roles to return (not
888             *         inclusive)
889             * @param  obc the comparator to order the roles (optionally
890             *         <code>null</code>)
891             * @return the ordered range of the matching roles, ordered by
892             *         <code>obc</code>
893             * @throws SystemException if a system exception occurred
894             * @see    com.liferay.portal.service.persistence.RoleFinder
895             */
896            public List<Role> search(
897                            long companyId, String keywords, Integer[] types, int start,
898                            int end, OrderByComparator obc)
899                    throws SystemException {
900    
901                    return search(
902                            companyId, keywords, types, new LinkedHashMap<String, Object>(),
903                            start, end, obc);
904            }
905    
906            /**
907             * Returns an ordered range of all the roles that match the keywords, types,
908             * and params.
909             *
910             * <p>
911             * Useful when paginating results. Returns a maximum of <code>end -
912             * start</code> instances. <code>start</code> and <code>end</code> are not
913             * primary keys, they are indexes in the result set. Thus, <code>0</code>
914             * refers to the first result in the set. Setting both <code>start</code>
915             * and <code>end</code> to {@link
916             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
917             * result set.
918             * </p>
919             *
920             * @param  companyId the primary key of the company
921             * @param  keywords the keywords (space separated), which may occur in the
922             *         role's name or description (optionally <code>null</code>)
923             * @param  types the role types (optionally <code>null</code>)
924             * @param  params the finder parameters. Can specify values for
925             *         "permissionsResourceId" and "usersRoles" keys. For more
926             *         information, see {@link
927             *         com.liferay.portal.service.persistence.RoleFinder}
928             * @param  start the lower bound of the range of roles to return
929             * @param  end the upper bound of the range of roles to return (not
930             *         inclusive)
931             * @param  obc the comparator to order the roles (optionally
932             *         <code>null</code>)
933             * @return the ordered range of the matching roles, ordered by
934             *         <code>obc</code>
935             * @throws SystemException if a system exception occurred
936             * @see    com.liferay.portal.service.persistence.RoleFinder
937             */
938            public List<Role> search(
939                            long companyId, String keywords, Integer[] types,
940                            LinkedHashMap<String, Object> params, int start, int end,
941                            OrderByComparator obc)
942                    throws SystemException {
943    
944                    return roleFinder.findByKeywords(
945                            companyId, keywords, types, params, start, end, obc);
946            }
947    
948            /**
949             * Returns an ordered range of all the roles that match the name,
950             * description, and types.
951             *
952             * <p>
953             * Useful when paginating results. Returns a maximum of <code>end -
954             * start</code> instances. <code>start</code> and <code>end</code> are not
955             * primary keys, they are indexes in the result set. Thus, <code>0</code>
956             * refers to the first result in the set. Setting both <code>start</code>
957             * and <code>end</code> to {@link
958             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
959             * result set.
960             * </p>
961             *
962             * @param  companyId the primary key of the company
963             * @param  name the role's name (optionally <code>null</code>)
964             * @param  description the role's description (optionally <code>null</code>)
965             * @param  types the role types (optionally <code>null</code>)
966             * @param  start the lower bound of the range of the roles to return
967             * @param  end the upper bound of the range of the roles to return (not
968             *         inclusive)
969             * @param  obc the comparator to order the roles (optionally
970             *         <code>null</code>)
971             * @return the ordered range of the matching roles, ordered by
972             *         <code>obc</code>
973             * @throws SystemException if a system exception occurred
974             * @see    com.liferay.portal.service.persistence.RoleFinder
975             */
976            public List<Role> search(
977                            long companyId, String name, String description, Integer[] types,
978                            int start, int end, OrderByComparator obc)
979                    throws SystemException {
980    
981                    return search(
982                            companyId, name, description, types,
983                            new LinkedHashMap<String, Object>(), start, end, obc);
984            }
985    
986            /**
987             * Returns an ordered range of all the roles that match the name,
988             * description, types, and params.
989             *
990             * <p>
991             * Useful when paginating results. Returns a maximum of <code>end -
992             * start</code> instances. <code>start</code> and <code>end</code> are not
993             * primary keys, they are indexes in the result set. Thus, <code>0</code>
994             * refers to the first result in the set. Setting both <code>start</code>
995             * and <code>end</code> to {@link
996             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
997             * result set.
998             * </p>
999             *
1000             * @param  companyId the primary key of the company
1001             * @param  name the role's name (optionally <code>null</code>)
1002             * @param  description the role's description (optionally <code>null</code>)
1003             * @param  types the role types (optionally <code>null</code>)
1004             * @param  params the finder's parameters. Can specify values for
1005             *         "permissionsResourceId" and "usersRoles" keys. For more
1006             *         information, see {@link
1007             *         com.liferay.portal.service.persistence.RoleFinder}
1008             * @param  start the lower bound of the range of the roles to return
1009             * @param  end the upper bound of the range of the roles to return (not
1010             *         inclusive)
1011             * @param  obc the comparator to order the roles (optionally
1012             *         <code>null</code>)
1013             * @return the ordered range of the matching roles, ordered by
1014             *         <code>obc</code>
1015             * @throws SystemException if a system exception occurred
1016             * @see    com.liferay.portal.service.persistence.RoleFinder
1017             */
1018            public List<Role> search(
1019                            long companyId, String name, String description, Integer[] types,
1020                            LinkedHashMap<String, Object> params, int start, int end,
1021                            OrderByComparator obc)
1022                    throws SystemException {
1023    
1024                    return roleFinder.findByC_N_D_T(
1025                            companyId, name, description, types, params, true, start, end, obc);
1026            }
1027    
1028            /**
1029             * Returns the number of roles that match the keywords and types.
1030             *
1031             * @param  companyId the primary key of the company
1032             * @param  keywords the keywords (space separated), which may occur in the
1033             *         role's name or description (optionally <code>null</code>)
1034             * @param  types the role types (optionally <code>null</code>)
1035             * @return the number of matching roles
1036             * @throws SystemException if a system exception occurred
1037             */
1038            public int searchCount(long companyId, String keywords, Integer[] types)
1039                    throws SystemException {
1040    
1041                    return searchCount(
1042                            companyId, keywords, types, new LinkedHashMap<String, Object>());
1043            }
1044    
1045            /**
1046             * Returns the number of roles that match the keywords, types and params.
1047             *
1048             * @param  companyId the primary key of the company
1049             * @param  keywords the keywords (space separated), which may occur in the
1050             *         role's name or description (optionally <code>null</code>)
1051             * @param  types the role types (optionally <code>null</code>)
1052             * @param  params the finder parameters. For more information, see {@link
1053             *         com.liferay.portal.service.persistence.RoleFinder}
1054             * @return the number of matching roles
1055             * @throws SystemException if a system exception occurred
1056             */
1057            public int searchCount(
1058                            long companyId, String keywords, Integer[] types,
1059                            LinkedHashMap<String, Object> params)
1060                    throws SystemException {
1061    
1062                    return roleFinder.countByKeywords(companyId, keywords, types, params);
1063            }
1064    
1065            /**
1066             * Returns the number of roles that match the name, description, and types.
1067             *
1068             * @param  companyId the primary key of the company
1069             * @param  name the role's name (optionally <code>null</code>)
1070             * @param  description the role's description (optionally <code>null</code>)
1071             * @param  types the role types (optionally <code>null</code>)
1072             * @return the number of matching roles
1073             * @throws SystemException if a system exception occurred
1074             */
1075            public int searchCount(
1076                            long companyId, String name, String description, Integer[] types)
1077                    throws SystemException {
1078    
1079                    return searchCount(
1080                            companyId, name, description, types,
1081                            new LinkedHashMap<String, Object>());
1082            }
1083    
1084            /**
1085             * Returns the number of roles that match the name, description, types, and
1086             * params.
1087             *
1088             * @param  companyId the primary key of the company
1089             * @param  name the role's name (optionally <code>null</code>)
1090             * @param  description the role's description (optionally <code>null</code>)
1091             * @param  types the role types (optionally <code>null</code>)
1092             * @param  params the finder parameters. Can specify values for
1093             *         "permissionsResourceId" and "usersRoles" keys. For more
1094             *         information, see {@link
1095             *         com.liferay.portal.service.persistence.RoleFinder}
1096             * @return the number of matching roles
1097             * @throws SystemException if a system exception occurred
1098             */
1099            public int searchCount(
1100                            long companyId, String name, String description, Integer[] types,
1101                            LinkedHashMap<String, Object> params)
1102                    throws SystemException {
1103    
1104                    return roleFinder.countByC_N_D_T(
1105                            companyId, name, description, types, params, true);
1106            }
1107    
1108            /**
1109             * Sets the roles associated with the user, replacing the user's existing
1110             * roles. The user is reindexed after the roles are set.
1111             *
1112             * @param  userId the primary key of the user
1113             * @param  roleIds the primary keys of the roles
1114             * @throws PortalException if a user with the primary could not be found or
1115             *         if any one of the roles with the primary keys could not be found
1116             * @throws SystemException if a system exception occurred
1117             */
1118            public void setUserRoles(long userId, long[] roleIds)
1119                    throws PortalException, SystemException {
1120    
1121                    roleIds = UsersAdminUtil.addRequiredRoles(userId, roleIds);
1122    
1123                    userPersistence.setRoles(userId, roleIds);
1124    
1125                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
1126    
1127                    indexer.reindex(userId);
1128    
1129                    PermissionCacheUtil.clearCache();
1130            }
1131    
1132            /**
1133             * Removes the matching roles associated with the user. The user is
1134             * reindexed after the roles are removed.
1135             *
1136             * @param  userId the primary key of the user
1137             * @param  roleIds the primary keys of the roles
1138             * @throws PortalException if a user with the primary key could not be found
1139             *         or if a role with any one of the primary keys could not be found
1140             * @throws SystemException if a system exception occurred
1141             */
1142            public void unsetUserRoles(long userId, long[] roleIds)
1143                    throws PortalException, SystemException {
1144    
1145                    roleIds = UsersAdminUtil.removeRequiredRoles(userId, roleIds);
1146    
1147                    userPersistence.removeRoles(userId, roleIds);
1148    
1149                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
1150    
1151                    indexer.reindex(userId);
1152    
1153                    PermissionCacheUtil.clearCache();
1154            }
1155    
1156            /**
1157             * Updates the role with the primary key.
1158             *
1159             * @param  roleId the primary key of the role
1160             * @param  name the role's new name
1161             * @param  titleMap the new localized titles (optionally <code>null</code>)
1162             *         to replace those existing for the role
1163             * @param  descriptionMap the new localized descriptions (optionally
1164             *         <code>null</code>) to replace those existing for the role
1165             * @param  subtype the role's new subtype (optionally <code>null</code>)
1166             * @return the role with the primary key
1167             * @throws PortalException if a role with the primary could not be found or
1168             *         if the role's name was invalid
1169             * @throws SystemException if a system exception occurred
1170             */
1171            public Role updateRole(
1172                            long roleId, String name, Map<Locale, String> titleMap,
1173                            Map<Locale, String> descriptionMap, String subtype)
1174                    throws PortalException, SystemException {
1175    
1176                    Role role = rolePersistence.findByPrimaryKey(roleId);
1177    
1178                    validate(roleId, role.getCompanyId(), role.getClassNameId(), name);
1179    
1180                    if (PortalUtil.isSystemRole(role.getName())) {
1181                            name = role.getName();
1182                            subtype = null;
1183                    }
1184    
1185                    role.setName(name);
1186                    role.setTitleMap(titleMap);
1187                    role.setDescriptionMap(descriptionMap);
1188                    role.setSubtype(subtype);
1189    
1190                    rolePersistence.update(role, false);
1191    
1192                    return role;
1193            }
1194    
1195            protected void checkSystemRole(
1196                            long companyId, String name, Map<Locale, String> descriptionMap,
1197                            int type)
1198                    throws PortalException, SystemException {
1199    
1200                    String companyIdHexString = StringUtil.toHexString(companyId);
1201    
1202                    String key = companyIdHexString.concat(name);
1203    
1204                    Role role = _systemRolesMap.get(key);
1205    
1206                    try {
1207                            if (role == null) {
1208                                    role = rolePersistence.findByC_N(companyId, name);
1209                            }
1210    
1211                            if (!descriptionMap.equals(role.getDescriptionMap())) {
1212                                    role.setDescriptionMap(descriptionMap);
1213    
1214                                    roleLocalService.updateRole(role, false);
1215                            }
1216                    }
1217                    catch (NoSuchRoleException nsre) {
1218                            role = roleLocalService.addRole(
1219                                    0, companyId, name, null, descriptionMap, type);
1220                    }
1221    
1222                    if (name.equals(RoleConstants.USER)) {
1223                            initPersonalControlPanelPortletsPermissions(role);
1224                    }
1225    
1226                    _systemRolesMap.put(key, role);
1227            }
1228    
1229            protected String[] getDefaultControlPanelPortlets() {
1230                    return new String[] {
1231                            PortletKeys.MY_ACCOUNT, PortletKeys.MY_PAGES,
1232                            PortletKeys.MY_WORKFLOW_INSTANCES, PortletKeys.MY_WORKFLOW_TASKS
1233                    };
1234            }
1235    
1236            protected void initPersonalControlPanelPortletsPermissions(Role role)
1237                    throws PortalException, SystemException {
1238    
1239                    for (String portletId : getDefaultControlPanelPortlets()) {
1240                            ResourceAction resourceAction =
1241                                    resourceActionLocalService.fetchResourceAction(
1242                                            portletId, ActionKeys.ACCESS_IN_CONTROL_PANEL);
1243    
1244                            if (resourceAction == null) {
1245                                    continue;
1246                            }
1247    
1248                            setRolePermissions(
1249                                    role, portletId,
1250                                    new String[] {
1251                                            ActionKeys.ACCESS_IN_CONTROL_PANEL
1252                                    });
1253                    }
1254            }
1255    
1256            protected void setRolePermissions(
1257                            Role role, String name, String[] actionIds)
1258                    throws PortalException, SystemException {
1259    
1260                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
1261                            if (resourceBlockLocalService.isSupported(name)) {
1262                                    resourceBlockLocalService.setCompanyScopePermissions(
1263                                            role.getCompanyId(), name, role.getRoleId(),
1264                                            Arrays.asList(actionIds));
1265                            }
1266                            else {
1267                                    resourcePermissionLocalService.setResourcePermissions(
1268                                            role.getCompanyId(), name, ResourceConstants.SCOPE_COMPANY,
1269                                            String.valueOf(role.getCompanyId()), role.getRoleId(),
1270                                            actionIds);
1271                            }
1272                    }
1273                    else {
1274                            permissionLocalService.setRolePermissions(
1275                                    role.getRoleId(), role.getCompanyId(), name,
1276                                    ResourceConstants.SCOPE_COMPANY,
1277                                    String.valueOf(role.getCompanyId()), actionIds);
1278                    }
1279            }
1280    
1281            protected void validate(
1282                            long roleId, long companyId, long classNameId, String name)
1283                    throws PortalException, SystemException {
1284    
1285                    if (classNameId == PortalUtil.getClassNameId(Role.class)) {
1286                            if (Validator.isNull(name) ||
1287                                    (name.indexOf(CharPool.COMMA) != -1) ||
1288                                    (name.indexOf(CharPool.STAR) != -1)) {
1289    
1290                                    throw new RoleNameException();
1291                            }
1292    
1293                            if (Validator.isNumber(name) &&
1294                                    !PropsValues.ROLES_NAME_ALLOW_NUMERIC) {
1295    
1296                                    throw new RoleNameException();
1297                            }
1298                    }
1299    
1300                    try {
1301                            Role role = roleFinder.findByC_N(companyId, name);
1302    
1303                            if (role.getRoleId() != roleId) {
1304                                    throw new DuplicateRoleException();
1305                            }
1306                    }
1307                    catch (NoSuchRoleException nsre) {
1308                    }
1309            }
1310    
1311            private Map<String, Role> _systemRolesMap = new HashMap<String, Role>();
1312    
1313    }