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