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