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