Coverage Report - org.kuali.rice.kim.service.impl.RoleManagementServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RoleManagementServiceImpl
0%
0/404
0%
0/148
2.25
 
 1  
 /*
 2  
  * Copyright 2007-2008 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kim.service.impl;
 17  
 
 18  
 import java.sql.Date;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Collection;
 21  
 import java.util.Collections;
 22  
 import java.util.HashMap;
 23  
 import java.util.HashSet;
 24  
 import java.util.Iterator;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 import java.util.Set;
 28  
 
 29  
 import javax.jws.WebParam;
 30  
 
 31  
 import org.apache.log4j.Logger;
 32  
 import org.kuali.rice.core.exception.RiceRemoteServiceConnectionException;
 33  
 import org.kuali.rice.core.resourceloader.GlobalResourceLoader;
 34  
 import org.kuali.rice.core.util.MaxAgeSoftReference;
 35  
 import org.kuali.rice.core.util.MaxSizeMap;
 36  
 import org.kuali.rice.core.util.RiceDebugUtils;
 37  
 import org.kuali.rice.kim.bo.Role;
 38  
 import org.kuali.rice.kim.bo.entity.KimPrincipal;
 39  
 import org.kuali.rice.kim.bo.role.dto.DelegateMemberCompleteInfo;
 40  
 import org.kuali.rice.kim.bo.role.dto.DelegateTypeInfo;
 41  
 import org.kuali.rice.kim.bo.role.dto.KimRoleInfo;
 42  
 import org.kuali.rice.kim.bo.role.dto.RoleMemberCompleteInfo;
 43  
 import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo;
 44  
 import org.kuali.rice.kim.bo.role.dto.RoleResponsibilityActionInfo;
 45  
 import org.kuali.rice.kim.bo.role.dto.RoleResponsibilityInfo;
 46  
 import org.kuali.rice.kim.bo.types.dto.AttributeSet;
 47  
 import org.kuali.rice.kim.bo.types.dto.KimTypeInfo;
 48  
 import org.kuali.rice.kim.service.KIMServiceLocator;
 49  
 import org.kuali.rice.kim.service.KimTypeInfoService;
 50  
 import org.kuali.rice.kim.service.RoleManagementService;
 51  
 import org.kuali.rice.kim.service.RoleService;
 52  
 import org.kuali.rice.kim.service.RoleUpdateService;
 53  
 import org.kuali.rice.kim.service.support.KimRoleTypeService;
 54  
 import org.kuali.rice.kim.service.support.KimTypeService;
 55  
 import org.springframework.beans.factory.InitializingBean;
 56  
 
 57  
 /**
 58  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 59  
  */
 60  0
 public class RoleManagementServiceImpl implements RoleManagementService, InitializingBean {
 61  0
         private static final Logger LOG = Logger.getLogger( RoleManagementServiceImpl.class );
 62  
         
 63  
         private RoleService roleService;
 64  
         private KimTypeInfoService typeInfoService;
 65  
         private RoleUpdateService roleUpdateService;
 66  
         
 67  
         // Max age defined in seconds
 68  0
         protected int roleCacheMaxSize = 200;
 69  0
         protected int roleCacheMaxAgeSeconds = 30;
 70  
         
 71  
         protected Map<String,MaxAgeSoftReference<KimRoleInfo>> roleByIdCache;
 72  
         protected Map<String,MaxAgeSoftReference<KimRoleInfo>> roleByNameCache;
 73  
         protected Map<String,MaxAgeSoftReference<List<RoleMembershipInfo>>> roleMembersWithDelegationCache;
 74  
         protected Map<String,MaxAgeSoftReference<List<AttributeSet>>> roleQualifiersForPrincipalCache;
 75  
         protected Map<String,MaxAgeSoftReference<Boolean>> principalHasRoleCache;
 76  
         protected Map<String,MaxAgeSoftReference<Collection<String>>> memberPrincipalIdsCache;
 77  
         
 78  
         protected Map<String, Boolean> shouldCacheRoleCache;
 79  
         
 80  
         public void afterPropertiesSet() throws Exception {
 81  0
                 roleByIdCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<KimRoleInfo>>( roleCacheMaxSize ) );
 82  0
                 roleByNameCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<KimRoleInfo>>( roleCacheMaxSize ) );
 83  0
                 roleMembersWithDelegationCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<List<RoleMembershipInfo>>>( roleCacheMaxSize ) );
 84  0
                 roleQualifiersForPrincipalCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<List<AttributeSet>>>( roleCacheMaxSize ) );
 85  0
                 principalHasRoleCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<Boolean>>( roleCacheMaxSize ) );
 86  0
                 memberPrincipalIdsCache = Collections.synchronizedMap( new MaxSizeMap<String,MaxAgeSoftReference<Collection<String>>>( roleCacheMaxSize ) );
 87  0
                 shouldCacheRoleCache = Collections.synchronizedMap(new HashMap<String, Boolean>());
 88  0
         }
 89  
         
 90  
         public void flushRoleCaches() {
 91  0
                 flushInternalRoleCache();
 92  0
                 flushInternalRoleMemberCache();
 93  0
                 flushInternalDelegationCache();
 94  0
                 flushInternalDelegationMemberCache();
 95  0
                 roleByIdCache.clear();
 96  0
                 roleByNameCache.clear();
 97  0
                 roleMembersWithDelegationCache.clear();
 98  0
                 roleQualifiersForPrincipalCache.clear();
 99  0
                 principalHasRoleCache.clear();
 100  0
                 memberPrincipalIdsCache.clear();
 101  0
                 shouldCacheRoleCache.clear();
 102  0
         }
 103  
         
 104  
         public void flushRoleMemberCaches() {
 105  0
                 flushInternalRoleMemberCache();
 106  0
                 roleMembersWithDelegationCache.clear();
 107  0
                 memberPrincipalIdsCache.clear();
 108  0
         }
 109  
         
 110  
         public void flushDelegationCaches() {
 111  0
                 flushInternalDelegationCache();
 112  0
                 flushInternalDelegationMemberCache();
 113  0
                 roleMembersWithDelegationCache.clear();
 114  0
         }
 115  
         
 116  
         public void flushDelegationMemberCaches() {
 117  0
                 flushInternalDelegationMemberCache();
 118  0
                 roleMembersWithDelegationCache.clear();
 119  0
         }
 120  
         
 121  
         // Caching helper methods
 122  
 
 123  
         protected KimRoleInfo getRoleByIdCache( String roleId ) {
 124  0
                 MaxAgeSoftReference<KimRoleInfo> roleRef = roleByIdCache.get( roleId );
 125  0
                 if ( roleRef != null ) {
 126  0
                         return roleRef.get();
 127  
                 }
 128  0
                 return null;
 129  
         }
 130  
 
 131  
         protected KimRoleInfo getRoleByNameCache( String key ) {
 132  0
                 MaxAgeSoftReference<KimRoleInfo> roleRef = roleByNameCache.get( key );
 133  0
                 if ( roleRef != null ) {
 134  0
                         return roleRef.get();
 135  
                 }
 136  0
                 return null;
 137  
         }
 138  
         
 139  
         protected List<RoleMembershipInfo> getRoleMembersWithDelegationCache( String key ) {
 140  0
                 MaxAgeSoftReference<List<RoleMembershipInfo>> roleMembersRef = roleMembersWithDelegationCache.get( key );
 141  0
                 if ( roleMembersRef != null ) {
 142  0
                         return roleMembersRef.get();
 143  
                 }
 144  0
                 return null;
 145  
         }
 146  
         
 147  
         protected List<AttributeSet> getRoleQualifiersForPrincipalCache( String key ) {
 148  0
                 MaxAgeSoftReference<List<AttributeSet>> qualifiersRef = roleQualifiersForPrincipalCache.get( key );
 149  0
                 if ( qualifiersRef != null ) {
 150  0
                         return qualifiersRef.get();
 151  
                 }
 152  0
                 return null;
 153  
         }
 154  
         
 155  
         protected Boolean getPrincipalHasRoleCacheCache( String key ) {
 156  0
                 MaxAgeSoftReference<Boolean> hasRoleRef = principalHasRoleCache.get( key );
 157  0
                 if ( hasRoleRef != null ) {
 158  0
                         return hasRoleRef.get();
 159  
                 }
 160  0
                 return null;
 161  
         }
 162  
         
 163  
         protected void addRoleToCaches( KimRoleInfo role ) {
 164  0
                 if ( role != null ) {
 165  0
                         roleByNameCache.put( role.getNamespaceCode() + "-" + role.getRoleName(), new MaxAgeSoftReference<KimRoleInfo>( roleCacheMaxAgeSeconds, role ) );
 166  0
                         roleByIdCache.put( role.getRoleId(), new MaxAgeSoftReference<KimRoleInfo>( roleCacheMaxAgeSeconds, role ) );
 167  
                 }
 168  0
         }
 169  
 
 170  
         protected void addRoleMembersWithDelegationToCache( String key, List<RoleMembershipInfo> members ) {
 171  0
                 if ( members != null ) {
 172  0
                         roleMembersWithDelegationCache.put( key, new MaxAgeSoftReference<List<RoleMembershipInfo>>( roleCacheMaxAgeSeconds, members ) );
 173  
                 }
 174  0
         }
 175  
 
 176  
         protected void addRoleQualifiersForPrincipalToCache( String key, List<AttributeSet> qualifiers ) {
 177  0
                 if ( qualifiers != null ) {
 178  0
                         roleQualifiersForPrincipalCache.put( key, new MaxAgeSoftReference<List<AttributeSet>>( roleCacheMaxAgeSeconds, qualifiers ) );
 179  
                 }
 180  0
         }
 181  
         
 182  
         protected void addPrincipalHasRoleToCache( String key, boolean hasRole ) {
 183  0
                 principalHasRoleCache.put( key, new MaxAgeSoftReference<Boolean>( roleCacheMaxAgeSeconds, hasRole ) );
 184  0
         }
 185  
                 
 186  
         // Cached methods
 187  
 
 188  
         protected Collection<String> getRoleMemberPrincipalIdsCache(String key) {
 189  0
                 MaxAgeSoftReference<Collection<String>> memberPrincipalIdsRef = memberPrincipalIdsCache.get(key);
 190  0
                 if ( memberPrincipalIdsRef != null ) {
 191  0
                         return memberPrincipalIdsRef.get();
 192  
                 }
 193  0
                 return null;
 194  
         }
 195  
         
 196  
         protected void addRoleMemberPrincipalIdsToCache(String key, Collection<String> principalIds) {
 197  0
                 memberPrincipalIdsCache.put(key, new MaxAgeSoftReference<Collection<String>>(roleCacheMaxAgeSeconds, principalIds ));
 198  0
         }
 199  
         
 200  
         /**
 201  
          * @see org.kuali.rice.kim.service.RoleService#getRoleMemberPrincipalIds(java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 202  
          */
 203  
         public Collection<String> getRoleMemberPrincipalIds(String namespaceCode, String roleName, AttributeSet qualification) {
 204  0
                 StringBuffer cacheKey = new StringBuffer();
 205  0
                 cacheKey.append( namespaceCode ).append( '/' ).append( roleName );
 206  0
                 addAttributesToKey(cacheKey, qualification);
 207  0
                 String key = cacheKey.toString();
 208  0
                 Collection<String> principalIds = getRoleMemberPrincipalIdsCache(key);
 209  0
                 if (principalIds != null) {
 210  0
                         return principalIds;
 211  
                 }
 212  0
                 principalIds = getRoleService().getRoleMemberPrincipalIds(namespaceCode, roleName, qualification);
 213  0
                 addRoleMemberPrincipalIdsToCache(key, principalIds);
 214  0
                 return principalIds;
 215  
         }
 216  
 
 217  
         /**
 218  
          * @see org.kuali.rice.kim.service.RoleService#getRole(java.lang.String)
 219  
          */
 220  
         public KimRoleInfo getRole(String roleId) {
 221  0
                 KimRoleInfo role = getRoleByIdCache(roleId);
 222  0
                 if (role != null) {
 223  0
                         return role;
 224  
                 }
 225  0
                 role = getRoleService().getRole(roleId);
 226  0
                 addRoleToCaches(role);
 227  0
             return role;
 228  
         }
 229  
 
 230  
         /**
 231  
          * @see org.kuali.rice.kim.service.RoleService#getRoleByName(java.lang.String, java.lang.String)
 232  
          */
 233  
         public KimRoleInfo getRoleByName(String namespaceCode, String roleName) {
 234  0
                 KimRoleInfo role = getRoleByNameCache(namespaceCode + "-" + roleName);
 235  0
                 if (role != null) {
 236  0
                         return role;
 237  
                 }
 238  0
                 role = getRoleService().getRoleByName(namespaceCode, roleName);
 239  0
                 addRoleToCaches(role);
 240  0
             return role;
 241  
         }
 242  
 
 243  
         /**
 244  
          * @see org.kuali.rice.kim.service.RoleService#getRoleIdByName(java.lang.String, java.lang.String)
 245  
          */
 246  
         public String getRoleIdByName(String namespaceCode, String roleName) {
 247  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 248  0
                 if ( role == null ) {
 249  0
                         return null;
 250  
                 }
 251  0
                 return role.getRoleId();
 252  
         }
 253  
                 
 254  
         /**
 255  
          * @see org.kuali.rice.kim.service.RoleService#getRoles(java.util.List)
 256  
          */
 257  
         public List<KimRoleInfo> getRoles(List<String> roleIds) {
 258  0
                 return getRoleService().getRoles(roleIds);
 259  
         }
 260  
 
 261  
         protected void addIdsToKey( StringBuffer key, List<String> idList ) {
 262  0
                 if ( idList == null || idList.isEmpty() ) {
 263  0
                         key.append( "[null]" );
 264  
                 } else {
 265  0
                         for ( String id : idList ) {
 266  0
                                 key.append( '|' ).append( id ).append( '|' );
 267  
                         }
 268  
                 }
 269  0
         }
 270  
         
 271  
         protected void addAttributesToKey( StringBuffer key, AttributeSet attributes ) {
 272  0
                 if ( attributes == null || attributes.isEmpty() ) {
 273  0
                         key.append( "[null]" );
 274  
                 } else {
 275  0
                         for (Map.Entry<String, String> entry : attributes.entrySet()) {
 276  0
                                 key.append( entry.getKey() ).append( '=' ).append( entry.getValue() ).append( '|' );
 277  
                         }
 278  
                 }
 279  0
         }
 280  
 
 281  
         /**
 282  
          * @see org.kuali.rice.kim.service.RoleService#getRoleMembers(java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 283  
          */
 284  
         public List<RoleMembershipInfo> getRoleMembers(List<String> roleIds, AttributeSet qualification) {
 285  0
                 List<String>[] filteredRoles = filterRoleIdsByCachingAbility(roleIds);
 286  0
                 List<String> cacheRoles = filteredRoles[0];
 287  0
                 List<String> noCacheRoles = filteredRoles[1];
 288  
                 
 289  0
                 List<RoleMembershipInfo> members = null;
 290  0
                 String key = null;
 291  
                 
 292  0
                 if (!cacheRoles.isEmpty()) {
 293  0
                         StringBuffer cacheKey = new StringBuffer();
 294  0
                         addIdsToKey( cacheKey, cacheRoles );
 295  0
                         cacheKey.append(  '/' );
 296  0
                         addAttributesToKey( cacheKey, qualification );
 297  0
                         key = cacheKey.toString();
 298  0
                         members = getRoleMembersWithDelegationCache(key);
 299  
                 }
 300  0
                 if (members != null) {
 301  0
                         if (!noCacheRoles.isEmpty()) {
 302  0
                                 members.addAll(getRoleService().getRoleMembers(noCacheRoles, qualification));
 303  
                         }
 304  0
                         return members;
 305  
                 }
 306  
                 
 307  0
                 if (!cacheRoles.isEmpty()) {
 308  0
                         members = getRoleService().getRoleMembers(cacheRoles, qualification);
 309  0
                         addRoleMembersWithDelegationToCache(key, members);
 310  
                 } else {
 311  0
                         members = new ArrayList<RoleMembershipInfo>();
 312  
                 }
 313  0
                 if (!noCacheRoles.isEmpty()) {
 314  0
                         members.addAll(getRoleService().getRoleMembers(noCacheRoles, qualification));
 315  
                 }
 316  0
             return members;
 317  
     }
 318  
 
 319  
         /**
 320  
          * @see org.kuali.rice.kim.service.RoleService#getRoleQualifiersForPrincipal(java.lang.String, java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 321  
          */
 322  
         public List<AttributeSet> getRoleQualifiersForPrincipal(String principalId, List<String> roleIds, AttributeSet qualification) {                
 323  0
                 StringBuffer cacheKey = new StringBuffer( principalId );
 324  0
                 cacheKey.append( '/' );
 325  0
                 addIdsToKey( cacheKey, roleIds );
 326  0
                 cacheKey.append(  '/' );
 327  0
                 addAttributesToKey( cacheKey, qualification );
 328  0
                 String key = cacheKey.toString();
 329  0
                 List<AttributeSet> qualifiers = getRoleQualifiersForPrincipalCache(key);
 330  0
                 if (qualifiers != null) {
 331  0
                         return qualifiers;
 332  
                 }
 333  0
                 qualifiers = getRoleService().getRoleQualifiersForPrincipal(principalId, roleIds, qualification);
 334  0
                 addRoleQualifiersForPrincipalToCache(key, qualifiers);
 335  0
             return qualifiers;
 336  
         }
 337  
 
 338  
         /**
 339  
          * @see org.kuali.rice.kim.service.RoleService#getRoleQualifiersForPrincipal(java.lang.String, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 340  
          */
 341  
         public List<AttributeSet> getRoleQualifiersForPrincipal(String principalId, String namespaceCode, String roleName, AttributeSet qualification) {
 342  0
                 StringBuffer cacheKey = new StringBuffer( principalId );
 343  0
                 cacheKey.append( '/' );
 344  0
                 cacheKey.append( namespaceCode ).append( '-' ).append( roleName );
 345  0
                 cacheKey.append( '/' );
 346  0
                 addAttributesToKey( cacheKey, qualification );
 347  0
                 String key = cacheKey.toString();
 348  0
                 List<AttributeSet> qualifiers = getRoleQualifiersForPrincipalCache(key);
 349  0
                 if (qualifiers != null) {
 350  0
                         return qualifiers;
 351  
                 }
 352  0
                 qualifiers = getRoleService().getRoleQualifiersForPrincipal(principalId, namespaceCode, roleName, qualification);
 353  0
                 addRoleQualifiersForPrincipalToCache(key, qualifiers);
 354  0
             return qualifiers;
 355  
         }
 356  
 
 357  
         public boolean isRoleActive(String roleId) {
 358  0
                 KimRoleInfo role = getRole( roleId );
 359  0
                 return role != null && role.isActive();
 360  
         }
 361  
 
 362  
         public boolean principalHasRole(String principalId, List<String> roleIds, AttributeSet qualification) {
 363  0
                 if ( LOG.isDebugEnabled() ) {
 364  0
                         logPrincipalHasRoleCheck(principalId, roleIds, qualification);
 365  
                 }
 366  0
                 List<String>[] filteredRoles = filterRoleIdsByCachingAbility(roleIds);
 367  0
                 List<String> cacheRoles = filteredRoles[0];
 368  0
                 List<String> noCacheRoles = filteredRoles[1];
 369  
                 
 370  0
                 Boolean hasRole = null;
 371  0
                 String key = null;
 372  0
                 if (!cacheRoles.isEmpty()) {
 373  0
                         StringBuffer cacheKey = new StringBuffer();
 374  0
                         cacheKey.append( principalId );
 375  0
                         cacheKey.append( '/' );
 376  0
                         addIdsToKey( cacheKey, cacheRoles );
 377  0
                         cacheKey.append( '/' );
 378  0
                         addAttributesToKey( cacheKey, qualification );
 379  0
                         key = cacheKey.toString();
 380  0
                         hasRole = getPrincipalHasRoleCacheCache(key);
 381  
                 }
 382  0
                 if (hasRole == null || !hasRole.booleanValue()) {
 383  0
                         if (!cacheRoles.isEmpty()) {
 384  0
                                 hasRole = getRoleService().principalHasRole(principalId, cacheRoles, qualification);
 385  0
                                 addPrincipalHasRoleToCache(key, hasRole);
 386  
                         }
 387  0
                         if ((hasRole == null || !hasRole.booleanValue()) && !noCacheRoles.isEmpty()) {
 388  0
                                 hasRole = getRoleService().principalHasRole(principalId, noCacheRoles, qualification);
 389  
                         }
 390  0
                     if ( LOG.isDebugEnabled() ) {
 391  0
                             LOG.debug( "Result: " + hasRole );
 392  
                     }
 393  
                 } else {
 394  0
                         if ( LOG.isDebugEnabled() ) {
 395  0
                                 LOG.debug( "Result Found in cache using key: " + key + "\nResult: " + hasRole );
 396  
                         }
 397  
                 }
 398  0
             return hasRole;
 399  
         }
 400  
         
 401  
         /**
 402  
          * Determines if the role with the given id will be cached
 403  
          * 
 404  
          * @param roleId the role id of the role to determine caching on
 405  
          * @return true if the role should be cached, false otherwise
 406  
          */
 407  
         protected boolean shouldCacheRole(String roleId) {
 408  0
                 Boolean shouldCacheRoleAnswer = shouldCacheRoleCache.get(roleId);
 409  0
                 if (shouldCacheRoleAnswer == null) {
 410  
                 
 411  0
                         final KimRoleTypeService roleType = getRoleTypeService(roleId);
 412  0
                         final KimRoleInfo roleInfo = this.getRole(roleId);
 413  0
                         if (roleType != null && roleInfo != null) {
 414  
                             try {
 415  0
                                 shouldCacheRoleAnswer = new Boolean(roleType.shouldCacheRoleMembershipResults(roleInfo.getNamespaceCode(), roleInfo.getRoleName()));
 416  0
                                 shouldCacheRoleCache.put(roleId, shouldCacheRoleAnswer);
 417  0
                             } catch (Exception e) {//was: RiceRemoteServiceConnectionException
 418  0
                                 LOG.warn("Unable to connect to remote service for roleType " + roleInfo.getNamespaceCode() + "-" + roleInfo.getRoleName());
 419  0
                     LOG.warn(e.getMessage());
 420  0
                                 return Boolean.FALSE;
 421  0
                             }
 422  
                         } else {
 423  0
                                 shouldCacheRoleAnswer = Boolean.TRUE; // no type?  that means we get to do the default - cache
 424  0
                                 shouldCacheRoleCache.put(roleId, shouldCacheRoleAnswer);
 425  
                         }
 426  
                 }
 427  0
                 return shouldCacheRoleAnswer.booleanValue();
 428  
         }
 429  
         
 430  
         /**
 431  
          * Splits the given List of role ids into two Lists, one with roles to cache, and one with roles
 432  
          * not to cache
 433  
          * 
 434  
          * @param roleIds the List of role ids to split
 435  
          * @return an array of two Lists of role ids - the first, roles which can be cached and the second, roles which should not be cached
 436  
          */
 437  
         @SuppressWarnings("unchecked")
 438  
         protected List<String>[] filterRoleIdsByCachingAbility(List<String> roleIds) {
 439  0
                 List<String> cacheRoles = new ArrayList<String>();
 440  0
                 List<String> noCacheRoles = new ArrayList<String>();
 441  0
                 Set<String> alreadyFilteredRoles = new HashSet<String>();
 442  
                 
 443  0
                 for (String roleId : roleIds) {
 444  0
                         if (!alreadyFilteredRoles.contains(roleId)) {
 445  0
                                 alreadyFilteredRoles.add(roleId);
 446  0
                                 if (shouldCacheRole(roleId)) {
 447  0
                                         cacheRoles.add(roleId);
 448  
                                 } else {
 449  0
                                         noCacheRoles.add(roleId);
 450  
                                 }
 451  
                         }
 452  
                 }
 453  0
                 return (List<String>[])new List[] { cacheRoles, noCacheRoles };
 454  
         }
 455  
         
 456  
         /**
 457  
      * Retrieves the role type service associated with the given role ID
 458  
      * 
 459  
      * @param roleId the role ID to get the role type service for
 460  
      * @return the Role Type Service
 461  
      */
 462  
     protected KimRoleTypeService getRoleTypeService( String roleId ) {
 463  0
             KimRoleTypeService service = null;
 464  
                     
 465  0
             final KimRoleInfo roleInfo = getRoleService().getRole(roleId);
 466  0
             if (roleInfo != null) {
 467  0
                     final KimTypeInfo roleType = getTypeInfoService().getKimType(roleInfo.getKimTypeId());
 468  0
                     if ( roleType != null ) {
 469  0
                         service = getRoleTypeService(roleType);
 470  
                     }
 471  
             }
 472  0
             return service;
 473  
     }
 474  
 
 475  
         /**
 476  
          * Retrieves a role type from the given type info
 477  
          * 
 478  
          * @param typeInfo
 479  
          * @return
 480  
          */
 481  
         protected KimRoleTypeService getRoleTypeService( KimTypeInfo typeInfo ) {
 482  0
                 String serviceName = typeInfo.getKimTypeServiceName();
 483  0
                 if ( serviceName != null ) {
 484  
                         try {
 485  0
                                 KimTypeService service = (KimTypeService)KIMServiceLocator.getService( serviceName );
 486  0
                                 if ( service != null && service instanceof KimRoleTypeService) {
 487  0
                                         return (KimRoleTypeService)service;
 488  
                                 } else {
 489  0
                                         return (KimRoleTypeService)KIMServiceLocator.getService( "kimNoMembersRoleTypeService" );
 490  
                                 }
 491  0
                         } catch ( Exception ex ) {
 492  0
                                 LOG.error( "Unable to find role type service with name: " + serviceName );
 493  0
                                 LOG.error( ex.getClass().getName() + " : " + ex.getMessage() );
 494  0
                                 return (KimRoleTypeService)KIMServiceLocator.getService( "kimNoMembersRoleTypeService" );
 495  
                         }
 496  
                 }
 497  0
                 return null;
 498  
         }
 499  
 
 500  
         /**
 501  
          * @see org.kuali.rice.kim.service.RoleService#getPrincipalIdSubListWithRole(java.util.List, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 502  
          */
 503  
         public List<String> getPrincipalIdSubListWithRole(
 504  
                         List<String> principalIds, String roleNamespaceCode,
 505  
                         String roleName, AttributeSet qualification) {
 506  0
                 return getRoleService().getPrincipalIdSubListWithRole(principalIds,
 507  
                                 roleNamespaceCode, roleName, qualification);
 508  
         }
 509  
 
 510  
         
 511  
 
 512  
         // Helper methods
 513  
         
 514  
         public void removeCacheEntries( String roleId, String principalId ) {
 515  0
                 if ( principalId != null ) {
 516  0
                         String keyPrefix = principalId + "-";
 517  0
                         synchronized ( principalHasRoleCache ) {
 518  0
                                 Iterator<String> cacheIterator = principalHasRoleCache.keySet().iterator();
 519  0
                                 while ( cacheIterator.hasNext() ) {
 520  0
                                         String cacheKey = cacheIterator.next();
 521  0
                                         if ( cacheKey.startsWith( keyPrefix ) ) {
 522  0
                                                 cacheIterator.remove();
 523  
                                         }
 524  0
                                 }
 525  0
                         }
 526  0
                         synchronized ( roleQualifiersForPrincipalCache ) {
 527  0
                                 Iterator<String> cacheIterator = roleQualifiersForPrincipalCache.keySet().iterator();
 528  0
                                 while ( cacheIterator.hasNext() ) {
 529  0
                                         String cacheKey = cacheIterator.next();
 530  0
                                         if ( cacheKey.startsWith( keyPrefix ) ) {
 531  0
                                                 cacheIterator.remove();
 532  
                                         }
 533  0
                                 }
 534  0
                         }
 535  
                 }
 536  0
                 if ( roleId != null ) {
 537  0
                         roleByIdCache.remove( roleId );
 538  0
                         roleByNameCache.clear();
 539  0
                         String keySubstring = "|" + roleId + "|";
 540  0
                         synchronized ( principalHasRoleCache ) {
 541  0
                                 Iterator<String> cacheIterator = principalHasRoleCache.keySet().iterator();
 542  0
                                 while ( cacheIterator.hasNext() ) {
 543  0
                                         String cacheKey = cacheIterator.next();
 544  0
                                         if( cacheKey.contains( keySubstring ) ) {
 545  0
                                                 cacheIterator.remove();
 546  
                                         }
 547  0
                                 }
 548  0
                         }
 549  0
                         synchronized ( roleQualifiersForPrincipalCache ) {
 550  0
                                 Iterator<String> cacheIterator = roleQualifiersForPrincipalCache.keySet().iterator();
 551  0
                                 while ( cacheIterator.hasNext() ) {
 552  0
                                         String cacheKey = cacheIterator.next();
 553  0
                                         if( cacheKey.contains( keySubstring ) ) {
 554  0
                                                 cacheIterator.remove();
 555  
                                         }
 556  0
                                 }
 557  0
                         }
 558  0
                         synchronized ( roleMembersWithDelegationCache ) {
 559  0
                                 Iterator<String> cacheIterator = roleMembersWithDelegationCache.keySet().iterator();
 560  0
                                 while ( cacheIterator.hasNext() ) {
 561  0
                                         String cacheKey = cacheIterator.next();
 562  0
                                         if( cacheKey.contains( keySubstring ) ) {
 563  0
                                                 cacheIterator.remove();
 564  
                                         }
 565  0
                                 }
 566  0
                         }
 567  0
                         synchronized ( memberPrincipalIdsCache ) {
 568  0
                                 Iterator<String> cacheIterator = memberPrincipalIdsCache.keySet().iterator();
 569  0
                                 while ( cacheIterator.hasNext() ) {
 570  0
                                         String cacheKey = cacheIterator.next();
 571  0
                                         if( cacheKey.contains( keySubstring ) ) {
 572  0
                                                 cacheIterator.remove();
 573  
                                         }
 574  0
                                 }
 575  0
                         }
 576  0
                         shouldCacheRoleCache.remove(roleId);
 577  
                 }
 578  0
         }
 579  
         
 580  
         /**
 581  
          * @see org.kuali.rice.kim.service.RoleService#getRoleQualifiersForPrincipalIncludingNested(java.lang.String, java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 582  
          */
 583  
         public List<AttributeSet> getRoleQualifiersForPrincipalIncludingNested(
 584  
                         String principalId, List<String> roleIds, AttributeSet qualification) {
 585  0
                 return getRoleService().getRoleQualifiersForPrincipalIncludingNested(principalId, roleIds, qualification);
 586  
         }
 587  
         
 588  
         /**
 589  
          * @see org.kuali.rice.kim.service.RoleService#getRoleQualifiersForPrincipalIncludingNested(java.lang.String, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 590  
          */
 591  
         public List<AttributeSet> getRoleQualifiersForPrincipalIncludingNested(
 592  
                         String principalId, String namespaceCode, String roleName,
 593  
                         AttributeSet qualification) {
 594  0
                 return getRoleService().getRoleQualifiersForPrincipalIncludingNested(principalId, namespaceCode, roleName, qualification);
 595  
         }
 596  
         
 597  
         public void assignGroupToRole(String groupId, String namespaceCode, String roleName,
 598  
                         AttributeSet qualifications) {
 599  0
                 getRoleUpdateService().assignGroupToRole( groupId, namespaceCode, roleName, qualifications );
 600  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 601  0
                 removeCacheEntries( role.getRoleId(), null );
 602  0
         }
 603  
 
 604  
         public void assignPrincipalToRole(String principalId, String namespaceCode, String roleName,
 605  
                         AttributeSet qualifications) {
 606  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 607  0
                 getRoleUpdateService().assignPrincipalToRole( principalId, namespaceCode, roleName, qualifications );
 608  0
                 removeCacheEntries( role.getRoleId(), principalId );
 609  0
         }
 610  
 
 611  
         public void removeGroupFromRole(String groupId, String namespaceCode, String roleName,
 612  
                         AttributeSet qualifications) {
 613  0
                 getRoleUpdateService().removeGroupFromRole( groupId, namespaceCode, roleName, qualifications );
 614  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 615  0
                 removeCacheEntries( role.getRoleId(), null );
 616  0
         }
 617  
 
 618  
         public void removePrincipalFromRole(String principalId, String namespaceCode, String roleName,
 619  
                         AttributeSet qualifications) {
 620  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 621  0
                 getRoleUpdateService().removePrincipalFromRole( principalId, namespaceCode, roleName, qualifications );
 622  0
                 removeCacheEntries( role.getRoleId(), principalId );
 623  0
         }
 624  
 
 625  
         /**
 626  
          * @see org.kuali.rice.kim.service.RoleService#getRolesSearchResults(java.util.Map)
 627  
          */
 628  
         public List<? extends Role> getRolesSearchResults(
 629  
                         Map<String, String> fieldValues) {
 630  0
                 return getRoleService().getRolesSearchResults(fieldValues);
 631  
         }
 632  
 
 633  
     protected void logPrincipalHasRoleCheck(String principalId, List<String> roleIds, AttributeSet roleQualifiers ) {
 634  0
                 StringBuilder sb = new StringBuilder();
 635  0
                 sb.append(  '\n' );
 636  0
                 sb.append( "Has Role     : " ).append( roleIds ).append( '\n' );
 637  0
                 if ( roleIds != null ) {
 638  0
                         for ( String roleId : roleIds ) {
 639  0
                                 KimRoleInfo role = getRole( roleId );
 640  0
                                 if ( role != null ) {
 641  0
                                         sb.append( "        Name : " ).append( role.getNamespaceCode() ).append( '/').append( role.getRoleName() );
 642  0
                                         sb.append( " (" ).append( roleId ).append( ')' );
 643  0
                                         sb.append( '\n' );
 644  
                                 }
 645  0
                         }
 646  
                 }
 647  0
                 sb.append( "   Principal : " ).append( principalId );
 648  0
                 if ( principalId != null ) {
 649  0
                         KimPrincipal principal = KIMServiceLocator.getIdentityManagementService().getPrincipal( principalId );
 650  0
                         if ( principal != null ) {
 651  0
                                 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' );
 652  
                         }
 653  
                 }
 654  0
                 sb.append( '\n' );
 655  0
                 sb.append( "     Details :\n" );
 656  0
                 if ( roleQualifiers != null ) {
 657  0
                         sb.append( roleQualifiers.formattedDump( 15 ) );
 658  
                 } else {
 659  0
                         sb.append( "               [null]\n" );
 660  
                 }
 661  0
                 if (LOG.isTraceEnabled()) { 
 662  0
                         LOG.trace( sb.append( RiceDebugUtils.getTruncatedStackTrace(true)).toString() ); 
 663  
                 } else {
 664  0
                         LOG.debug(sb.toString());
 665  
                 }
 666  0
     }
 667  
 
 668  
     /**
 669  
      * @see org.kuali.rice.kim.service.RoleService#principalInactivated(java.lang.String)
 670  
      */
 671  
     public void principalInactivated(String principalId) {
 672  0
             getRoleService().principalInactivated(principalId);    
 673  0
             removeCacheEntries(null, principalId);
 674  0
     }
 675  
     
 676  
     /**
 677  
      * @see org.kuali.rice.kim.service.RoleService#roleInactivated(java.lang.String)
 678  
      */
 679  
     public void roleInactivated(String roleId) {
 680  0
             getRoleService().roleInactivated(roleId);    
 681  0
             removeCacheEntries(roleId, null);
 682  0
     }
 683  
     
 684  
     /**
 685  
      * @see org.kuali.rice.kim.service.RoleService#roleInactivated(java.lang.String)
 686  
      */
 687  
     public void groupInactivated(String groupId) {
 688  0
             getRoleService().groupInactivated(groupId);    
 689  0
     }
 690  
 
 691  
     public List<RoleMembershipInfo> getFirstLevelRoleMembers(List<String> roleIds){
 692  0
             return getRoleService().getFirstLevelRoleMembers(roleIds);
 693  
     }
 694  
 
 695  
     public List<RoleMembershipInfo> findRoleMembers(Map<String, String> fieldValues){
 696  0
             return getRoleService().findRoleMembers(fieldValues);
 697  
     }
 698  
 
 699  
         public void assignRoleToRole(String roleId, String namespaceCode, String roleName,
 700  
                         AttributeSet qualifications) {
 701  0
                 getRoleUpdateService().assignRoleToRole( 
 702  
                                 roleId, namespaceCode, roleName, qualifications);
 703  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 704  0
                 removeCacheEntries( role.getRoleId(), null );
 705  0
         }
 706  
 
 707  
     /**
 708  
      * @see org.kuali.rice.kim.service.RoleUpdateService#assignRoleAsDelegationMemberToRole(java.lang.String, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 709  
      */
 710  
         public void saveDelegationMemberForRole(String delegationMemberId, String roleMemberId, String memberId, String memberTypeCode, 
 711  
                         String delegationTypeCode, String roleId, AttributeSet qualifications, 
 712  
                         Date activeFromDate, Date activeToDate) throws UnsupportedOperationException{
 713  0
             getRoleUpdateService().saveDelegationMemberForRole(delegationMemberId, roleMemberId, memberId, memberTypeCode, delegationTypeCode, roleId, qualifications, activeFromDate, activeToDate);
 714  0
                 KimRoleInfo role = getRole( roleId );
 715  0
                 removeCacheEntries( role.getRoleId(), null );
 716  0
     }
 717  
 
 718  
     public RoleMemberCompleteInfo saveRoleMemberForRole(String roleMemberId, String memberId, String memberTypeCode, 
 719  
                     String roleId, AttributeSet qualifications, Date activeFromDate, Date activeToDate) throws UnsupportedOperationException{
 720  0
                 KimRoleInfo role = getRole( roleId );
 721  0
                 RoleMemberCompleteInfo roleMemberCompleteInfo = getRoleUpdateService().saveRoleMemberForRole(roleMemberId, memberId, memberTypeCode, roleId, qualifications, activeFromDate, activeToDate);
 722  0
                 removeCacheEntries( role.getRoleId(), memberId );
 723  0
                 return roleMemberCompleteInfo;
 724  
     }
 725  
     
 726  
         public void removeRoleFromRole(String roleId, String namespaceCode, String roleName,
 727  
                         AttributeSet qualifications) {
 728  0
                 getRoleUpdateService().removeRoleFromRole( roleId, namespaceCode, roleName, qualifications );
 729  0
                 KimRoleInfo role = getRoleByName( namespaceCode, roleName );
 730  0
                 removeCacheEntries( role.getRoleId(), null );
 731  0
         }
 732  
 
 733  
     public List<RoleMemberCompleteInfo> findRoleMembersCompleteInfo(Map<String, String> fieldValues){
 734  0
             return getRoleService().findRoleMembersCompleteInfo(fieldValues);
 735  
     }
 736  
     
 737  
     public List<DelegateMemberCompleteInfo> findDelegateMembersCompleteInfo(Map<String, String> fieldValues){
 738  0
             return getRoleService().findDelegateMembersCompleteInfo(fieldValues);
 739  
     }
 740  
         
 741  
     public List<DelegateMemberCompleteInfo> getDelegationMembersByDelegationId(@WebParam(name="delegationId") String delegationId){
 742  0
                 return getRoleService().getDelegationMembersByDelegationId(delegationId);
 743  
         }
 744  
         
 745  
         public DelegateMemberCompleteInfo getDelegationMemberByDelegationAndMemberId(@WebParam(name="delegationId") String delegationId, @WebParam(name="memberId") String memberId){
 746  0
                 return getRoleService().getDelegationMemberByDelegationAndMemberId(delegationId, memberId);
 747  
         }
 748  
         
 749  
         public DelegateMemberCompleteInfo getDelegationMemberById(@WebParam(name="delegationMemberId") String delegationMemberId){
 750  0
                 return getRoleService().getDelegationMemberById(delegationMemberId);        
 751  
         }
 752  
 
 753  
         public List<RoleResponsibilityActionInfo> getRoleMemberResponsibilityActionInfo(String roleMemberId){
 754  0
                 return getRoleService().getRoleMemberResponsibilityActionInfo(roleMemberId);
 755  
         }
 756  
         
 757  
         public DelegateTypeInfo getDelegateTypeInfo(String roleId, String delegationTypeCode){
 758  0
                 return getRoleService().getDelegateTypeInfo(roleId, delegationTypeCode);
 759  
         }
 760  
 
 761  
         public DelegateTypeInfo getDelegateTypeInfoById(String delegationId){
 762  0
                 return getRoleService().getDelegateTypeInfoById(delegationId);
 763  
         }
 764  
         
 765  
         public void saveRoleRspActions(String roleResponsibilityActionId, String roleId, String roleResponsibilityId, String roleMemberId, 
 766  
                         String actionTypeCode, String actionPolicyCode, Integer priorityNumber, Boolean forceAction){
 767  0
             getRoleUpdateService().saveRoleRspActions(roleResponsibilityActionId, roleId, roleResponsibilityId, roleMemberId, actionTypeCode, actionPolicyCode, priorityNumber, forceAction);
 768  0
                 removeCacheEntries(roleId, null);
 769  0
         }
 770  
 
 771  
         public List<RoleResponsibilityInfo> getRoleResponsibilities(String roleId){
 772  0
                 return getRoleService().getRoleResponsibilities(roleId);
 773  
         }
 774  
         
 775  
         public void applicationRoleMembershipChanged(String roleId) {
 776  0
                 removeCacheEntries(roleId, null);
 777  0
                 getRoleService().applicationRoleMembershipChanged(roleId);                
 778  0
         }
 779  
         
 780  
         // Spring and injection methods
 781  
         
 782  
         public RoleService getRoleService() {
 783  0
                 if ( roleService == null ) {
 784  0
                         roleService = KIMServiceLocator.getRoleService();
 785  
                 }
 786  0
                 return roleService;
 787  
         }
 788  
         
 789  
         public KimTypeInfoService getTypeInfoService() {
 790  0
                 if (typeInfoService == null) {
 791  0
                         typeInfoService = KIMServiceLocator.getTypeInfoService();
 792  
                 }
 793  0
                 return typeInfoService;
 794  
         }
 795  
 
 796  
         public RoleUpdateService getRoleUpdateService() {
 797  
                 try {
 798  0
                         if ( roleUpdateService == null ) {
 799  0
                                 roleUpdateService = KIMServiceLocator.getRoleUpdateService();
 800  0
                                 if ( roleUpdateService == null ) {
 801  0
                                         throw new UnsupportedOperationException( "null returned for RoleUpdateService, unable to update role data");
 802  
                                 }
 803  
                         }
 804  0
                 } catch ( Exception ex ) {
 805  0
                         throw new UnsupportedOperationException( "unable to obtain a RoleUpdateService, unable to update role data", ex);
 806  0
                 }
 807  0
                 return roleUpdateService;
 808  
         }
 809  
         
 810  
         public void setRoleCacheMaxSize(int roleCacheMaxSize) {
 811  0
                 this.roleCacheMaxSize = roleCacheMaxSize;
 812  0
         }
 813  
 
 814  
         public void setRoleCacheMaxAgeSeconds(int roleCacheMaxAge) {
 815  0
                 this.roleCacheMaxAgeSeconds = roleCacheMaxAge;
 816  0
         }
 817  
         
 818  
         /**
 819  
          * This overridden method looks up roles based on criteria.  If you want
 820  
          * to return all roles pass in an empty map.
 821  
          *
 822  
          * @see org.kuali.rice.kim.service.RoleService#lookupRoles(java.util.Map)
 823  
          */
 824  
         public List<KimRoleInfo> lookupRoles(Map<String, String> searchCriteria) {
 825  0
                 return getRoleService().lookupRoles(searchCriteria);
 826  
         }
 827  
 
 828  
         public void flushInternalRoleCache() {
 829  0
                 getRoleService().flushInternalRoleCache();
 830  0
         }
 831  
         
 832  
         public void flushInternalRoleMemberCache() {
 833  0
                 getRoleService().flushInternalRoleMemberCache();
 834  0
         }
 835  
         
 836  
         public void flushInternalDelegationCache() {
 837  0
                 getRoleService().flushInternalDelegationCache();
 838  0
         }
 839  
         
 840  
         public void flushInternalDelegationMemberCache() {
 841  0
                 getRoleService().flushInternalDelegationMemberCache();
 842  0
         }
 843  
 
 844  
     public void assignPermissionToRole(String permissionId, String roleId) throws UnsupportedOperationException {
 845  0
         getRoleUpdateService().assignPermissionToRole(permissionId, roleId);
 846  0
     }
 847  
 
 848  
     public String getNextAvailableRoleId() throws UnsupportedOperationException {
 849  0
         return getRoleUpdateService().getNextAvailableRoleId();
 850  
     }
 851  
 
 852  
     public void saveRole(String roleId, String roleName, String roleDescription, boolean active, String kimTypeId, String namespaceCode) throws UnsupportedOperationException {
 853  0
         getRoleUpdateService().saveRole(roleId, roleName, roleDescription, active, kimTypeId, namespaceCode);
 854  0
     }
 855  
 
 856  
         /**
 857  
          * This overridden method ...
 858  
          * 
 859  
          * @see org.kuali.rice.kim.service.RoleService#getMemberParentRoleIds(java.lang.String, java.lang.String)
 860  
          */
 861  
         public List<String> getMemberParentRoleIds(String memberType,
 862  
                         String memberId) {
 863  0
                 return getRoleService().getMemberParentRoleIds(memberType, memberId);
 864  
         }
 865  
 }