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