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 }