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