Coverage Report - org.kuali.rice.kim.service.impl.RoleServiceBase
 
Classes in this File Line Coverage Branch Coverage Complexity
RoleServiceBase
0%
0/537
0%
0/436
4.055
RoleServiceBase$1
0%
0/1
N/A
4.055
RoleServiceBase$RoleDaoAction
0%
0/10
N/A
4.055
RoleServiceBase$RoleMemberCacheKeyHelper
0%
0/11
0%
0/2
4.055
 
 1  
 /*
 2  
  * Copyright 2007-2010 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 org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 21  
 import org.kuali.rice.core.util.AttributeSet;
 22  
 import org.kuali.rice.kew.util.KEWConstants;
 23  
 import org.kuali.rice.kim.api.entity.principal.Principal;
 24  
 import org.kuali.rice.kim.api.entity.principal.PrincipalContract;
 25  
 import org.kuali.rice.kim.api.group.Group;
 26  
 import org.kuali.rice.kim.api.services.IdentityManagementService;
 27  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 28  
 import org.kuali.rice.kim.bo.Role;
 29  
 
 30  
 import org.kuali.rice.kim.bo.impl.RoleImpl;
 31  
 import org.kuali.rice.kim.bo.role.dto.DelegateMemberCompleteInfo;
 32  
 import org.kuali.rice.kim.bo.role.dto.RoleMemberCompleteInfo;
 33  
 import org.kuali.rice.kim.bo.role.dto.RoleResponsibilityActionInfo;
 34  
 import org.kuali.rice.kim.bo.role.impl.KimDelegationImpl;
 35  
 import org.kuali.rice.kim.bo.role.impl.KimDelegationMemberImpl;
 36  
 import org.kuali.rice.kim.bo.role.impl.RoleMemberAttributeDataImpl;
 37  
 import org.kuali.rice.kim.bo.role.impl.RoleMemberImpl;
 38  
 import org.kuali.rice.kim.bo.role.impl.RoleResponsibilityActionImpl;
 39  
 import org.kuali.rice.kim.dao.KimRoleDao;
 40  
 import org.kuali.rice.kim.framework.type.KimDelegationTypeService;
 41  
 import org.kuali.rice.kim.framework.type.KimRoleTypeService;
 42  
 import org.kuali.rice.kim.impl.common.attribute.KimAttributeBo;
 43  
 import org.kuali.rice.kim.impl.responsibility.ResponsibilityInternalService;
 44  
 import org.kuali.rice.kim.service.IdentityManagementNotificationService;
 45  
 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
 46  
 import org.kuali.rice.kim.util.KIMPropertyConstants;
 47  
 import org.kuali.rice.kim.util.KimCommonUtilsInternal;
 48  
 import org.kuali.rice.kim.util.KimConstants;
 49  
 import org.kuali.rice.kns.service.BusinessObjectService;
 50  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 51  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 52  
 import org.kuali.rice.kns.service.LookupService;
 53  
 import org.kuali.rice.kns.service.SequenceAccessorService;
 54  
 import org.kuali.rice.kns.util.KNSPropertyConstants;
 55  
 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
 56  
 import org.kuali.rice.ksb.api.cache.RiceCacheAdministrator;
 57  
 
 58  
 import javax.xml.namespace.QName;
 59  
 import java.util.ArrayList;
 60  
 import java.util.Collection;
 61  
 import java.util.Collections;
 62  
 import java.util.HashMap;
 63  
 import java.util.HashSet;
 64  
 import java.util.List;
 65  
 import java.util.Map;
 66  
 import java.util.Set;
 67  
 
 68  
 /**
 69  
  * This is a description of what this class does - jjhanso don't forget to fill this in. 
 70  
  * 
 71  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 72  
  *
 73  
  */
 74  0
 public class RoleServiceBase {
 75  
         protected static final String ROLE_IMPL_CACHE_PREFIX = "RoleImpl-ID-";
 76  
         protected static final String ROLE_IMPL_BY_NAME_CACHE_PREFIX = "RoleImpl-Name-";
 77  
         protected static final String ROLE_IMPL_CACHE_GROUP = "RoleImpl";
 78  
         
 79  
         protected static final String ROLE_MEMBER_IMPL_CACHE_PREFIX = "RoleMemberImpl-ID-";
 80  
         protected static final String ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX = "RoleMemberImpl-List-";
 81  
         protected static final String ROLE_MEMBER_IMPL_CACHE_GROUP = "RoleMemberImpl";
 82  
         
 83  
         protected static final String DELEGATION_IMPL_CACHE_PREFIX = "KimDelegationImpl-ID-";
 84  
         protected static final String DELEGATION_IMPL_LIST_CACHE_PREFIX = "KimDelegationImpl-List-";
 85  
         protected static final String DELEGATION_IMPL_CACHE_GROUP = "KimDelegationImpl";
 86  
         
 87  
         protected static final String DELEGATION_MEMBER_IMPL_CACHE_PREFIX = "KimDelegationMemberImpl-ID-";
 88  
         protected static final String DELEGATION_MEMBER_IMPL_BY_DLGN_AND_ID_CACHE_PREFIX = "KimDelegationMemberImpl-DelegationAndId-";
 89  
         protected static final String DELEGATION_MEMBER_IMPL_LIST_CACHE_PREFIX = "KimDelegationMemberImpl-List-";
 90  
         protected static final String DELEGATION_MEMBER_IMPL_LIST_BY_MBR_DLGN_CACHE_PREFIX = "KimDelegationMemberImpl-List-MemberAndDelegationId-";
 91  
         protected static final String DELEGATION_MEMBER_IMPL_CACHE_GROUP = "KimDelegationMemberImpl";
 92  
         
 93  
         private BusinessObjectService businessObjectService;
 94  
         private LookupService lookupService;
 95  
         private RiceCacheAdministrator cacheAdministrator;
 96  
         private SequenceAccessorService sequenceAccessorService;
 97  
         private IdentityManagementService identityManagementService;
 98  
         private ResponsibilityInternalService responsibilityInternalService;
 99  
 
 100  0
     private Map<String,KimRoleTypeService> roleTypeServiceCache = Collections.synchronizedMap( new HashMap<String,KimRoleTypeService>() );
 101  0
         private Map<String,KimDelegationTypeService> delegationTypeServiceCache = Collections.synchronizedMap( new HashMap<String,KimDelegationTypeService>() );
 102  
 
 103  0
         private Map<String,Boolean> applicationRoleTypeCache = Collections.synchronizedMap( new HashMap<String,Boolean>() );
 104  
         private KimRoleDao roleDao;
 105  
         
 106  
         /**
 107  
          * A helper enumeration for indicating which KimRoleDao method to use when attempting to get role/delegation-related lists that are not in the cache.
 108  
          * 
 109  
          * @author Kuali Rice Team (rice.collab@kuali.org)
 110  
          */
 111  0
         protected static enum RoleDaoAction {
 112  0
                 ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS("principalMembers-"),
 113  0
                 ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS("groupMembers-"),
 114  0
                 ROLE_MEMBERS_FOR_ROLE_IDS("membersOfRole-"),
 115  0
                 ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS("rolesAsMembers-"),
 116  0
                 ROLE_MEMBERS_FOR_ROLE_IDS_WITH_FILTERS("roleIdsWithFilters-"),
 117  0
                 DELEGATION_PRINCIPALS_FOR_PRINCIPAL_ID_AND_DELEGATION_IDS("delegationPrincipals-"),
 118  0
                 DELEGATION_GROUPS_FOR_GROUP_IDS_AND_DELEGATION_IDS("delegationGroups-"),
 119  0
                 DELEGATION_MEMBERS_FOR_DELEGATION_IDS("delegationMembers-");
 120  
                 
 121  
                 public final String DAO_ACTION_CACHE_PREFIX;
 122  0
                 private RoleDaoAction(String daoActionCachePrefix) { this.DAO_ACTION_CACHE_PREFIX = daoActionCachePrefix;  }
 123  
         }
 124  
         
 125  
     // -----------------------------------------------------------------------------------------------------------------
 126  
     // Role Membership Caching Methods
 127  
     // -----------------------------------------------------------------------------------------------------------------
 128  
 
 129  
         /**
 130  
          * Generates a String key to use for storing or retrieving a RoleMemberImpl to/from the cache.
 131  
          * 
 132  
          * @param roleMemberId The ID of the RoleMemberImpl to generate a key for.
 133  
          * @return A cache key for the RoleMemberImpl with the given ID.
 134  
          */
 135  
         protected String getRoleMemberCacheKey(String roleMemberId) {
 136  0
                 return ROLE_MEMBER_IMPL_CACHE_PREFIX + roleMemberId;
 137  
         }
 138  
         
 139  
         /**
 140  
          * Generates a String key to use for storing or retrieving a list of RoleMemberImpls to/from the cache. The key is generated by specifying
 141  
          * certain properties that are common to all the RoleMemberImpl instances in the list to be cached. Note that at least one common
 142  
          * property will always be null; for instance, a role member cannot have a member ID that refers to both a principal and a group, so at least
 143  
          * the principalId or the groupId parameter will have a null value passed in by the calling code in this RoleService implementation. Also,
 144  
          * the value of the RoleDaoAction parameter passed in will affect which subsequent parameters will be used in generating the cache key.
 145  
          * 
 146  
          * @param roleDaoAction The RoleDaoAction signifying which KimRoleDao call found this list; will determine how and which parameters are used.
 147  
          * @param roleId The role ID (possibly as a member ID) shared among the members of the list; will be interpreted as an empty String if this is blank.
 148  
          * @param principalId The (principal) member ID shared among the members of the list; will be interpreted as an empty String if this is blank.
 149  
          * @param groupId The (group) member ID shared among the members of the list; will be interpreted as an empty String if this is blank.
 150  
          * @param memberTypeCode The member type code shared among the members of the list; will be interpreted as an empty String if this is blank.
 151  
          * @return A cache key for the RoleMemberImpl list whose members share the given roleId, principalId, groupId, and memberTypeCode.
 152  
          * @throws IllegalArgumentException if the RoleDaoAction parameter does not refer to a role-member-related enumeration value.
 153  
          */
 154  
         protected String getRoleMemberListCacheKey(RoleDaoAction roleDaoAction, String roleId, String principalId, String groupId, String memberTypeCode) {
 155  0
                 switch (roleDaoAction) {
 156  
                         case ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS : // Search for principal role members only.
 157  0
                                 return new StringBuilder(ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX).append(roleDaoAction.DAO_ACTION_CACHE_PREFIX).append(
 158  
                                                 StringUtils.isBlank(roleId) ? "" : roleId).append('-').append(StringUtils.isBlank(principalId) ? "" : principalId).toString();
 159  
                         case ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS : // Search for group role members only.
 160  0
                                 return new StringBuilder(ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX).append(roleDaoAction.DAO_ACTION_CACHE_PREFIX).append(
 161  
                                                 StringUtils.isBlank(roleId) ? "" : roleId).append('-').append(StringUtils.isBlank(groupId) ? "" : groupId).toString();
 162  
                         case ROLE_MEMBERS_FOR_ROLE_IDS : // Search for role members with the given member type code.
 163  0
                                 return new StringBuilder(ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX).append(roleDaoAction.DAO_ACTION_CACHE_PREFIX).append(
 164  
                                                 StringUtils.isBlank(roleId) ? "" : roleId).append('-').append(StringUtils.isBlank(memberTypeCode) ? "" : memberTypeCode).toString();
 165  
                         case ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS : // Search for role members who are also roles.
 166  0
                                 return new StringBuilder(ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX).append(roleDaoAction.DAO_ACTION_CACHE_PREFIX).append(
 167  
                                                 StringUtils.isBlank(roleId) ? "" : roleId).toString();
 168  
                         case ROLE_MEMBERS_FOR_ROLE_IDS_WITH_FILTERS : // Search for role members that might be roles, principals, or groups.
 169  0
                                 return new StringBuilder(ROLE_MEMBER_IMPL_LIST_CACHE_PREFIX).append(roleDaoAction.DAO_ACTION_CACHE_PREFIX).append(
 170  
                                                 StringUtils.isBlank(roleId) ? "" : roleId).append('-').append(StringUtils.isBlank(principalId) ? "" : principalId).append(
 171  
                                                                 '-').append(StringUtils.isBlank(groupId) ? "" : groupId).append('-').append(
 172  
                                                                                 StringUtils.isBlank(memberTypeCode) ? "" : memberTypeCode).toString();
 173  
                         default : // The daoActionToTake parameter is invalid; throw an exception.
 174  0
                                 throw new IllegalArgumentException("The 'roleDaoAction' parameter cannot refer to a non-role-member-related value!");
 175  
                 }
 176  
         }
 177  
         
 178  
         /**
 179  
          * Converts the Qualifier Name/Value Role qualification set into Qualifier AttributeID/Value set
 180  
          * 
 181  
          * @param qualification The original role qualification attribute set
 182  
          * @return Converted attributeSet containing ID/value pairs
 183  
          */        
 184  
         private AttributeSet convertQualifierKeys(AttributeSet qualification) {
 185  0
                 AttributeSet convertedQualification = new AttributeSet();
 186  0
                 if(qualification != null && CollectionUtils.isNotEmpty(qualification.keySet())) { 
 187  0
                         for(String attributeName : qualification.keySet()) {
 188  0
                                 if(StringUtils.isNotEmpty(getKimAttributeId(attributeName))) {
 189  0
                                         convertedQualification.put(getKimAttributeId(attributeName), qualification.get(attributeName));
 190  
                                 }
 191  
                         }
 192  
                 }
 193  0
                 return convertedQualification;
 194  
         }
 195  
         
 196  
     public Set<String> getRoleTypeRoleMemberIds( String roleId ){
 197  0
             Set<String> results = new HashSet();
 198  0
             getNestedRoleTypeMemberIds( roleId, results);
 199  0
             return results;
 200  
     }
 201  
 
 202  
     protected void getNestedRoleTypeMemberIds( String roleId, Set members) throws RuntimeException
 203  
     {
 204  0
             ArrayList<String> roleList = new ArrayList<String>( 1 );
 205  0
                 roleList.add( roleId );
 206  0
                 List<RoleMemberImpl> firstLevelMembers = getStoredRoleMembersForRoleIds(roleList, KimConstants.KimUIConstants.MEMBER_TYPE_ROLE_CODE, null);
 207  0
                 for (RoleMemberImpl member : firstLevelMembers) {
 208  0
                         if (KimConstants.KimUIConstants.MEMBER_TYPE_ROLE_CODE.equals(member.getMemberTypeCode())){
 209  0
                                 if (!members.contains(member.getMemberId())){
 210  0
                                         members.add(member.getMemberId());
 211  0
                                         getNestedRoleTypeMemberIds( member.getMemberId(), members);
 212  
                                 }
 213  
                         }
 214  
             }            
 215  0
     }
 216  
     
 217  
     public List<String> getMemberParentRoleIds(String memberType, String memberId) {        
 218  0
                 List<RoleMemberImpl> parentRoleMembers = roleDao.getRoleMembershipsForMemberId(memberType, memberId, null);
 219  
 
 220  0
                 List<String> parentRoleIds = new ArrayList<String>(parentRoleMembers.size());
 221  0
                 for (RoleMemberImpl parentRoleMember: parentRoleMembers) {
 222  0
                         parentRoleIds.add(parentRoleMember.getRoleId());
 223  
                 }
 224  
                 
 225  0
             return parentRoleIds;
 226  
     }
 227  
     
 228  
         /**
 229  
          * Retrieves a list of RoleMemberImpl instances from the cache and/or the KimRoleDao as appropriate.
 230  
          * 
 231  
          * @param daoActionToTake An indicator for which KimRoleDao method should be used to get the results if the desired RoleMemberImpls are not cached.
 232  
          * @param roleIds The role IDs to filter by; may get used as the IDs for members that are also roles, depending on the daoActionToTake value.
 233  
          * @param principalId The principal ID to filter by; may get ignored depending on the daoActionToTake value.
 234  
          * @param groupIds The group IDs to filter by; may get ignored depending on the daoActionToTake value.
 235  
          * @param memberTypeCode The member type code to filter by; may get overridden depending on the daoActionToTake value.
 236  
          * @param qualification The original role qualification attribute set 
 237  
          * @return A list of RoleMemberImpl instances based on the provided parameters.
 238  
          * @throws IllegalArgumentException if daoActionToTake refers to an enumeration constant that is not role-member-related.
 239  
          */
 240  
         protected List<RoleMemberImpl> getRoleMemberImplList(RoleDaoAction daoActionToTake, Collection<String> roleIds, String principalId,
 241  
                         Collection<String> groupIds, String memberTypeCode, AttributeSet qualification) {
 242  0
                 List<RoleMemberImpl> finalResults = new ArrayList<RoleMemberImpl>();
 243  0
                 List<RoleMemberCacheKeyHelper> searchKeys = new ArrayList<RoleMemberCacheKeyHelper>();
 244  0
                 List<RoleMemberCacheKeyHelper> uncachedKeys = new ArrayList<RoleMemberCacheKeyHelper>();
 245  0
                 Set<String> usedKeys = new HashSet<String>();
 246  0
                 AttributeSet convertedQualification = convertQualifierKeys(qualification);
 247  
                 
 248  0
                 if (roleIds == null || roleIds.isEmpty()) { roleIds = Collections.singletonList(null); }
 249  0
                 if (groupIds == null || groupIds.isEmpty()) { groupIds = Collections.singletonList(null); }
 250  
                 
 251  
                 // Attempt to find any pre-cached role members based on what KimRoleDao method call is desired.
 252  0
                 switch (daoActionToTake) {
 253  
                         case ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS : // Search for principal role members only.
 254  0
                                 for (String roleId : roleIds) {
 255  0
                                         searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, principalId, null, Role.PRINCIPAL_MEMBER_TYPE));
 256  
                                 }
 257  0
                                 break;
 258  
                         case ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS : // Search for group role members only.
 259  0
                                 for (String roleId : roleIds) {
 260  0
                                         for (String groupId : groupIds) {
 261  0
                                                 searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, null, groupId, Role.GROUP_MEMBER_TYPE));
 262  
                                         }
 263  
                                 }
 264  0
                                 break;
 265  
                         case ROLE_MEMBERS_FOR_ROLE_IDS : // Search for role members with the given member type code.
 266  0
                                 for (String roleId : roleIds) {
 267  0
                                         searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, null, null, memberTypeCode));
 268  
                                 }
 269  0
                                 break;
 270  
                         case ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS : // Search for role members who are also roles.
 271  0
                                 for (String roleId : roleIds) {
 272  0
                                         searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, null, null, Role.ROLE_MEMBER_TYPE));
 273  
                                 }
 274  0
                                 break;
 275  
                         case ROLE_MEMBERS_FOR_ROLE_IDS_WITH_FILTERS : // Search for role members that might be roles, principals, or groups.
 276  0
                                 for (String roleId : roleIds) {
 277  0
                                         searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, null, null, Role.ROLE_MEMBER_TYPE));
 278  0
                                         searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, principalId, null, Role.PRINCIPAL_MEMBER_TYPE));
 279  0
                                         for (String groupId : groupIds) {
 280  0
                                                 searchKeys.add(new RoleMemberCacheKeyHelper(daoActionToTake, roleId, null, groupId, Role.GROUP_MEMBER_TYPE));
 281  
                                         }
 282  
                                 }
 283  0
                                 break;
 284  
                         default : // The daoActionToTake parameter is invalid; throw an exception.
 285  0
                                 throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a non-role-member-related value!");
 286  
                 }
 287  
                 
 288  
                 // Attempt to find any pre-cached role members.
 289  0
                 for (RoleMemberCacheKeyHelper searchKey : searchKeys) {
 290  0
                         if (!usedKeys.contains(searchKey.getCacheKey())) {
 291  0
                                 List<RoleMemberImpl> tempMembers = (List<RoleMemberImpl>) getCacheAdministrator().getFromCache(searchKey.getCacheKey(), getRefreshPeriodInSeconds());
 292  0
                                 if (tempMembers != null) {
 293  0
                                         finalResults.addAll(tempMembers);
 294  
                                 } else {
 295  0
                                         uncachedKeys.add(searchKey);
 296  
                                 }
 297  0
                                 usedKeys.add(searchKey.getCacheKey());
 298  0
                         }
 299  
                 }
 300  
                 
 301  
                 // If any portion of the result set was not in the cache, then retrieve and cache the missing sections.
 302  0
                 if (!uncachedKeys.isEmpty()) {
 303  0
                         Set<String> uncachedRoleSet = new HashSet<String>();
 304  0
                         Set<String> uncachedGroupSet = new HashSet<String>();
 305  0
                         for (RoleMemberCacheKeyHelper uncachedKey : uncachedKeys) {
 306  0
                                 if (uncachedKey.ROLE_ID != null) { uncachedRoleSet.add(uncachedKey.ROLE_ID); }
 307  0
                                 if (uncachedKey.GROUP_ID != null) { uncachedGroupSet.add(uncachedKey.GROUP_ID); }
 308  
                         }
 309  
                         
 310  0
                         List<String> uncachedRoles = (uncachedRoleSet.isEmpty()) ? null : new ArrayList<String>(uncachedRoleSet);
 311  0
                         List<String> uncachedGroups = (uncachedGroupSet.isEmpty()) ? null : new ArrayList<String>(uncachedGroupSet);
 312  0
                         List<RoleMemberImpl> uncachedResults = null;
 313  
                         
 314  
                         // Retrieve the uncached RoleMemberImpls via the appropriate RoleDao method.
 315  0
                         switch (daoActionToTake) {
 316  
                                 case ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS : // Search for principal role members only.
 317  0
                                         uncachedResults = roleDao.getRolePrincipalsForPrincipalIdAndRoleIds(uncachedRoles, principalId, convertedQualification);
 318  0
                                         break;
 319  
                                 case ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS : // Search for group role members only.
 320  0
                                         uncachedResults = roleDao.getRoleGroupsForGroupIdsAndRoleIds(uncachedRoles, uncachedGroups, convertedQualification);
 321  0
                                         break;
 322  
                                 case ROLE_MEMBERS_FOR_ROLE_IDS : // Search for role members with the given member type code.
 323  0
                                         uncachedResults = roleDao.getRoleMembersForRoleIds(uncachedRoles, memberTypeCode, convertedQualification);
 324  0
                                         break;
 325  
                                 case ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS : // Search for role members who are also roles.
 326  0
                                         uncachedResults = roleDao.getRoleMembershipsForRoleIdsAsMembers(uncachedRoles, convertedQualification);
 327  0
                                         break;
 328  
                                 case ROLE_MEMBERS_FOR_ROLE_IDS_WITH_FILTERS : // Search for role members that might be roles, principals, or groups.
 329  0
                                         uncachedResults = roleDao.getRoleMembersForRoleIdsWithFilters(uncachedRoles, principalId, uncachedGroups, convertedQualification);
 330  0
                                         break;
 331  
                                 default : // This should never happen, since the previous switch block should handle this case appropriately.
 332  0
                                         throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a non-role-member-related value!");
 333  
                         }
 334  
                         
 335  0
                         cacheRoleMemberLists(uncachedKeys, uncachedResults);
 336  0
                         for (RoleMemberImpl uncachedMember : uncachedResults) {
 337  0
                                 addRoleMemberImplToCache(uncachedMember);
 338  
                         }
 339  0
                         finalResults.addAll(uncachedResults);
 340  
                 }
 341  0
                 return finalResults;
 342  
         }
 343  
         
 344  
         /**
 345  
          * Caches several Lists of role members that are constructed based on the given search keys. Note that a given List will not be cached if
 346  
          * it contains any role members that belong to a role that disallows caching of its members.
 347  
          * 
 348  
          * @param keysToCache The keys of the role member Lists that will be used to store the uncached results.
 349  
          * @param membersToCache The uncached role members.
 350  
          */
 351  
         private void cacheRoleMemberLists(List<RoleMemberCacheKeyHelper> keysToCache, List<RoleMemberImpl> membersToCache) {
 352  0
                 if (membersToCache == null) { membersToCache = new ArrayList<RoleMemberImpl>(); }
 353  0
                 for (RoleMemberCacheKeyHelper keyToCache : keysToCache) {
 354  0
                         List<RoleMemberImpl> roleMembers = new ArrayList<RoleMemberImpl>();
 355  
                         
 356  
                         // Cache the Lists that do not contain role members belonging to roles that forbid caching of their members.
 357  0
                         if (RoleDaoAction.ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS.equals(keyToCache.ROLE_DAO_ACTION)) {
 358  0
                                 boolean safeToCacheList = true;
 359  0
                                 for (RoleMemberImpl memberToCache : membersToCache) {
 360  0
                                         if ( (keyToCache.ROLE_ID == null || keyToCache.ROLE_ID.equals(memberToCache.getMemberId())) &&
 361  
                                                         (keyToCache.MEMBER_TYPE_CODE == null || keyToCache.MEMBER_TYPE_CODE.equals(memberToCache.getMemberTypeCode())) ) {
 362  0
                                                 if (shouldCacheMembersOfRole(memberToCache.getRoleId())) {
 363  0
                                                         roleMembers.add(memberToCache);
 364  
                                                 } else {
 365  0
                                                         safeToCacheList = false;
 366  0
                                                         break;
 367  
                                                 }
 368  
                                         }
 369  
                                 }
 370  0
                                 if (safeToCacheList) { getCacheAdministrator().putInCache(keyToCache.getCacheKey(), roleMembers, ROLE_MEMBER_IMPL_CACHE_GROUP); }
 371  0
                         } else if (keyToCache.ROLE_ID == null || shouldCacheMembersOfRole(keyToCache.ROLE_ID)) {
 372  0
                                 for (RoleMemberImpl memberToCache : membersToCache) {
 373  0
                                         if ( (keyToCache.ROLE_ID == null || keyToCache.ROLE_ID.equals(memberToCache.getRoleId())) &&
 374  
                                                         (keyToCache.PRINCIPAL_ID == null || keyToCache.PRINCIPAL_ID.equals(memberToCache.getMemberId())) &&
 375  
                                                         (keyToCache.GROUP_ID == null || keyToCache.GROUP_ID.equals(memberToCache.getMemberId())) &&
 376  
                                                         (keyToCache.MEMBER_TYPE_CODE == null || keyToCache.MEMBER_TYPE_CODE.equals(memberToCache.getMemberTypeCode())) ) {
 377  0
                                                 roleMembers.add(memberToCache);
 378  
                                         }
 379  
                                 }
 380  0
                                 getCacheAdministrator().putInCache(keyToCache.getCacheKey(), roleMembers, ROLE_MEMBER_IMPL_CACHE_GROUP);
 381  
                         }
 382  0
                 }
 383  0
         }
 384  
         
 385  
         /** Calls the KimRoleDao's "getRolePrincipalsForPrincipalIdAndRoleIds" method and/or retrieves any corresponding members from the cache. */
 386  
         protected List<RoleMemberImpl> getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collection<String> roleIds, String principalId, AttributeSet qualification) {
 387  0
                 return getRoleMemberImplList(RoleDaoAction.ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS, roleIds, principalId, null, null, qualification);
 388  
         }
 389  
         
 390  
         /** Calls the KimRoleDao's "getRoleGroupsForGroupIdsAndRoleIds" method and/or retrieves any corresponding members from the cache. */
 391  
         protected List<RoleMemberImpl> getStoredRoleGroupsForGroupIdsAndRoleIds(Collection<String> roleIds, Collection<String> groupIds, AttributeSet qualification) {
 392  0
                 return getRoleMemberImplList(RoleDaoAction.ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS, roleIds, null, groupIds, null, qualification);
 393  
         }
 394  
         
 395  
         /** Calls the KimRoleDao's "getRoleMembersForRoleIds" method and/or retrieves any corresponding members from the cache. */
 396  
         protected List<RoleMemberImpl> getStoredRoleMembersForRoleIds(Collection<String> roleIds, String memberTypeCode, AttributeSet qualification) {
 397  0
                 return getRoleMemberImplList(RoleDaoAction.ROLE_MEMBERS_FOR_ROLE_IDS, roleIds, null, null, memberTypeCode, qualification);
 398  
         }
 399  
         
 400  
         /** Calls the KimRoleDao's "getRoleMembershipsForRoleIdsAsMembers" method and/or retrieves any corresponding members from the cache. */
 401  
         protected List<RoleMemberImpl> getStoredRoleMembershipsForRoleIdsAsMembers(Collection<String> roleIds, AttributeSet qualification) {
 402  0
                 return getRoleMemberImplList(RoleDaoAction.ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS, roleIds, null, null, null, qualification);
 403  
         }
 404  
         
 405  
         /** Calls the KimRoleDao's "getRoleMembersForRoleIdsWithFilters" method and/or retrieves any corresponding members from the cache. */
 406  
         protected List<RoleMemberImpl> getStoredRoleMembersForRoleIdsWithFilters(Collection<String> roleIds, String principalId, List<String> groupIds, AttributeSet qualification) {
 407  0
                 return getRoleMemberImplList(RoleDaoAction.ROLE_MEMBERS_FOR_ROLE_IDS_WITH_FILTERS, roleIds, principalId, groupIds, null, qualification);
 408  
         }
 409  
         
 410  
         /**
 411  
          * Determines whether or not the given role should allow its members to be cached. The default implementation always returns true, but
 412  
          * subclasses can override this method if other non-default Role implementations forbid their members from being cached.
 413  
          * 
 414  
          * @param roleId The ID of the role to check for determining whether or not to allow caching of its members.
 415  
          * @return True if the given role allows its members to be cached; false otherwise.
 416  
          */
 417  
         protected boolean shouldCacheMembersOfRole(String roleId) {
 418  0
                 return true;
 419  
         }
 420  
         
 421  
         protected void addRoleMemberImplToCache(RoleMemberImpl roleMember) {
 422  0
                 if (roleMember != null && shouldCacheMembersOfRole(roleMember.getRoleId())) {
 423  0
                         getCacheAdministrator().putInCache(getRoleMemberCacheKey(roleMember.getRoleMemberId()), roleMember, ROLE_MEMBER_IMPL_CACHE_GROUP);
 424  
                 }
 425  0
         }
 426  
         
 427  
         protected RoleMemberImpl getRoleMemberFromCache(String roleMemberId) {
 428  0
                 return (RoleMemberImpl)getCacheAdministrator().getFromCache(getRoleMemberCacheKey(roleMemberId), getRefreshPeriodInSeconds());
 429  
         }
 430  
         
 431  
         public void flushInternalRoleMemberCache() {
 432  0
                 getCacheAdministrator().flushGroup(ROLE_MEMBER_IMPL_CACHE_GROUP);
 433  0
         }
 434  
         
 435  
         /**
 436  
          * Retrieves a RoleMemberImpl object by its ID. If the role member already exists in the cache, this method will return the cached
 437  
          * version; otherwise, it will retrieve the uncached version from the database and then cache it (if it belongs to a role that allows
 438  
          * its members to be cached) before returning it.
 439  
          */
 440  
     protected RoleMemberImpl getRoleMemberImpl( String roleMemberId ) {
 441  0
             if (StringUtils.isBlank(roleMemberId)) {
 442  0
                     return null;
 443  
             }
 444  
             
 445  
             // If the RoleMemberImpl exists in the cache, return the cached one.
 446  0
             RoleMemberImpl tempRoleMemberImpl = getRoleMemberFromCache(roleMemberId);
 447  0
             if (tempRoleMemberImpl != null) {
 448  0
                     return tempRoleMemberImpl;
 449  
             }
 450  
             // Otherwise, retrieve it normally.
 451  0
             tempRoleMemberImpl = (RoleMemberImpl)getBusinessObjectService().findByPrimaryKey( RoleMemberImpl.class,
 452  
                             Collections.singletonMap(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId) );
 453  0
             addRoleMemberImplToCache(tempRoleMemberImpl);
 454  0
             return tempRoleMemberImpl;
 455  
     }
 456  
         
 457  
     // -----------------------------------------------------------------------------------------------------------------
 458  
     // Delegation Caching Methods
 459  
     // -----------------------------------------------------------------------------------------------------------------
 460  
     
 461  
         /**
 462  
          * Generates a String key to use for storing or retrieving a KimDelegationImpl to/from the cache.
 463  
          * 
 464  
          * @param delegationId The ID of the KimDelegationImpl to generate a key for.
 465  
          * @return A cache key for the KimDelegationImpl with the given ID.
 466  
          */
 467  
         protected String getDelegationCacheKey(String delegationId) {
 468  0
                 return DELEGATION_IMPL_CACHE_PREFIX + delegationId;
 469  
         }
 470  
 
 471  
     /**
 472  
      * Generates a String key to use for storing or retrieving a List of KimDelegationImpls to/from the cache based on a role's ID.
 473  
      * @param roleId The ID of the role that the KIM delegations belong to.
 474  
      * @return A cache key for the KimDelegationImpls with the given role ID.
 475  
      */
 476  
     protected String getDelegationListCacheKey(String roleId) {
 477  0
             return DELEGATION_IMPL_LIST_CACHE_PREFIX + (StringUtils.isBlank(roleId) ? "" : roleId);
 478  
     }
 479  
         
 480  
     /** Calls the KimRoleDao's "getDelegationImplMapFromRoleIds" method and/or retrieves any corresponding delegations from the cache. */
 481  
         protected Map<String,KimDelegationImpl> getStoredDelegationImplMapFromRoleIds(Collection<String> roleIds) {
 482  0
                 Map<String,KimDelegationImpl> finalResults = Collections.emptyMap();
 483  
                 
 484  0
                 if (roleIds != null && !roleIds.isEmpty()) {
 485  0
                         Map<String,List<KimDelegationImpl>> uncachedLists = new HashMap<String,List<KimDelegationImpl>>();
 486  
                         // Retrieve any existing results from the cache.
 487  0
                         finalResults = getKimDelegationImplMap(uncachedLists, roleIds);
 488  
                         
 489  
                         // Retrieve any uncached results from the database and then cache them.
 490  0
                         if (!uncachedLists.isEmpty()) {
 491  0
                                 Map<String,KimDelegationImpl> uncachedResults = roleDao.getDelegationImplMapFromRoleIds(uncachedLists.keySet());
 492  
                                 
 493  0
                                 for (Map.Entry<String,KimDelegationImpl> uncachedResult : uncachedResults.entrySet()) {
 494  0
                                         finalResults.put(uncachedResult.getKey(), uncachedResult.getValue());
 495  0
                                         addKimDelegationImplToCache(uncachedResult.getValue());
 496  0
                                         uncachedLists.get(uncachedResult.getValue().getRoleId()).add(uncachedResult.getValue());
 497  
                                 }
 498  0
                                 for (Map.Entry<String,List<KimDelegationImpl>> uncachedList : uncachedLists.entrySet()) {
 499  0
                                         getCacheAdministrator().putInCache(getDelegationListCacheKey(uncachedList.getKey()),
 500  
                                                         uncachedList.getValue(), DELEGATION_IMPL_CACHE_GROUP);
 501  
                                 }
 502  
                         }
 503  
                 }
 504  
                 
 505  0
                 return finalResults;
 506  
         }
 507  
         
 508  
         /** Calls the KimRoleDao's "getDelegationImplsForRoleIds" method and/or retrieves any corresponding delegations from the cache. */
 509  
         protected List<KimDelegationImpl> getStoredDelegationImplsForRoleIds(Collection<String> roleIds) {
 510  0
                 List<KimDelegationImpl> finalResults = new ArrayList<KimDelegationImpl>();
 511  
                 
 512  0
                 if (roleIds != null && !roleIds.isEmpty()) {
 513  0
                         Map<String,List<KimDelegationImpl>> uncachedLists = new HashMap<String,List<KimDelegationImpl>>();
 514  
                         // Retrieve any existing results from the cache.
 515  0
                         Map<String,KimDelegationImpl> tempDelegations = getKimDelegationImplMap(uncachedLists, roleIds);
 516  0
                         finalResults.addAll(tempDelegations.values());
 517  
                         
 518  
                         // Retrieve any uncached results from the database and then cache them.
 519  0
                         if (!uncachedLists.isEmpty()) {
 520  0
                                 List<KimDelegationImpl> uncachedResults = roleDao.getDelegationImplsForRoleIds(uncachedLists.keySet());
 521  
                                 
 522  0
                                 for (KimDelegationImpl uncachedResult : uncachedResults) {
 523  0
                                         addKimDelegationImplToCache(uncachedResult);
 524  0
                                         uncachedLists.get(uncachedResult.getRoleId()).add(uncachedResult);
 525  
                                 }
 526  0
                                 for (Map.Entry<String,List<KimDelegationImpl>> uncachedList : uncachedLists.entrySet()) {
 527  0
                                         getCacheAdministrator().putInCache(getDelegationListCacheKey(uncachedList.getKey()),
 528  
                                                         uncachedList.getValue(), DELEGATION_IMPL_CACHE_GROUP);
 529  
                                 }
 530  0
                                 finalResults.addAll(uncachedResults);
 531  
                         }
 532  
                 }
 533  
                 
 534  0
                 return finalResults;
 535  
         }
 536  
         
 537  
         /**
 538  
          * Retrieves any existing delegation lists from the cache for the given role IDs. If the delegations for a given role have not been cached,
 539  
          * then a new entry containing the uncached role ID and an empty List will be added to the given Map.
 540  
          * 
 541  
          * @param uncachedLists The Map in which to place any uncached lists; cannot be null.
 542  
          * @param roleIds The IDs of the roles containing the delegations.
 543  
          * @return A mutable Map containing any existing results from the cache and which maps the delegations' IDs to the delegation objects.
 544  
          * @throws IllegalArgumentException if the provided Map is null.
 545  
          */
 546  
         protected Map<String,KimDelegationImpl> getKimDelegationImplMap(Map<String,List<KimDelegationImpl>> uncachedLists, Collection<String> roleIds) {
 547  0
                 if (uncachedLists == null) {
 548  0
                         throw new IllegalArgumentException("'uncachedLists' parameter cannot be null!");
 549  
                 }
 550  0
                 Map<String,KimDelegationImpl> delegationMap = new HashMap<String,KimDelegationImpl>();
 551  
                 
 552  
                 // Retrieve any existing results from the cache.
 553  0
                 if (roleIds != null && !roleIds.isEmpty()) {
 554  0
                         for (String roleId : roleIds) {
 555  0
                                 List<KimDelegationImpl> tempDelegations = (List<KimDelegationImpl>) getCacheAdministrator().getFromCache(getDelegationListCacheKey(roleId), getRefreshPeriodInSeconds());
 556  0
                                 if (tempDelegations != null) {
 557  0
                                         for (KimDelegationImpl tempDelegation : tempDelegations) {
 558  0
                                                 delegationMap.put(tempDelegation.getDelegationId(), tempDelegation);
 559  
                                         }
 560  
                                 } else {
 561  0
                                         uncachedLists.put(roleId, new ArrayList<KimDelegationImpl>());
 562  
                                 }
 563  0
                         }
 564  
                 }
 565  
                 
 566  0
                 return delegationMap;
 567  
         }
 568  
         
 569  
         protected void addKimDelegationImplToCache(KimDelegationImpl delegation) {
 570  0
                 if (delegation != null) {
 571  0
                         getCacheAdministrator().putInCache(getDelegationCacheKey(delegation.getDelegationId()),
 572  
                                         delegation, DELEGATION_IMPL_CACHE_GROUP);
 573  
                 }
 574  0
         }
 575  
         
 576  
         protected KimDelegationImpl getDelegationFromCache(String delegationId) {
 577  0
                 return (KimDelegationImpl)getCacheAdministrator().getFromCache(getDelegationCacheKey(delegationId), getRefreshPeriodInSeconds());
 578  
         }
 579  
         
 580  
         public void flushInternalDelegationCache() {
 581  0
                 getCacheAdministrator().flushGroup(DELEGATION_IMPL_CACHE_GROUP);
 582  0
         }
 583  
         
 584  
         /**
 585  
          * Retrieves a KimDelegationImpl object by its ID. If the delegation already exists in the cache, this method will return the cached
 586  
          * version; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 587  
          */
 588  
     protected KimDelegationImpl getKimDelegationImpl( String delegationId ) {
 589  0
             if (StringUtils.isBlank(delegationId)) {
 590  0
                     return null;
 591  
             }
 592  
             
 593  
             // If the KimDelegationImpl exists in the cache, return the cached one.
 594  0
             KimDelegationImpl tempDelegation = getDelegationFromCache(delegationId);
 595  0
             if (tempDelegation != null) {
 596  0
                     return tempDelegation;
 597  
             }
 598  
             // Otherwise, retrieve it normally.
 599  0
             tempDelegation = (KimDelegationImpl)getBusinessObjectService().findByPrimaryKey( KimDelegationImpl.class,
 600  
                             Collections.singletonMap(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId) );
 601  0
             addKimDelegationImplToCache(tempDelegation);
 602  0
             return tempDelegation;
 603  
     }
 604  
     
 605  
     // -----------------------------------------------------------------------------------------------------------------
 606  
     // Delegation Membership Caching Methods
 607  
     // -----------------------------------------------------------------------------------------------------------------
 608  
     
 609  
         /**
 610  
          * Generates a String key to use for storing or retrieving a KimDelegationMemberImpl to/from the cache.
 611  
          * 
 612  
          * @param delegationMemberId The ID of the KimDelegationMemberImpl to generate a key for.
 613  
          * @return A cache key for the KimDelegationMemberImpl with the given ID.
 614  
          */
 615  
         protected String getDelegationMemberCacheKey(String delegationMemberId) {
 616  0
                 return DELEGATION_MEMBER_IMPL_CACHE_PREFIX + delegationMemberId;
 617  
         }
 618  
     
 619  
         /**
 620  
          * Generates a String key to use for storing or retrieving a KimDelegationMemberImpl to/from the cache by both delegation ID and delegation member ID.
 621  
          * 
 622  
          * @param delegationId The ID of the delegation that the KimDelegationMemberImpl belongs to.
 623  
          * @param delegationMemberId The ID of the KimDelegationMemberImpl to generate a key for.
 624  
          * @return A cache key for the KimDelegationMemberImpl with the given delegation ID and delegation member ID.
 625  
          */
 626  
         protected String getDelegationMemberByDelegationAndIdCacheKey(String delegationId, String delegationMemberId) {
 627  0
                 return new StringBuilder(DELEGATION_MEMBER_IMPL_BY_DLGN_AND_ID_CACHE_PREFIX).append(delegationId).append('-').append(delegationMemberId).toString();
 628  
         }
 629  
         
 630  
         /**
 631  
          * Generates a String key to use for storing or retrieving a KimDelegationMemberImpl List to/from the cache by both delegation ID and member ID.
 632  
          * 
 633  
          * @param memberId The principal/group/role ID of the KimDelegationMemberImpl(s) in the List.
 634  
          * @param delegationId The ID of the delegation that the KimDelegationMemberImpl(s) in the List belong to.
 635  
          * @return A cache key for the KimDelegationMemberImpl List with the given delegation ID and member ID.
 636  
          */
 637  
         protected String getDelegationMemberListByMemberAndDelegationIdCacheKey(String memberId, String delegationId) {
 638  0
                 return new StringBuilder(DELEGATION_MEMBER_IMPL_LIST_BY_MBR_DLGN_CACHE_PREFIX).append(StringUtils.isBlank(memberId) ? "" : memberId).append(
 639  
                                 '-').append(StringUtils.isBlank(delegationId) ? "" : delegationId).toString();
 640  
         }
 641  
         
 642  
         /**
 643  
          * Generates a String key to use for storing or retrieving a List of KimDelegationMemberImpl lists to/from the cache. Some parameters may get
 644  
          * ignored depending on which KimRoleDao call is desired.
 645  
          * 
 646  
          * @param daoAction The RoleDaoAction signifying which KimRoleDao call found this list; will determine how and which parameters are used.
 647  
          * @param delegationId The ID of the KimDelegationImpl that the indicated delegation member belongs to; will be interpreted as an empty String if blank.
 648  
          * @param principalId The (principal) member ID of the delegation members; will be interpreted as an empty String if blank.
 649  
          * @param groupId The (group) member ID of the delegation members; will be interpreted as an empty String if blank.
 650  
          * @return A cache key for the KimDelegationMemberImpl List with the given criteria.
 651  
          * @throws IllegalArgumentException if daoAction does not represent a delegation-member-related enumeration value.
 652  
          */
 653  
         protected String getDelegationMemberListCacheKey(RoleDaoAction daoAction, String delegationId, String principalId, String groupId) {
 654  0
                 switch (daoAction) {
 655  
                         case DELEGATION_PRINCIPALS_FOR_PRINCIPAL_ID_AND_DELEGATION_IDS : // Search for principal delegation members.
 656  0
                                 return new StringBuilder(DELEGATION_MEMBER_IMPL_LIST_CACHE_PREFIX).append(daoAction.DAO_ACTION_CACHE_PREFIX).append(
 657  
                                                 StringUtils.isBlank(delegationId) ? "" : delegationId).append('-').append(
 658  
                                                                 StringUtils.isBlank(principalId) ? "" : principalId).toString();
 659  
                         case DELEGATION_GROUPS_FOR_GROUP_IDS_AND_DELEGATION_IDS : // Search for group delegation members.
 660  0
                                 return new StringBuilder(DELEGATION_MEMBER_IMPL_LIST_CACHE_PREFIX).append(daoAction.DAO_ACTION_CACHE_PREFIX).append(
 661  
                                                 StringUtils.isBlank(delegationId) ? "" : delegationId).append('-').append(StringUtils.isBlank(groupId) ? "" : groupId).toString();
 662  
                         case DELEGATION_MEMBERS_FOR_DELEGATION_IDS : // Search for delegation members regardless of their member type.
 663  0
                                 return new StringBuilder(DELEGATION_MEMBER_IMPL_LIST_CACHE_PREFIX).append(daoAction.DAO_ACTION_CACHE_PREFIX).append(
 664  
                                                 StringUtils.isBlank(delegationId) ? "" : delegationId).toString();
 665  
                         default : // daoActionToTake is invalid; throw an exception.
 666  0
                                 throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a non-delegation-member-related value!");
 667  
                 }
 668  
         }
 669  
         
 670  
         /**
 671  
          * Retrieves a List of delegation members from the cache and/or the KimRoleDao as appropriate.
 672  
          * 
 673  
          * @param daoActionToTake An indicator for which KimRoleDao method to use for retrieving uncached results.
 674  
          * @param delegationIds The IDs of the delegations that the members belong to.
 675  
          * @param principalId The principal ID of the principal delegation members; may get ignored depending on the RoleDaoAction value.
 676  
          * @param groupIds The group IDs of the group delegation members; may get ignored depending on the RoleDaoAction value.
 677  
          * @return A List of KimDelegationMemberImpl objects based on the provided parameters.
 678  
          * @throws IllegalArgumentException if daoActionToTake does not represent a delegation-member-list-related enumeration value.
 679  
          */
 680  
         protected List<KimDelegationMemberImpl> getKimDelegationMemberImplList(RoleDaoAction daoActionToTake, Collection<String> delegationIds,
 681  
                         String principalId, List<String> groupIds) {
 682  0
                 List<KimDelegationMemberImpl> finalResults = new ArrayList<KimDelegationMemberImpl>();
 683  0
                 List<String[]> uncachedKeys = new ArrayList<String[]>();
 684  0
                 Set<String> usedKeys = new HashSet<String>();
 685  0
                 if (delegationIds == null || delegationIds.isEmpty()) { delegationIds = Collections.singletonList(null); }
 686  0
                 if (groupIds == null || groupIds.isEmpty()) { groupIds = Collections.singletonList(null); }
 687  
                 
 688  
                 // Search for cached values based on the intended search action.
 689  0
                 switch (daoActionToTake) {
 690  
                         case DELEGATION_PRINCIPALS_FOR_PRINCIPAL_ID_AND_DELEGATION_IDS : // Search for principal delegation members.
 691  0
                                 for (String delegationId : delegationIds) {
 692  0
                                         String tempKey = getDelegationMemberListCacheKey(daoActionToTake, delegationId, principalId, null);
 693  0
                                         if (!usedKeys.contains(tempKey)) {
 694  0
                                                 List<KimDelegationMemberImpl> tempMembers = (List<KimDelegationMemberImpl>) getCacheAdministrator().getFromCache(tempKey, getRefreshPeriodInSeconds());
 695  0
                                                 if (tempMembers != null) {
 696  0
                                                         finalResults.addAll(tempMembers);
 697  
                                                 } else {
 698  0
                                                         uncachedKeys.add(new String[] {delegationId, principalId, null});
 699  
                                                 }
 700  0
                                                 usedKeys.add(tempKey);
 701  
                                         }
 702  0
                                 }
 703  0
                                 break;
 704  
                         case DELEGATION_GROUPS_FOR_GROUP_IDS_AND_DELEGATION_IDS : // Search for group delegation members.
 705  0
                                 for (String delegationId : delegationIds) {
 706  0
                                         for (String groupId : groupIds) {
 707  0
                                                 String tempKey = getDelegationMemberListCacheKey(daoActionToTake, delegationId, null, groupId);
 708  0
                                                 if (!usedKeys.contains(tempKey)) {
 709  0
                                                         List<KimDelegationMemberImpl> tempMembers = (List<KimDelegationMemberImpl>) getCacheAdministrator().getFromCache(tempKey, getRefreshPeriodInSeconds());
 710  0
                                                         if (tempMembers != null) {
 711  0
                                                                 finalResults.addAll(tempMembers);
 712  
                                                         } else {
 713  0
                                                                 uncachedKeys.add(new String[] {delegationId, null, groupId});
 714  
                                                         }
 715  
                                                 }
 716  0
                                         }
 717  
                                 }
 718  0
                                 break;
 719  
                         default : // daoActionToTake is invalid; throw an exception.
 720  0
                                 throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a non-delegation-member-list-related value!");
 721  
                 }
 722  
                 
 723  
                 // Retrieve any uncached values based on the intended search action.
 724  0
                 if (!uncachedKeys.isEmpty()) {
 725  0
                         List<KimDelegationMemberImpl> uncachedResults = new ArrayList<KimDelegationMemberImpl>();
 726  0
                         Set<String> uncachedDelegationSet = new HashSet<String>();
 727  0
                         Set<String> uncachedGroupSet = new HashSet<String>();
 728  0
                         for (String[] uncachedKey : uncachedKeys) {
 729  0
                                 if (uncachedKey[0] != null) { uncachedDelegationSet.add(uncachedKey[0]); }
 730  0
                                 if (uncachedKey[2] != null) { uncachedGroupSet.add(uncachedKey[2]); }
 731  
                         }
 732  0
                         List<String> uncachedDelegations = (uncachedDelegationSet.isEmpty()) ? null : new ArrayList<String>(uncachedDelegationSet);
 733  0
                         List<String> uncachedGroups = (uncachedGroupSet.isEmpty()) ? null : new ArrayList<String>(uncachedGroupSet);
 734  0
                         String memberTypeCode = null;
 735  
                         
 736  
                         // Search for uncached values based on the intended search action.
 737  0
                         switch (daoActionToTake) {
 738  
                                 case DELEGATION_PRINCIPALS_FOR_PRINCIPAL_ID_AND_DELEGATION_IDS : // Search for principal delegation members.
 739  0
                                         uncachedResults = roleDao.getDelegationPrincipalsForPrincipalIdAndDelegationIds(uncachedDelegations, principalId);
 740  0
                                         memberTypeCode = Role.PRINCIPAL_MEMBER_TYPE;
 741  0
                                         break;
 742  
                                 case DELEGATION_GROUPS_FOR_GROUP_IDS_AND_DELEGATION_IDS : // Search for group delegation members.
 743  0
                                         uncachedResults = roleDao.getDelegationGroupsForGroupIdsAndDelegationIds(uncachedDelegations, uncachedGroups);
 744  0
                                         memberTypeCode = Role.GROUP_MEMBER_TYPE;
 745  0
                                         break;
 746  
                                 default : // This should never happen since the previous switch block should handle this case appropriately.
 747  0
                                         throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a non-delegation-member-list-related value!");
 748  
                         }
 749  
                         
 750  
                         // Cache the delegation members and add them to the final results.
 751  0
                         cacheDelegationMemberLists(daoActionToTake, uncachedKeys, memberTypeCode, uncachedResults);
 752  0
                         for (KimDelegationMemberImpl uncachedResult : uncachedResults) {
 753  0
                                 addKimDelegationMemberImplToCache(uncachedResult);
 754  
                         }
 755  0
                         finalResults.addAll(uncachedResults);
 756  
                 }
 757  
                 
 758  0
                 return finalResults;
 759  
         }
 760  
         
 761  
         /**
 762  
          * Caches several Lists of delegation members that are constructed based on the given search parameters.
 763  
          * 
 764  
          * @param daoActionToTake The enumeration constant representing the KimRoleDao call that returned the results.
 765  
          * @param uncachedKeys The keys of the delegation member Lists that will be used to store the uncached results.
 766  
          * @param memberTypeCode The member type code of all the delegation members in the uncached results.
 767  
          * @param uncachedMembers The uncached delegation members.
 768  
          */
 769  
         private void cacheDelegationMemberLists(RoleDaoAction daoActionToTake, List<String[]> uncachedKeys,
 770  
                         String memberTypeCode, List<KimDelegationMemberImpl> uncachedMembers) {
 771  
                 // Place the uncached delegation members into the list cache appropriately.
 772  0
                 for (String[] uncachedKey : uncachedKeys) {
 773  0
                         List<KimDelegationMemberImpl> tempMembers = new ArrayList<KimDelegationMemberImpl>();
 774  0
                         for (KimDelegationMemberImpl uncachedMember : uncachedMembers) {
 775  0
                                 if ( (memberTypeCode == null || memberTypeCode.equals(uncachedMember.getMemberTypeCode())) &&
 776  
                                                 (uncachedKey[0] == null || uncachedKey[0].equals(uncachedMember.getDelegationId())) &&
 777  
                                                                 (uncachedKey[1] == null || uncachedKey[1].equals(uncachedMember.getMemberId())) &&
 778  
                                                                                 (uncachedKey[2] == null || uncachedKey[2].equals(uncachedMember.getMemberId())) ) {
 779  0
                                         tempMembers.add(uncachedMember);
 780  
                                 }
 781  
                         }
 782  0
                         getCacheAdministrator().putInCache(getDelegationMemberListCacheKey(daoActionToTake, uncachedKey[0], uncachedKey[1], uncachedKey[2]),
 783  
                                         tempMembers, DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 784  0
                 }
 785  0
         }
 786  
         
 787  
         /** Calls the KimRoleDao's "getDelegationPrincipalsForPrincipalIdAndDelegationIds" method and/or retrieves any corresponding members from the cache. */
 788  
         protected List<KimDelegationMemberImpl> getStoredDelegationPrincipalsForPrincipalIdAndDelegationIds(Collection<String> delegationIds,String principalId){
 789  0
                 return getKimDelegationMemberImplList(RoleDaoAction.DELEGATION_PRINCIPALS_FOR_PRINCIPAL_ID_AND_DELEGATION_IDS, delegationIds, principalId, null);
 790  
         }
 791  
         
 792  
         /** Calls the KimRoleDao's "getDelegationGroupsForGroupIdAndDelegationIds" method and/or retrieves any corresponding members from the cache. */
 793  
         protected List<KimDelegationMemberImpl> getStoredDelegationGroupsForGroupIdsAndDelegationIds(Collection<String> delegationIds, List<String> groupIds) {
 794  0
                 return getKimDelegationMemberImplList(RoleDaoAction.DELEGATION_GROUPS_FOR_GROUP_IDS_AND_DELEGATION_IDS, delegationIds, null, groupIds);
 795  
         }
 796  
         
 797  
         /** Calls the KimRoleDao's "getDelegationMembersForDelegationIds" method and/or retrieves any corresponding members from the cache. */
 798  
         protected Map<String,List<KimDelegationMemberImpl>> getStoredDelegationMembersForDelegationIds(List<String> delegationIds) {
 799  0
                 Map<String,List<KimDelegationMemberImpl>> finalResults = new HashMap<String,List<KimDelegationMemberImpl>>();
 800  0
                 Set<String> uncachedDelegationIds = new HashSet<String>();
 801  0
                 boolean idListWasNullOrEmpty = (delegationIds == null || delegationIds.isEmpty());
 802  0
                 if (idListWasNullOrEmpty) { delegationIds = Collections.singletonList(null); }
 803  
                 
 804  
                 // Retrieve any existing Lists from the cache.
 805  0
                 for (String delegationId : delegationIds) {
 806  0
                         List<KimDelegationMemberImpl> tempMembers = (List<KimDelegationMemberImpl>) getCacheAdministrator().getFromCache(
 807  
                                         getDelegationMemberListCacheKey(RoleDaoAction.DELEGATION_MEMBERS_FOR_DELEGATION_IDS, delegationId, null, null), getRefreshPeriodInSeconds());
 808  0
                         if (tempMembers != null) {
 809  0
                                 finalResults.put(delegationId, tempMembers);
 810  
                         } else {
 811  0
                                 uncachedDelegationIds.add(delegationId);
 812  
                         }
 813  0
                 }
 814  
                 
 815  
                 // Retrieve and cache any uncached results. If the initial delegation ID List was null or empty, then also cache a List holding all the results.
 816  0
                 if (!uncachedDelegationIds.isEmpty()) {
 817  0
                         List<String> uncachedIdsList = (idListWasNullOrEmpty) ? new ArrayList<String>() : new ArrayList<String>(uncachedDelegationIds);
 818  
                         
 819  0
                         Map<String,List<KimDelegationMemberImpl>> tempMemberMap = roleDao.getDelegationMembersForDelegationIds(uncachedIdsList);
 820  0
                         List<KimDelegationMemberImpl> allMembers = new ArrayList<KimDelegationMemberImpl>();
 821  
                         
 822  0
                         for (Map.Entry<String,List<KimDelegationMemberImpl>> tempMemberEntry : tempMemberMap.entrySet()) {
 823  0
                                 getCacheAdministrator().putInCache(getDelegationMemberListCacheKey(RoleDaoAction.DELEGATION_MEMBERS_FOR_DELEGATION_IDS,
 824  
                                                 tempMemberEntry.getKey(), null, null), tempMemberEntry.getValue(), DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 825  0
                                 for (KimDelegationMemberImpl tempMember : tempMemberEntry.getValue()) {
 826  0
                                         addKimDelegationMemberImplToCache(tempMember);
 827  
                                 }
 828  0
                                 if (idListWasNullOrEmpty) {
 829  0
                                         allMembers.addAll(tempMemberEntry.getValue());
 830  
                                 }
 831  0
                                 finalResults.put(tempMemberEntry.getKey(), tempMemberEntry.getValue());
 832  
                         }
 833  
                         
 834  0
                         if (idListWasNullOrEmpty) {
 835  0
                                 getCacheAdministrator().putInCache(getDelegationMemberListCacheKey(RoleDaoAction.DELEGATION_MEMBERS_FOR_DELEGATION_IDS,
 836  
                                                 null, null, null), allMembers, DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 837  
                         }
 838  
                 }
 839  
                 
 840  0
                 return finalResults;
 841  
         }
 842  
         
 843  
         protected void addKimDelegationMemberImplToCache(KimDelegationMemberImpl delegationMember) {
 844  0
                 if (delegationMember != null) {
 845  0
                         getCacheAdministrator().putInCache(getDelegationMemberCacheKey(delegationMember.getDelegationMemberId()),
 846  
                                         delegationMember, DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 847  0
                         getCacheAdministrator().putInCache(getDelegationMemberByDelegationAndIdCacheKey(delegationMember.getDelegationId(),
 848  
                                         delegationMember.getDelegationMemberId()), delegationMember, DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 849  
                 }
 850  0
         }
 851  
         
 852  
         protected void addKimDelegationMemberImplListByMemberAndDelegationIdToCache(
 853  
                         List<KimDelegationMemberImpl> memberList, String memberId, String delegationId) {
 854  0
                 if (memberList != null) {
 855  0
                         getCacheAdministrator().putInCache(getDelegationMemberListByMemberAndDelegationIdCacheKey(memberId, delegationId),
 856  
                                         memberList, DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 857  
                 }
 858  0
         }
 859  
         
 860  
         protected KimDelegationMemberImpl getDelegationMemberFromCache(String delegationMemberId) {
 861  0
                 return (KimDelegationMemberImpl)getCacheAdministrator().getFromCache(getDelegationMemberCacheKey(delegationMemberId), getRefreshPeriodInSeconds());
 862  
         }
 863  
         
 864  
         protected KimDelegationMemberImpl getDelegationMemberByDelegationAndIdFromCache(String delegationId, String delegationMemberId) {
 865  0
                 return (KimDelegationMemberImpl)getCacheAdministrator().getFromCache(getDelegationMemberByDelegationAndIdCacheKey(delegationId,delegationMemberId), getRefreshPeriodInSeconds());
 866  
         }
 867  
         
 868  
         protected List<KimDelegationMemberImpl> getDelegationMemberListByMemberAndDelegationIdFromCache(String memberId, String delegationId) {
 869  0
                 return (List<KimDelegationMemberImpl>)
 870  
                                 getCacheAdministrator().getFromCache(getDelegationMemberListByMemberAndDelegationIdCacheKey(memberId, delegationId), getRefreshPeriodInSeconds());
 871  
         }
 872  
         
 873  
         public void flushInternalDelegationMemberCache() {
 874  0
                 getCacheAdministrator().flushGroup(DELEGATION_MEMBER_IMPL_CACHE_GROUP);
 875  0
         }
 876  
         
 877  
         /**
 878  
          * Retrieves a KimDelegationMemberImpl object by its ID. If the delegation member already exists in the cache, this method will return the cached
 879  
          * version; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 880  
          */
 881  
     protected KimDelegationMemberImpl getKimDelegationMemberImpl( String delegationMemberId ) {
 882  0
             if (StringUtils.isBlank(delegationMemberId)) {
 883  0
                     return null;
 884  
             }
 885  
             
 886  
             // If the KimDelegationMemberImpl exists in the cache, return the cached one.
 887  0
             KimDelegationMemberImpl tempDelegationMember = getDelegationMemberFromCache(delegationMemberId);
 888  0
             if (tempDelegationMember != null) {
 889  0
                     return tempDelegationMember;
 890  
             }
 891  
             // Otherwise, retrieve it normally.
 892  0
             tempDelegationMember = (KimDelegationMemberImpl)getBusinessObjectService().findByPrimaryKey( KimDelegationMemberImpl.class,
 893  
                             Collections.singletonMap(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMemberId) );
 894  0
             addKimDelegationMemberImplToCache(tempDelegationMember);
 895  0
             return tempDelegationMember;
 896  
     }
 897  
 
 898  
     /**
 899  
          * Retrieves a KimDelegationMemberImpl object by its ID and the ID of the delegation it belongs to. If the delegation member exists in the cache,
 900  
          * this method will return the cached one; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 901  
          */
 902  
         protected KimDelegationMemberImpl getKimDelegationMemberImplByDelegationAndId(String delegationId, String delegationMemberId) {
 903  0
                 if (StringUtils.isBlank(delegationId) || StringUtils.isBlank(delegationMemberId)) {
 904  0
                     return null;
 905  
             }
 906  
             
 907  
             // If the KimDelegationMemberImpl exists in the cache, return the cached one.
 908  0
             KimDelegationMemberImpl tempDelegationMember = getDelegationMemberByDelegationAndIdFromCache(delegationId, delegationMemberId);
 909  0
             if (tempDelegationMember != null) {
 910  0
                     return tempDelegationMember;
 911  
             }
 912  
             // Otherwise, retrieve it normally.
 913  0
             Map<String,String> searchCriteria = new HashMap<String,String>();
 914  0
             searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId);
 915  0
             searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMemberId);
 916  0
             List<KimDelegationMemberImpl> memberList =
 917  
                     (List<KimDelegationMemberImpl>) getBusinessObjectService().findMatching(KimDelegationMemberImpl.class, searchCriteria);
 918  0
             if (memberList != null && !memberList.isEmpty()) {
 919  0
                     tempDelegationMember = memberList.get(0);
 920  0
                     addKimDelegationMemberImplToCache(tempDelegationMember);
 921  
             }
 922  0
             return tempDelegationMember;
 923  
         }
 924  
     
 925  
         /**
 926  
          * Retrieves a KimDelegationMemberImpl List by (principal/group/role) member ID and delegation ID. If the List already exists in the cache,
 927  
          * this method will return the cached one; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 928  
          */
 929  
         protected List<KimDelegationMemberImpl> getKimDelegationMemberImplListByMemberAndDelegationId(String memberId, String delegationId) {
 930  
                 // If the KimDelegationMemberImpl List exists in the cache, return the cached one.
 931  0
             List<KimDelegationMemberImpl> memberList = getDelegationMemberListByMemberAndDelegationIdFromCache(memberId, delegationId);
 932  0
             if (memberList != null) {
 933  0
                     return memberList;
 934  
             }
 935  
                 
 936  
             // Otherwise, retrieve it normally.
 937  0
             Map<String,String> searchCriteria = new HashMap<String,String>();
 938  0
                 searchCriteria.put(KimConstants.PrimaryKeyConstants.MEMBER_ID, memberId);
 939  0
             searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId);
 940  0
             List<KimDelegationMemberImpl> tempList =
 941  
                     (List<KimDelegationMemberImpl>)getBusinessObjectService().findMatching(KimDelegationMemberImpl.class, searchCriteria);
 942  0
             if (tempList != null && !tempList.isEmpty()) {
 943  0
                     memberList = new ArrayList<KimDelegationMemberImpl>();
 944  0
                     memberList.addAll(tempList);
 945  0
                     addKimDelegationMemberImplListByMemberAndDelegationIdToCache(memberList, memberId, delegationId);
 946  
             }
 947  0
                 return memberList;
 948  
         }
 949  
         
 950  
         public void flushInternalRoleCache() {
 951  0
             getCacheAdministrator().flushGroup(ROLE_IMPL_CACHE_GROUP);
 952  0
     }
 953  
         
 954  
         public RoleMemberCompleteInfo findRoleMemberCompleteInfo(String roleMemberId){
 955  0
             Map<String, String> fieldValues = new HashMap<String, String>();
 956  0
             fieldValues.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId);
 957  0
             List<RoleMemberCompleteInfo> roleMemberInfos = findRoleMembersCompleteInfo(fieldValues);
 958  0
             if(roleMemberInfos!=null && roleMemberInfos.size()>0)
 959  0
                     return roleMemberInfos.get(0);
 960  0
             return null;
 961  
     }
 962  
         
 963  
         public List<RoleMemberCompleteInfo> findRoleMembersCompleteInfo(Map<String, String> fieldValues){
 964  0
             List<RoleMemberCompleteInfo> roleMembersCompleteInfos = new ArrayList<RoleMemberCompleteInfo>();
 965  
             RoleMemberCompleteInfo roleMembersCompleteInfo;
 966  0
             List<RoleMemberImpl> roleMembers = (List<RoleMemberImpl>)getLookupService().findCollectionBySearchHelper(
 967  
                                 RoleMemberImpl.class, fieldValues, true);
 968  0
             for(RoleMemberImpl roleMember: roleMembers){
 969  0
                     roleMembersCompleteInfo = roleMember.toSimpleInfo();
 970  0
                         Object member = getMember(roleMembersCompleteInfo.getMemberTypeCode(), roleMembersCompleteInfo.getMemberId());
 971  0
                         roleMembersCompleteInfo.setMemberName(getMemberName(member));
 972  0
                         roleMembersCompleteInfo.setMemberNamespaceCode(getMemberNamespaceCode(member));
 973  0
                         roleMembersCompleteInfo.setRoleRspActions(getRoleMemberResponsibilityActionInfo(roleMember.getRoleMemberId()));
 974  0
                         roleMembersCompleteInfos.add(roleMembersCompleteInfo);
 975  0
             }
 976  0
             return roleMembersCompleteInfos;
 977  
     }
 978  
         
 979  
         public List<RoleResponsibilityActionInfo> getRoleMemberResponsibilityActionInfo(String roleMemberId){
 980  0
                 Map<String, String> criteria = new HashMap<String, String>(1);                
 981  0
                 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId);
 982  0
                 List<RoleResponsibilityActionImpl> responsibilityImpls = (List<RoleResponsibilityActionImpl>)
 983  
                         getBusinessObjectService().findMatching(RoleResponsibilityActionImpl.class, criteria);
 984  0
                 List<RoleResponsibilityActionInfo> roleResponsibilityActionInfos = new ArrayList<RoleResponsibilityActionInfo>();
 985  
                 RoleResponsibilityActionInfo roleResponsibilityActionInfo;
 986  0
                 for(RoleResponsibilityActionImpl responsibilityActionImpl: responsibilityImpls){
 987  0
                         roleResponsibilityActionInfo = new RoleResponsibilityActionInfo();
 988  0
                         KimCommonUtilsInternal.copyProperties(roleResponsibilityActionInfo, responsibilityActionImpl);
 989  0
                         roleResponsibilityActionInfos.add(roleResponsibilityActionInfo);
 990  
                 }
 991  0
                 return roleResponsibilityActionInfos;
 992  
         }
 993  
         
 994  
         public List<DelegateMemberCompleteInfo> findDelegateMembersCompleteInfo(final Map<String, String> fieldValues){
 995  0
             List<DelegateMemberCompleteInfo> delegateMembersCompleteInfo = new ArrayList<DelegateMemberCompleteInfo>();
 996  
             DelegateMemberCompleteInfo delegateMemberCompleteInfo;
 997  0
             List<KimDelegationImpl> delegations = (List<KimDelegationImpl>)getLookupService().findCollectionBySearchHelper(
 998  
                                 KimDelegationImpl.class, fieldValues, true);
 999  0
             if(delegations!=null && !delegations.isEmpty()){
 1000  0
                     Map<String, String> delegationMemberFieldValues = new HashMap<String, String>();
 1001  0
                     for(String key: fieldValues.keySet()){
 1002  0
                             if(key.startsWith(KimConstants.KimUIConstants.MEMBER_ID_PREFIX)){
 1003  0
                                     delegationMemberFieldValues.put(
 1004  
                                                     key.substring(key.indexOf(
 1005  
                                                     KimConstants.KimUIConstants.MEMBER_ID_PREFIX)+KimConstants.KimUIConstants.MEMBER_ID_PREFIX.length()), 
 1006  
                                                     fieldValues.get(key));
 1007  
                             }
 1008  
                     }
 1009  0
                         StringBuffer memberQueryString = new StringBuffer();
 1010  0
                     for(KimDelegationImpl delegation: delegations)
 1011  0
                             memberQueryString.append(delegation.getDelegationId()+KimConstants.KimUIConstants.OR_OPERATOR);
 1012  0
                     delegationMemberFieldValues.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, 
 1013  
                                     KimCommonUtilsInternal.stripEnd(memberQueryString.toString(), KimConstants.KimUIConstants.OR_OPERATOR));
 1014  0
                     List<KimDelegationMemberImpl> delegateMembers = (List<KimDelegationMemberImpl>)getLookupService().findCollectionBySearchHelper(
 1015  
                                         KimDelegationMemberImpl.class, delegationMemberFieldValues, true);
 1016  
                     KimDelegationImpl delegationTemp;
 1017  0
                     for(KimDelegationMemberImpl delegateMember: delegateMembers){
 1018  0
                             delegateMemberCompleteInfo = delegateMember.toSimpleInfo();
 1019  0
                             delegationTemp = getDelegationImpl(delegations, delegateMember.getDelegationId());
 1020  0
                             delegateMemberCompleteInfo.setRoleId(delegationTemp.getRoleId());
 1021  0
                             delegateMemberCompleteInfo.setDelegationTypeCode(delegationTemp.getDelegationTypeCode());
 1022  0
                                 Object member = getMember(delegateMemberCompleteInfo.getMemberTypeCode(), delegateMemberCompleteInfo.getMemberId());
 1023  0
                                 delegateMemberCompleteInfo.setMemberName(getMemberName(member));
 1024  0
                                 delegateMemberCompleteInfo.setMemberNamespaceCode(getMemberNamespaceCode(member));
 1025  0
                                 delegateMembersCompleteInfo.add(delegateMemberCompleteInfo);
 1026  0
                     }
 1027  
 
 1028  
             }
 1029  0
             return delegateMembersCompleteInfo;
 1030  
     }
 1031  
         
 1032  
         protected KimDelegationImpl getDelegationImpl(List<KimDelegationImpl> delegations, String delegationId){
 1033  0
             if(StringUtils.isEmpty(delegationId) || delegations==null)
 1034  0
                     return null;
 1035  0
             for(KimDelegationImpl delegation: delegations){
 1036  0
                     if(StringUtils.equals(delegation.getDelegationId(), delegationId))
 1037  0
                             return delegation;
 1038  
             }
 1039  0
             return null;
 1040  
     }
 1041  
         
 1042  
         protected Object getMember(String memberTypeCode, String memberId){
 1043  0
                 if ( StringUtils.isBlank(memberId) ) {
 1044  0
                         return null;
 1045  
                 }
 1046  0
         if(KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE.equals(memberTypeCode)){
 1047  0
                 return getIdentityManagementService().getPrincipal(memberId);
 1048  0
         } else if(KimConstants.KimUIConstants.MEMBER_TYPE_GROUP_CODE.equals(memberTypeCode)){
 1049  0
                 return getIdentityManagementService().getGroup(memberId);
 1050  0
         } else if(KimConstants.KimUIConstants.MEMBER_TYPE_ROLE_CODE.equals(memberTypeCode)){
 1051  0
                 return getRoleImpl(memberId);
 1052  
         }
 1053  0
         return null;
 1054  
     }
 1055  
         
 1056  
         protected String getMemberName(Object member){
 1057  0
         if( member == null ) {
 1058  0
                 return "";
 1059  
         }
 1060  0
         if ( member instanceof PrincipalContract ) {
 1061  0
                 return ((PrincipalContract)member).getPrincipalName();
 1062  
         }
 1063  0
         if ( member instanceof Group ) {
 1064  0
                 return ((Group)member).getName();
 1065  
         }
 1066  0
         if ( member instanceof Role ) {
 1067  0
                 return ((Role)member).getRoleName();
 1068  
         }
 1069  0
         return member.toString();
 1070  
     }
 1071  
         
 1072  
         protected String getMemberNamespaceCode(Object member){
 1073  0
         if( member == null ) {
 1074  0
                 return "";
 1075  
         }
 1076  0
         if ( member instanceof PrincipalContract ) {
 1077  0
                 return "";
 1078  
         }
 1079  0
         if ( member instanceof Group ) {
 1080  0
                 return ((Group)member).getNamespaceCode();
 1081  
         }
 1082  0
         if ( member instanceof Role ) {
 1083  0
                 return ((Role)member).getNamespaceCode();
 1084  
         }
 1085  0
         return "";
 1086  
     }
 1087  
         
 1088  
         protected RoleImpl getRoleImpl(String roleId) {
 1089  0
                 if ( StringUtils.isBlank( roleId ) ) {
 1090  0
                         return null;
 1091  
                 }
 1092  
                 // check for a non-null result in the cache, return it if found
 1093  0
                 RoleImpl cachedResult = getRoleFromCache( roleId );
 1094  0
                 if ( cachedResult != null ) {
 1095  0
                         return cachedResult;
 1096  
                 }
 1097  
                 // otherwise, run the query
 1098  0
                 RoleImpl result = (RoleImpl)getBusinessObjectService().findBySinglePrimaryKey(RoleImpl.class, roleId);
 1099  0
                 addRoleImplToCache( result );
 1100  0
                 return result;
 1101  
         }
 1102  
         
 1103  
         protected KimDelegationImpl getDelegationOfType(String roleId, String delegationTypeCode){
 1104  0
             List<KimDelegationImpl> roleDelegations = getRoleDelegations(roleId);
 1105  0
         if(isDelegationPrimary(delegationTypeCode))
 1106  0
             return getPrimaryDelegation(roleId, roleDelegations);
 1107  
         else
 1108  0
             return getSecondaryDelegation(roleId, roleDelegations);
 1109  
     }
 1110  
         
 1111  
         private KimDelegationImpl getSecondaryDelegation(String roleId, List<KimDelegationImpl> roleDelegations){
 1112  0
         KimDelegationImpl secondaryDelegation = null;
 1113  0
         RoleImpl roleImpl = getRoleImpl(roleId);
 1114  0
         for(KimDelegationImpl delegation: roleDelegations){
 1115  0
             if(isDelegationSecondary(delegation.getDelegationTypeCode()))
 1116  0
                 secondaryDelegation = delegation;
 1117  
         }
 1118  0
         if(secondaryDelegation==null){
 1119  0
             secondaryDelegation = new KimDelegationImpl();
 1120  0
             secondaryDelegation.setRoleId(roleId);
 1121  0
             secondaryDelegation.setDelegationId(getNewDelegationId());
 1122  0
             secondaryDelegation.setDelegationTypeCode(KEWConstants.DELEGATION_SECONDARY);
 1123  0
             secondaryDelegation.setKimTypeId(roleImpl.getKimTypeId());
 1124  
         }
 1125  0
         return secondaryDelegation;
 1126  
     }
 1127  
         
 1128  
         protected KimDelegationImpl getPrimaryDelegation(String roleId, List<KimDelegationImpl> roleDelegations){
 1129  0
         KimDelegationImpl primaryDelegation = null;
 1130  0
         RoleImpl roleImpl = getRoleImpl(roleId);
 1131  0
         for(KimDelegationImpl delegation: roleDelegations){
 1132  0
             if(isDelegationPrimary(delegation.getDelegationTypeCode()))
 1133  0
                 primaryDelegation = delegation;
 1134  
         }
 1135  0
         if(primaryDelegation==null){
 1136  0
             primaryDelegation = new KimDelegationImpl();
 1137  0
             primaryDelegation.setRoleId(roleId);
 1138  0
             primaryDelegation.setDelegationId(getNewDelegationId());
 1139  0
             primaryDelegation.setDelegationTypeCode(KEWConstants.DELEGATION_PRIMARY);
 1140  0
             primaryDelegation.setKimTypeId(roleImpl.getKimTypeId());
 1141  
         }
 1142  0
         return primaryDelegation;
 1143  
     }
 1144  
         
 1145  
         protected RoleMemberImpl matchingMemberRecord( List<RoleMemberImpl> roleMembers, String memberId, String memberTypeCode, AttributeSet qualifier ) {
 1146  0
                 for ( RoleMemberImpl rm : roleMembers ) {
 1147  0
                         if ( doesMemberMatch( rm, memberId, memberTypeCode, qualifier ) ) {
 1148  0
                                 return rm;
 1149  
                         }
 1150  
                 }
 1151  0
                 return null;
 1152  
         }
 1153  
         
 1154  
         protected boolean isDelegationPrimary(String delegationTypeCode){
 1155  0
         return KEWConstants.DELEGATION_PRIMARY.equals(delegationTypeCode);
 1156  
     }
 1157  
         
 1158  
         protected boolean isDelegationSecondary(String delegationTypeCode){
 1159  0
         return KEWConstants.DELEGATION_SECONDARY.equals(delegationTypeCode);
 1160  
     }
 1161  
         
 1162  
         
 1163  
         private List<KimDelegationImpl> getRoleDelegations(String roleId){
 1164  0
                 if(roleId==null)
 1165  0
                         return new ArrayList<KimDelegationImpl>();
 1166  0
                 return getStoredDelegationImplsForRoleIds(Collections.singletonList(roleId));
 1167  
 
 1168  
         }
 1169  
         
 1170  
         protected RoleImpl getRoleImplByName( String namespaceCode, String roleName ) {
 1171  0
                 if ( StringUtils.isBlank( namespaceCode )
 1172  
                                 || StringUtils.isBlank( roleName ) ) {
 1173  0
                         return null;
 1174  
                 }
 1175  
                 // check for a non-null result in the cache, return it if found
 1176  0
                 RoleImpl cachedResult = getRoleFromCache( namespaceCode, roleName );
 1177  0
                 if ( cachedResult != null ) {
 1178  0
                         return cachedResult;
 1179  
                 }
 1180  0
                 AttributeSet criteria = new AttributeSet();
 1181  0
                 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
 1182  0
                 criteria.put(KimConstants.UniqueKeyConstants.ROLE_NAME, roleName);
 1183  0
                 criteria.put(KNSPropertyConstants.ACTIVE, "Y");
 1184  
                 // while this is not actually the primary key - there will be at most one row with these criteria
 1185  0
                 RoleImpl result = (RoleImpl)getBusinessObjectService().findByPrimaryKey(RoleImpl.class, criteria);
 1186  0
                 addRoleImplToCache( result );
 1187  0
                 return result;
 1188  
         }
 1189  
         
 1190  
         protected boolean doAnyMemberRecordsMatch( List<RoleMemberImpl> roleMembers, String memberId, String memberTypeCode, AttributeSet qualifier ) {
 1191  0
                 for ( RoleMemberImpl rm : roleMembers ) {
 1192  0
                         if ( doesMemberMatch( rm, memberId, memberTypeCode, qualifier ) ) {
 1193  0
                                 return true;
 1194  
                         }
 1195  
                 }
 1196  0
                 return false;
 1197  
         }
 1198  
         
 1199  
         protected boolean doesMemberMatch( RoleMemberImpl roleMember, String memberId, String memberTypeCode, AttributeSet qualifier ) {
 1200  0
                 if ( roleMember.getMemberId().equals( memberId ) && roleMember.getMemberTypeCode().equals( memberTypeCode ) ) {
 1201  
                         // member ID/type match
 1202  0
                     AttributeSet roleQualifier = roleMember.getQualifier();
 1203  0
                     if ( (qualifier == null || qualifier.isEmpty())
 1204  
                                     && (roleQualifier == null || roleQualifier.isEmpty()) ) {
 1205  0
                             return true; // blank qualifier match
 1206  
                     } else {
 1207  0
                             if ( qualifier != null && roleQualifier != null && qualifier.equals( roleQualifier ) ) {
 1208  0
                                     return true; // qualifier match
 1209  
                             }
 1210  
                     }
 1211  
                 }
 1212  0
                 return false;
 1213  
         }
 1214  
 
 1215  
         /**
 1216  
          * 
 1217  
          * This method tests to see if assigning a role to another role will create a circular reference.
 1218  
          * The Role is checked to see if it is a member (direct or nested) of the role to be assigned as a member.
 1219  
          * 
 1220  
          * @param newMemberId
 1221  
          * @param role
 1222  
          * @return true  - assignment is allowed, no circular reference will be created.
 1223  
          *         false - illegal assignment, it will create a circular membership
 1224  
          */
 1225  
         protected boolean checkForCircularRoleMembership( String newMemberId, RoleImpl role ) {
 1226  
                 // get all nested role members that are of type role
 1227  0
                 Set<String> newRoleMemberIds = getRoleTypeRoleMemberIds(newMemberId);
 1228  0
                 if (newRoleMemberIds.contains(role.getRoleId())){
 1229  0
                                         return false;
 1230  
                 }
 1231  0
                 return true;
 1232  
         }
 1233  
         
 1234  
         // TODO: pulling attribute IDs repeatedly is inefficient - consider caching the entire list as a map
 1235  
         @SuppressWarnings("unchecked")
 1236  
         protected String getKimAttributeId( String attributeName ) {
 1237  0
                 String result = null;
 1238  0
                 Map<String,Object> critieria = new HashMap<String,Object>( 1 );
 1239  0
                 critieria.put( "attributeName", attributeName );
 1240  0
                 Collection<KimAttributeBo> defs = getBusinessObjectService().findMatching( KimAttributeBo.class, critieria );
 1241  0
                 if(CollectionUtils.isNotEmpty(defs)) {
 1242  0
                         result = defs.iterator().next().getId();
 1243  
                 }
 1244  0
                 return result;
 1245  
         }
 1246  
         
 1247  
     /**
 1248  
          * @return the applicationRoleTypeCache
 1249  
          */
 1250  
         protected Map<String, Boolean> getApplicationRoleTypeCache() {
 1251  0
                 return this.applicationRoleTypeCache;
 1252  
         }
 1253  
         /**
 1254  
          * @return the roleTypeServiceCache
 1255  
          */
 1256  
         protected Map<String, KimRoleTypeService> getRoleTypeServiceCache() {
 1257  0
                 return this.roleTypeServiceCache;
 1258  
         }
 1259  
 
 1260  
         /**
 1261  
          * @return the delegationTypeServiceCache
 1262  
          */
 1263  
         protected Map<String, KimDelegationTypeService> getDelegationTypeServiceCache() {
 1264  0
                 return this.delegationTypeServiceCache;
 1265  
         }
 1266  
         protected String getRoleCacheKey( String roleId ) {
 1267  0
             return ROLE_IMPL_CACHE_PREFIX + roleId;
 1268  
     }
 1269  
 
 1270  
     protected String getRoleByNameCacheKey( String namespaceCode, String roleName ) {
 1271  0
             return ROLE_IMPL_BY_NAME_CACHE_PREFIX + namespaceCode + "-" + roleName;
 1272  
             }
 1273  
 
 1274  
     protected void addRoleImplToCache( RoleImpl role ) {
 1275  0
             if (role != null) {
 1276  0
                     getCacheAdministrator().putInCache(getRoleCacheKey(role.getRoleId()), role, ROLE_IMPL_CACHE_GROUP);
 1277  0
                     getCacheAdministrator().putInCache(getRoleByNameCacheKey(role.getNamespaceCode(),role.getRoleName()), role, ROLE_IMPL_CACHE_GROUP);
 1278  
                     }
 1279  0
             }
 1280  
 
 1281  
     protected RoleImpl getRoleFromCache( String roleId ) {
 1282  0
             return (RoleImpl)getCacheAdministrator().getFromCache(getRoleCacheKey(roleId), getRefreshPeriodInSeconds());
 1283  
     }
 1284  
 
 1285  
     protected RoleImpl getRoleFromCache( String namespaceCode, String roleName ) {
 1286  0
             return (RoleImpl)getCacheAdministrator().getFromCache(getRoleByNameCacheKey(namespaceCode,roleName), getRefreshPeriodInSeconds());
 1287  
     }
 1288  
     
 1289  
     protected String getNewDelegationId(){
 1290  0
             SequenceAccessorService sas = getSequenceAccessorService();
 1291  0
             Long nextSeq = sas.getNextAvailableSequenceNumber(
 1292  
                 KimConstants.SequenceNames.KRIM_DLGN_ID_S,
 1293  
                 KimDelegationImpl.class);
 1294  0
         return nextSeq.toString();
 1295  
     }
 1296  
 
 1297  
     protected String getNewAttributeDataId(){
 1298  0
                 SequenceAccessorService sas = getSequenceAccessorService();                
 1299  0
                 Long nextSeq = sas.getNextAvailableSequenceNumber(
 1300  
                                 KimConstants.SequenceNames.KRIM_ATTR_DATA_ID_S, 
 1301  
                                 RoleMemberAttributeDataImpl.class );
 1302  0
                 return nextSeq.toString();
 1303  
     }
 1304  
     
 1305  
     protected String getNewDelegationMemberId(){
 1306  0
             SequenceAccessorService sas = getSequenceAccessorService();
 1307  0
             Long nextSeq = sas.getNextAvailableSequenceNumber(
 1308  
                 KimConstants.SequenceNames.KRIM_DLGN_MBR_ID_S,
 1309  
                 KimDelegationImpl.class);
 1310  0
         return nextSeq.toString();
 1311  
     }
 1312  
     
 1313  
     protected BusinessObjectService getBusinessObjectService() {
 1314  0
                 if ( businessObjectService == null ) {
 1315  0
                         businessObjectService = KNSServiceLocator.getBusinessObjectService();
 1316  
                 }
 1317  0
                 return businessObjectService;
 1318  
         }
 1319  
     
 1320  
     /**
 1321  
          * @return the lookupService
 1322  
          */
 1323  
     protected LookupService getLookupService() {
 1324  0
                 if(lookupService == null) {
 1325  0
                         lookupService = KNSServiceLocatorWeb.getLookupService();
 1326  
                 }
 1327  0
                 return lookupService;
 1328  
         }
 1329  
     
 1330  
     protected RiceCacheAdministrator getCacheAdministrator() {
 1331  0
                 if ( cacheAdministrator == null ) {
 1332  0
                         cacheAdministrator = KsbApiServiceLocator.getCacheAdministrator();
 1333  
                 }
 1334  0
                 return cacheAdministrator;
 1335  
     }
 1336  
     
 1337  
     protected IdentityManagementService getIdentityManagementService() {
 1338  0
                 if ( identityManagementService == null ) {
 1339  0
                         identityManagementService = KimApiServiceLocator.getIdentityManagementService();
 1340  
                 }
 1341  
 
 1342  0
                 return identityManagementService;
 1343  
         }
 1344  
 
 1345  
         protected SequenceAccessorService getSequenceAccessorService() {
 1346  0
                 if ( sequenceAccessorService == null ) {
 1347  0
                         sequenceAccessorService = KNSServiceLocator.getSequenceAccessorService();
 1348  
                 }
 1349  0
                 return sequenceAccessorService;
 1350  
         }
 1351  
         
 1352  
         protected ResponsibilityInternalService getResponsibilityInternalService() {
 1353  0
                 if ( responsibilityInternalService == null ) {
 1354  0
                         responsibilityInternalService = KIMServiceLocatorInternal.getResponsibilityInternalService();
 1355  
                 }
 1356  0
                 return responsibilityInternalService;
 1357  
         }
 1358  
         
 1359  
         protected IdentityManagementNotificationService getIdentityManagementNotificationService() {
 1360  0
         return (IdentityManagementNotificationService) KsbApiServiceLocator.getMessageHelper().getServiceAsynchronously(new QName("KIM", "kimIdentityManagementNotificationService"));
 1361  
     }
 1362  
         
 1363  
         /**
 1364  
          * An internal helper class for encapsulating the information related to generating a key for a RoleMemberImpl list. 
 1365  
          * 
 1366  
          * @author Kuali Rice Team (rice.collab@kuali.org)
 1367  
          */
 1368  0
         private class RoleMemberCacheKeyHelper {
 1369  
                 private final RoleDaoAction ROLE_DAO_ACTION;
 1370  
                 private final String ROLE_ID;
 1371  
                 private final String PRINCIPAL_ID;
 1372  
                 private final String GROUP_ID;
 1373  
                 private final String MEMBER_TYPE_CODE;
 1374  
                 private String cacheKey;
 1375  
                 
 1376  0
                 private RoleMemberCacheKeyHelper(RoleDaoAction roleDaoAction, String roleId, String principalId, String groupId, String memberTypeCode) {
 1377  0
                         this.ROLE_DAO_ACTION = roleDaoAction;
 1378  0
                         this.ROLE_ID = roleId;
 1379  0
                         this.PRINCIPAL_ID = principalId;
 1380  0
                         this.GROUP_ID = groupId;
 1381  0
                         this.MEMBER_TYPE_CODE = memberTypeCode;
 1382  0
                 }
 1383  
                 
 1384  
                 private String getCacheKey() {
 1385  0
                         if (this.cacheKey == null) {
 1386  0
                                 this.cacheKey = getRoleMemberListCacheKey(ROLE_DAO_ACTION, ROLE_ID, PRINCIPAL_ID, GROUP_ID, MEMBER_TYPE_CODE);
 1387  
                         }
 1388  0
                         return this.cacheKey;
 1389  
                 }
 1390  
         }
 1391  
         /**
 1392  
          * @return the roleDao
 1393  
          */
 1394  
         public KimRoleDao getRoleDao() {
 1395  0
                 return this.roleDao;
 1396  
         }
 1397  
 
 1398  
         /**
 1399  
          * @param roleDao the roleDao to set
 1400  
          */
 1401  
         public void setRoleDao(KimRoleDao roleDao) {
 1402  0
                 this.roleDao = roleDao;
 1403  0
         }
 1404  
         
 1405  
     public int getRefreshPeriodInSeconds() {
 1406  
         try {
 1407  0
                 return (int)(new Integer(ConfigContext.getCurrentContextConfig().getProperty(KimConstants.CacheRefreshPeriodSeconds.KIM_CACHE_ROLE_REFRESH_PERIOD_SECONDS)));
 1408  0
         } catch (NumberFormatException e) {
 1409  
                     // The cache will never expire when refreshPeriod is set to -1
 1410  0
                     return -1;                        
 1411  
         }
 1412  
     }
 1413  
 }