001    /**
002     * Copyright (c) 2000-2010 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.annotation.Propagation;
022    import com.liferay.portal.kernel.annotation.Transactional;
023    import com.liferay.portal.kernel.cache.Lifecycle;
024    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
025    import com.liferay.portal.kernel.cache.ThreadLocalCache;
026    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.exception.SystemException;
029    import com.liferay.portal.kernel.search.Indexer;
030    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
031    import com.liferay.portal.kernel.util.CharPool;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.OrderByComparator;
034    import com.liferay.portal.kernel.util.StringUtil;
035    import com.liferay.portal.kernel.util.Validator;
036    import com.liferay.portal.model.Group;
037    import com.liferay.portal.model.Layout;
038    import com.liferay.portal.model.ResourceConstants;
039    import com.liferay.portal.model.Role;
040    import com.liferay.portal.model.RoleConstants;
041    import com.liferay.portal.model.Team;
042    import com.liferay.portal.model.User;
043    import com.liferay.portal.security.permission.PermissionCacheUtil;
044    import com.liferay.portal.service.base.RoleLocalServiceBaseImpl;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portal.util.PropsUtil;
047    import com.liferay.portlet.enterpriseadmin.util.EnterpriseAdminUtil;
048    
049    import java.util.ArrayList;
050    import java.util.Collections;
051    import java.util.HashMap;
052    import java.util.LinkedHashMap;
053    import java.util.List;
054    import java.util.Locale;
055    import java.util.Map;
056    
057    /**
058     * @author Brian Wing Shun Chan
059     */
060    public class RoleLocalServiceImpl extends RoleLocalServiceBaseImpl {
061    
062            public Role addRole(
063                            long userId, long companyId, String name,
064                            Map<Locale, String> titleMap, String description, int type)
065                    throws PortalException, SystemException {
066    
067                    return addRole(
068                            userId, companyId, name, titleMap, description, type, null, 0);
069            }
070    
071            public Role addRole(
072                            long userId, long companyId, String name,
073                            Map<Locale, String> titleMap, String description,
074                            int type, String className, long classPK)
075                    throws PortalException, SystemException {
076    
077                    // Role
078    
079                    className = GetterUtil.getString(className);
080                    long classNameId = PortalUtil.getClassNameId(className);
081    
082                    long roleId = counterLocalService.increment();
083    
084                    if ((classNameId <= 0) || className.equals(Role.class.getName())) {
085                            classNameId = PortalUtil.getClassNameId(Role.class);
086                            classPK = roleId;
087                    }
088    
089                    validate(0, companyId, classNameId, name);
090    
091                    Role role = rolePersistence.create(roleId);
092    
093                    role.setCompanyId(companyId);
094                    role.setClassNameId(classNameId);
095                    role.setClassPK(classPK);
096                    role.setName(name);
097                    role.setTitleMap(titleMap);
098                    role.setDescription(description);
099                    role.setType(type);
100    
101                    rolePersistence.update(role, false);
102    
103                    // Resources
104    
105                    if (userId > 0) {
106                            resourceLocalService.addResources(
107                                    companyId, 0, userId, Role.class.getName(), role.getRoleId(),
108                                    false, false, false);
109    
110                            Indexer indexer = IndexerRegistryUtil.getIndexer(User.class);
111    
112                            indexer.reindex(userId);
113                    }
114    
115                    return role;
116            }
117    
118            public void addUserRoles(long userId, long[] roleIds)
119                    throws PortalException, SystemException {
120    
121                    userPersistence.addRoles(userId, roleIds);
122    
123                    Indexer indexer = IndexerRegistryUtil.getIndexer(User.class);
124    
125                    indexer.reindex(userId);
126    
127                    PermissionCacheUtil.clearCache();
128            }
129    
130            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
131            public void checkSystemRoles(long companyId)
132                    throws PortalException, SystemException {
133    
134                    for (Role role : roleFinder.findBySystem(companyId)) {
135                            _systemRolesMap.put(companyId + role.getName(), role);
136                    }
137    
138                    // Regular roles
139    
140                    String[] systemRoles = PortalUtil.getSystemRoles();
141    
142                    for (String name : systemRoles) {
143                            String description = PropsUtil.get(
144                                    "system.role." +
145                                    StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
146                                    ".description");
147                            int type = RoleConstants.TYPE_REGULAR;
148    
149                            checkSystemRole(companyId, name, description, type);
150                    }
151    
152                    // Community roles
153    
154                    String[] systemCommunityRoles = PortalUtil.getSystemCommunityRoles();
155    
156                    for (String name : systemCommunityRoles) {
157                            String description = PropsUtil.get(
158                                    "system.community.role." +
159                                    StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
160                                    ".description");
161                            int type = RoleConstants.TYPE_COMMUNITY;
162    
163                            checkSystemRole(companyId, name, description, type);
164                    }
165    
166                    // Organization roles
167    
168                    String[] systemOrganizationRoles =
169                            PortalUtil.getSystemOrganizationRoles();
170    
171                    for (String name : systemOrganizationRoles) {
172                            String description = PropsUtil.get(
173                                    "system.organization.role." +
174                                            StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) +
175                                            ".description");
176                            int type = RoleConstants.TYPE_ORGANIZATION;
177    
178                            checkSystemRole(companyId, name, description, type);
179                    }
180            }
181    
182            public void deleteRole(long roleId)
183                    throws PortalException, SystemException {
184    
185                    Role role = rolePersistence.findByPrimaryKey(roleId);
186    
187                    if (PortalUtil.isSystemRole(role.getName())) {
188                            throw new RequiredRoleException();
189                    }
190    
191                    // Resources
192    
193                    String className = role.getClassName();
194                    long classNameId = role.getClassNameId();
195    
196                    if ((classNameId <= 0) || className.equals(Role.class.getName())) {
197                            resourceLocalService.deleteResource(
198                                    role.getCompanyId(), Role.class.getName(),
199                                    ResourceConstants.SCOPE_INDIVIDUAL, role.getRoleId());
200                    }
201    
202                    if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
203                            (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
204    
205                            userGroupRoleLocalService.deleteUserGroupRolesByRoleId(
206                                    role.getRoleId());
207    
208                            userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByRoleId(
209                                    role.getRoleId());
210                    }
211    
212                    // Role
213    
214                    rolePersistence.remove(role);
215    
216                    // Permission cache
217    
218                    PermissionCacheUtil.clearCache();
219            }
220    
221            public Role getDefaultGroupRole(long groupId)
222                    throws PortalException, SystemException {
223    
224                    Group group = groupPersistence.findByPrimaryKey(groupId);
225    
226                    if (group.isLayout()) {
227                            Layout layout = layoutLocalService.getLayout(group.getClassPK());
228    
229                            group = layout.getGroup();
230                    }
231    
232                    if (group.isStagingGroup()) {
233                            group = group.getLiveGroup();
234                    }
235    
236                    Role role = null;
237    
238                    if (group.isCommunity() || group.isLayoutPrototype() ||
239                            group.isLayoutSetPrototype()) {
240    
241                            role = getRole(
242                                    group.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
243                    }
244                    else if (group.isCompany()) {
245                            role = getRole(group.getCompanyId(), RoleConstants.ADMINISTRATOR);
246                    }
247                    else if (group.isOrganization()) {
248                            role = getRole(
249                                    group.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
250                    }
251                    else if (group.isUser() || group.isUserGroup()) {
252                            role = getRole(group.getCompanyId(), RoleConstants.POWER_USER);
253                    }
254    
255                    return role;
256            }
257    
258            public List<Role> getGroupRoles(long groupId) throws SystemException {
259                    return groupPersistence.getRoles(groupId);
260            }
261    
262            public Map<String, List<String>> getResourceRoles(
263                            long companyId, String name, int scope, String primKey)
264                    throws SystemException {
265    
266                    return roleFinder.findByC_N_S_P(companyId, name, scope, primKey);
267            }
268    
269            public Role getRole(long roleId) throws PortalException, SystemException {
270                    return rolePersistence.findByPrimaryKey(roleId);
271            }
272    
273            public Role getRole(long companyId, String name)
274                    throws PortalException, SystemException {
275    
276                    Role role = _systemRolesMap.get(companyId + name);
277    
278                    if (role != null) {
279                            return role;
280                    }
281    
282                    return rolePersistence.findByC_N(companyId, name);
283            }
284    
285            public List<Role> getRoles(long companyId) throws SystemException {
286                    return rolePersistence.findByCompanyId(companyId);
287            }
288    
289            public List<Role> getRoles(long[] roleIds)
290                    throws PortalException, SystemException {
291    
292                    List<Role> roles = new ArrayList<Role>(roleIds.length);
293    
294                    for (long roleId : roleIds) {
295                            Role role = getRole(roleId);
296    
297                            roles.add(role);
298                    }
299    
300                    return roles;
301            }
302    
303            public List<Role> getRoles(int type, String subtype)
304                    throws SystemException {
305    
306                    return rolePersistence.findByT_S(type, subtype);
307            }
308    
309            public List<Role> getSubtypeRoles(String subtype) throws SystemException {
310                    return rolePersistence.findBySubtype(subtype);
311            }
312    
313            public int getSubtypeRolesCount(String subtype) throws SystemException {
314                    return rolePersistence.countBySubtype(subtype);
315            }
316    
317            public Role getTeamRole(long companyId, long teamId)
318                    throws PortalException, SystemException {
319    
320                    long classNameId = PortalUtil.getClassNameId(Team.class);
321    
322                    return rolePersistence.findByC_C_C(companyId, classNameId, teamId);
323            }
324    
325            public List<Role> getUserGroupGroupRoles(long userId, long groupId)
326                    throws SystemException {
327    
328                    return roleFinder.findByUserGroupGroupRole(userId, groupId);
329            }
330    
331            public List<Role> getUserGroupRoles(long userId, long groupId)
332                    throws SystemException {
333    
334                    return roleFinder.findByUserGroupRole(userId, groupId);
335            }
336    
337            public List<Role> getUserRelatedRoles(long userId, long groupId)
338                    throws SystemException {
339    
340                    return roleFinder.findByU_G(userId, groupId);
341            }
342    
343            public List<Role> getUserRelatedRoles(long userId, long[] groupIds)
344                    throws SystemException {
345    
346                    return roleFinder.findByU_G(userId, groupIds);
347            }
348    
349            public List<Role> getUserRelatedRoles(long userId, List<Group> groups)
350                    throws SystemException {
351    
352                    if ((groups == null) || groups.isEmpty()) {
353                            return Collections.EMPTY_LIST;
354                    }
355    
356                    return roleFinder.findByU_G(userId, groups);
357            }
358    
359            public List<Role> getUserRoles(long userId) throws SystemException {
360                    return userPersistence.getRoles(userId);
361            }
362    
363            public boolean hasUserRole(long userId, long roleId)
364                    throws SystemException {
365    
366                    return userPersistence.containsRole(userId, roleId);
367            }
368    
369            /**
370             * Returns <code>true</code> if the user has the regular role.
371             *
372             * @return <code>true</code> if the user has the regular role
373             */
374            @ThreadLocalCachable
375            public boolean hasUserRole(
376                            long userId, long companyId, String name, boolean inherited)
377                    throws PortalException, SystemException {
378    
379                    Role role = rolePersistence.findByC_N(companyId, name);
380    
381                    if (role.getType() != RoleConstants.TYPE_REGULAR) {
382                            throw new IllegalArgumentException(name + " is not a regular role");
383                    }
384    
385                    if (inherited) {
386                            ThreadLocalCache<Integer> threadLocalCache =
387                                    ThreadLocalCacheManager.getThreadLocalCache(
388                                            Lifecycle.REQUEST, _COUNT_BY_R_U_CACHE_NAME);
389    
390                            String key = String.valueOf(role.getRoleId()).concat(
391                                    String.valueOf(userId));
392    
393                            Integer value = threadLocalCache.get(key);
394    
395                            if (value == null) {
396                                    value = roleFinder.countByR_U(role.getRoleId(), userId);
397    
398                                    threadLocalCache.put(key, value);
399                            }
400    
401                            if (value > 0) {
402                                    return true;
403                            }
404                            else {
405                                    return false;
406                            }
407                    }
408                    else {
409                            return userPersistence.containsRole(userId, role.getRoleId());
410                    }
411            }
412    
413            /**
414             * Returns <code>true</code> if the user has any one of the specified
415             * regular roles.
416             *
417             * @return <code>true</code> if the user has the regular role
418             */
419            public boolean hasUserRoles(
420                            long userId, long companyId, String[] names, boolean inherited)
421                    throws PortalException, SystemException {
422    
423                    for (String name : names) {
424                            if (hasUserRole(userId, companyId, name, inherited)) {
425                                    return true;
426                            }
427                    }
428    
429                    return false;
430            }
431    
432            public List<Role> search(
433                            long companyId, String name, String description, Integer[] types,
434                            int start, int end, OrderByComparator obc)
435                    throws SystemException {
436    
437                    return search(
438                            companyId, name, description, types,
439                            new LinkedHashMap<String, Object>(), start, end, obc);
440            }
441    
442            public List<Role> search(
443                            long companyId, String name, String description, Integer[] types,
444                            LinkedHashMap<String, Object> params, int start, int end,
445                            OrderByComparator obc)
446                    throws SystemException {
447    
448                    return roleFinder.findByC_N_D_T(
449                            companyId, name, description, types, params, start, end, obc);
450            }
451    
452            public int searchCount(
453                            long companyId, String name, String description, Integer[] types)
454                    throws SystemException {
455    
456                    return searchCount(
457                            companyId, name, description, types,
458                            new LinkedHashMap<String, Object>());
459            }
460    
461            public int searchCount(
462                            long companyId, String name, String description, Integer[] types,
463                            LinkedHashMap<String, Object> params)
464                    throws SystemException {
465    
466                    return roleFinder.countByC_N_D_T(
467                            companyId, name, description, types, params);
468            }
469    
470            public void setUserRoles(long userId, long[] roleIds)
471                    throws PortalException, SystemException {
472    
473                    roleIds = EnterpriseAdminUtil.addRequiredRoles(userId, roleIds);
474    
475                    userPersistence.setRoles(userId, roleIds);
476    
477                    Indexer indexer = IndexerRegistryUtil.getIndexer(User.class);
478    
479                    indexer.reindex(userId);
480    
481                    PermissionCacheUtil.clearCache();
482            }
483    
484            public void unsetUserRoles(long userId, long[] roleIds)
485                    throws PortalException, SystemException {
486    
487                    roleIds = EnterpriseAdminUtil.removeRequiredRoles(userId, roleIds);
488    
489                    userPersistence.removeRoles(userId, roleIds);
490    
491                    Indexer indexer = IndexerRegistryUtil.getIndexer(User.class);
492    
493                    indexer.reindex(userId);
494    
495                    PermissionCacheUtil.clearCache();
496            }
497    
498            public Role updateRole(
499                            long roleId, String name, Map<Locale, String> titleMap,
500                            String description, String subtype)
501                    throws PortalException, SystemException {
502    
503                    Role role = rolePersistence.findByPrimaryKey(roleId);
504    
505                    validate(roleId, role.getCompanyId(), role.getClassNameId(), name);
506    
507                    if (PortalUtil.isSystemRole(role.getName())) {
508                            name = role.getName();
509                            subtype = null;
510                    }
511    
512                    role.setName(name);
513                    role.setTitleMap(titleMap);
514                    role.setDescription(description);
515                    role.setSubtype(subtype);
516    
517                    rolePersistence.update(role, false);
518    
519                    return role;
520            }
521    
522            protected void checkSystemRole(
523                            long companyId, String name, String description, int type)
524                    throws PortalException, SystemException {
525    
526                    Role role = _systemRolesMap.get(companyId + name);
527    
528                    try {
529                            if (role == null) {
530                                    role = rolePersistence.findByC_N(companyId, name);
531                            }
532    
533                            if (!role.getDescription().equals(description)) {
534                                    role.setDescription(description);
535    
536                                    roleLocalService.updateRole(role, false);
537                            }
538                    }
539                    catch (NoSuchRoleException nsre) {
540                            role = roleLocalService.addRole(
541                                    0, companyId, name, null, description, type);
542                    }
543    
544                    _systemRolesMap.put(companyId + name, role);
545            }
546    
547            protected void validate(
548                            long roleId, long companyId, long classNameId, String name)
549                    throws PortalException, SystemException {
550    
551                    if ((classNameId == PortalUtil.getClassNameId(Role.class)) &&
552                            ((Validator.isNull(name)) || (Validator.isNumber(name)) ||
553                             (name.indexOf(CharPool.COMMA) != -1) ||
554                             (name.indexOf(CharPool.STAR) != -1))) {
555    
556                            throw new RoleNameException();
557                    }
558    
559                    try {
560                            Role role = roleFinder.findByC_N(companyId, name);
561    
562                            if (role.getRoleId() != roleId) {
563                                    throw new DuplicateRoleException();
564                            }
565                    }
566                    catch (NoSuchRoleException nsge) {
567                    }
568            }
569    
570            private static final String _COUNT_BY_R_U_CACHE_NAME = "COUNT_BY_R_U";
571    
572            private Map<String, Role> _systemRolesMap = new HashMap<String, Role>();
573    
574    }