Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright 2005-2012 The Kuali Foundation Licensed under the Educational Community License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.opensource.org/licenses/ecl2.php Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  
  package org.kuali.rice.kim.impl.role;
  
  
  import java.util.Date;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
  
  public class RoleServiceImpl extends RoleServiceBase implements RoleService {
      private static final Logger LOG = Logger.getLogger(RoleServiceImpl.class);
  
  
      private static Map<StringRoleDaoActionpopulateMemberTypeToRoleDaoActionMap() {
          Map<StringRoleDaoActionmap = new HashMap<StringRoleDaoAction>();
          return Collections.unmodifiableMap(map);
      }
  
  
      @Override
      public Role createRole(final Role rolethrows RiceIllegalArgumentExceptionRiceIllegalStateException {
          incomingParamCheck(role"role");
  
          if (StringUtils.isNotBlank(role.getId()) && getRole(role.getId()) != null) {
              throw new RiceIllegalStateException("the role to create already exists: " + role);
          }
          RoleBo bo = RoleBo.from(role);
          return RoleBo.to(getBusinessObjectService().save(bo));
      }
  
      @Override
      public Role updateRole(final Role rolethrows RiceIllegalArgumentExceptionRiceIllegalStateException {
          incomingParamCheck(role"role");
  
         RoleBo originalRole = getRoleBo(role.getId());
         if (StringUtils.isBlank(role.getId()) || originalRole == null) {
             throw new RiceIllegalStateException("the role does not exist: " + role);
         }
 
         RoleBo bo = RoleBo.from(role);
 
         RoleBo updatedRole = getBusinessObjectService().save(bo);
         if (originalRole.isActive()
                 && !updatedRole.isActive()) {
             KimImplServiceLocator.getRoleInternalService().roleInactivated(updatedRole.getId());
         }
         return RoleBo.to(updatedRole);
     }

    
This method tests to see if assigning a roleBo to another roleBo will create a circular reference. The Role is checked to see if it is a member (direct or nested) of the roleBo to be assigned as a member.

Parameters:
newMemberId
roleBo
Returns:
true - assignment is allowed, no circular reference will be created. false - illegal assignment, it will create a circular membership
 
     protected boolean checkForCircularRoleMembership(String newMemberIdRoleBo roleBo) {
         // get all nested roleBo members that are of type roleBo
         Set<StringnewRoleMemberIds = getRoleTypeRoleMemberIds(newMemberId);
         return !newRoleMemberIds.contains(roleBo.getId());
     }
 
     protected RoleMember findRoleMember(String roleMemberId) {
         final List<RoleMemberroleMembers = findRoleMembers(QueryByCriteria.Builder.fromPredicates(equal(..roleMemberId))).getResults();
         if (roleMembers != null && !roleMembers.isEmpty()) {
             return roleMembers.get(0);
         }
         return null;
     }
 
     @Override
         incomingParamCheck(queryByCriteria"queryByCriteria");
 
         GenericQueryResults<RoleMemberBoresults = getCriteriaLookupService().lookup(RoleMemberBo.classqueryByCriteria);
 
         RoleMemberQueryResults.Builder builder = RoleMemberQueryResults.Builder.create();
         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
         builder.setTotalRowCount(results.getTotalRowCount());
 
         final List<RoleMember.Builderims = new ArrayList<RoleMember.Builder>();
         for (RoleMemberBo bo : results.getResults()) {
             ims.add(RoleMember.Builder.create(bo));
         }
 
         builder.setResults(ims);
         return builder.build();
     }
 
     @Override
     public Set<StringgetRoleTypeRoleMemberIds(String roleIdthrows RiceIllegalArgumentException  {
         incomingParamCheck(roleId"roleId");
 
         Set<Stringresults = new HashSet<String>();
         getNestedRoleTypeMemberIds(roleIdresults);
         return Collections.unmodifiableSet(results);
     }
 
     @Override
     public List<StringgetMemberParentRoleIds(String memberTypeString memberIdthrows RiceIllegalStateException  {
         incomingParamCheck(memberType"memberType");
         incomingParamCheck(memberId"memberId");
 
         List<RoleMemberBoparentRoleMembers = getRoleDao().getRoleMembershipsForMemberId(memberTypememberId,
                 Collections.<StringString>emptyMap());
 
         List<StringparentRoleIds = new ArrayList<String>(parentRoleMembers.size());
         for (RoleMemberBo parentRoleMember : parentRoleMembers) {
             parentRoleIds.add(parentRoleMember.getRoleId());
         }
 
         return parentRoleIds;
     }
 
     @Override
         incomingParamCheck(roleMemberId"roleMemberId");
 
         Map<StringStringcriteria = new HashMap<StringString>(1);
         criteria.put(..roleMemberId);
 
         List<RoleResponsibilityActionBoresponsibilityActionBoList = (List<RoleResponsibilityActionBo>)
                 getBusinessObjectService().findMatching(RoleResponsibilityActionBo.classcriteria);
 
         List<RoleResponsibilityActionroleResponsibilityActionsList = new ArrayList<RoleResponsibilityAction>();
         for (RoleResponsibilityActionBo roleResponsibilityActionBo : responsibilityActionBoList) {
             RoleResponsibilityAction roleResponsibility = RoleResponsibilityActionBo.to(roleResponsibilityActionBo);
             roleResponsibilityActionsList.add(roleResponsibility);
         }
         return roleResponsibilityActionsList;
     }
 
     @Override
         incomingParamCheck(queryByCriteria"queryByCriteria");
 
         GenericQueryResults<DelegateMemberBoresults = getCriteriaLookupService().lookup(DelegateMemberBo.classqueryByCriteria);
 
         DelegateMemberQueryResults.Builder builder = DelegateMemberQueryResults.Builder.create();
         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
         builder.setTotalRowCount(results.getTotalRowCount());
 
         final List<DelegateMember.Builderims = new ArrayList<DelegateMember.Builder>();
         for (DelegateMemberBo bo : results.getResults()) {
             ims.add(DelegateMember.Builder.create(bo));
         }
 
         builder.setResults(ims);
         return builder.build();
     }
 
     @Override
     public Role getRole(String roleIdthrows RiceIllegalStateException  {
         incomingParamCheck(roleId"roleId");
 
         RoleBo roleBo = getRoleBo(roleId);
         if (roleBo == null) {
             return null;
         }
         return RoleBo.to(roleBo);
     }
 
     protected Map<StringRoleBogetRoleBoMap(Collection<StringroleIds) {
         Map<StringRoleBoresult;
         // check for a non-null result in the cache, return it if found
         if (roleIds.size() == 1) {
             String roleId = roleIds.iterator().next();
             RoleBo bo = getRoleBo(roleId);
             result = bo.isActive() ? Collections.singletonMap(roleIdbo) :  Collections.<StringRoleBo>emptyMap();
         } else {
             result = new HashMap<StringRoleBo>(roleIds.size());
             for (String roleId : roleIds) {
                 RoleBo bo = getRoleBo(roleId);
                 if (bo.isActive()) {
                     result.put(roleIdbo);
                 }
             }
         }
         return result;
     }
 
     @Override
     public List<RolegetRoles(List<StringroleIdsthrows RiceIllegalStateException  {
         if (CollectionUtils.isEmpty(roleIds)) {
             throw new RiceIllegalArgumentException("roleIds is null or empty");
         }
 
         Collection<RoleBoroleBos = getRoleBoMap(roleIds).values();
         List<Roleroles = new ArrayList<Role>(roleBos.size());
         for (RoleBo bo : roleBos) {
             roles.add(RoleBo.to(bo));
         }
         return Collections.unmodifiableList(roles);
     }
 
     @Override
     public Role getRoleByNamespaceCodeAndName(String namespaceCodeString roleNamethrows RiceIllegalStateException  {
         incomingParamCheck(namespaceCode"namespaceCode");
         incomingParamCheck(roleName"roleName");
 
         RoleBo roleBo = getRoleBoByName(namespaceCoderoleName);
         if (roleBo != null) {
             return RoleBo.to(roleBo);
         }
         return null;
     }
 
     @Override
     public String getRoleIdByNamespaceCodeAndName(String namespaceCodeString roleNamethrows RiceIllegalStateException  {
         incomingParamCheck(namespaceCode"namespaceCode");
         incomingParamCheck(roleName"roleName");
 
         Role role = getRoleByNamespaceCodeAndName(namespaceCoderoleName);
         if (role != null) {
             return role.getId();
         } else {
             return null;
         }
     }
 
     @Override
     public boolean isRoleActive(String roleIdthrows RiceIllegalStateException  {
         incomingParamCheck(roleId"roleId");
 
         RoleBo roleBo = getRoleBo(roleId);
         return roleBo != null && roleBo.isActive();
     }
 
     @Override
     public List<Map<StringString>> getRoleQualifersForPrincipalByRoleIds(String principalIdList<StringroleIds,
             Map<StringStringqualificationthrows RiceIllegalStateException  {
         incomingParamCheck(principalId"principalId");
         incomingParamCheck(roleIds"roleIds");
 
         List<Map<StringString>> results = new ArrayList<Map<StringString>>();
 
         List<RoleMemberBoroleMemberBoList = getStoredRoleMembersUsingExactMatchOnQualification(principalIdnull,
                 roleIdsqualification);
 
         Map<StringList<RoleMembership>> roleIdToMembershipMap = new HashMap<StringList<RoleMembership>>();
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
             // gather up the qualifier sets and the service they go with
             if (..equals(roleMemberBo.getType())) {
                 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId());
                 if (roleTypeService != null) {
                     List<RoleMembershiplas = roleIdToMembershipMap.get(roleMemberBo.getRoleId());
                     if (las == null) {
                         las = new ArrayList<RoleMembership>();
                         roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las);
                     }
                     RoleMembership mi = RoleMembership.Builder.create(
                             roleMemberBo.getRoleId(),
                             roleMemberBo.getId(),
                             roleMemberBo.getMemberId(),
                             roleMemberBo.getType(),
                             roleMemberBo.getAttributes()).build();
 
                     las.add(mi);
                 } else {
                     results.add(roleMemberBo.getAttributes());
                 }
             }
         }
         for (Map.Entry<StringList<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) {
             RoleTypeService roleTypeService = getRoleTypeService(entry.getKey());
             //it is possible that the the roleTypeService is coming from a remote application
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
             try {
                 List<RoleMembershipmatchingMembers = roleTypeService.getMatchingRoleMemberships(qualificationentry.getValue());
                 for (RoleMembership rmi : matchingMembers) {
                     results.add(rmi.getQualifier());
                 }
             } catch (Exception ex) {
                 .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex);
             }
         }
         return Collections.unmodifiableList(results);
     }
 
     @Override
             String namespaceCodeString roleNameMap<StringStringqualification)
             throws RiceIllegalStateException {
         incomingParamCheck(principalId"principalId");
         incomingParamCheck(namespaceCode"namespaceCode");
         incomingParamCheck(roleName"roleName");
 
         String roleId = getRoleIdByNamespaceCodeAndName(namespaceCoderoleName);
         if (roleId == null) {
             return Collections.emptyList();
         }
         return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId),
                 qualification);
     }
 
     @Override
             String namespaceCodeString roleNameMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(principalId"principalId");
         incomingParamCheck(namespaceCode"namespaceCode");
         incomingParamCheck(roleName"roleName");
 
         String roleId = getRoleIdByNamespaceCodeAndName(namespaceCoderoleName);
         if (roleId == null) {
             return new ArrayList<Map<StringString>>(0);
         }
         return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId),
                 qualification);
     }
 
     @Override
             List<StringroleIdsMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(principalId"principalId");
         incomingParamCheck(roleIds"roleIds");
 
 
         List<Map<StringString>> results = new ArrayList<Map<StringString>>();
 
         Map<StringRoleBoroleBosById = getRoleBoMap(roleIds);
 
         // get the person's groups
         List<StringgroupIds = getGroupService().getGroupIdsByPrincipalId(principalId);
         List<RoleMemberBoroleMemberBos = getStoredRoleMembersUsingExactMatchOnQualification(principalIdgroupIdsroleIdsqualification);
 
         Map<StringList<RoleMembership>> roleIdToMembershipMap = new HashMap<StringList<RoleMembership>>();
         for (RoleMemberBo roleMemberBo : roleMemberBos) {
             RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId());
             // gather up the qualifier sets and the service they go with
             if (..equals(roleMemberBo.getType())
                     || ..equals(roleMemberBo.getType())) {
                 if (roleTypeService != null) {
                     List<RoleMembershiplas = roleIdToMembershipMap.get(roleMemberBo.getRoleId());
                     if (las == null) {
                         las = new ArrayList<RoleMembership>();
                         roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las);
                     }
                     RoleMembership mi = RoleMembership.Builder.create(
                             roleMemberBo.getRoleId(),
                             roleMemberBo.getId(),
                             roleMemberBo.getMemberId(),
                             roleMemberBo.getType(),
                             roleMemberBo.getAttributes()).build();
 
                     las.add(mi);
                 } else {
                     results.add(roleMemberBo.getAttributes());
                 }
             } else if (..equals(roleMemberBo.getType())) {
                 // find out if the user has the role
                 // need to convert qualification using this role's service
                 Map<StringStringnestedQualification = qualification;
                 if (roleTypeService != null) {
                     RoleBo roleBo = roleBosById.get(roleMemberBo.getRoleId());
                     // pulling from here as the nested roleBo is not necessarily (and likely is not)
                     // in the roleBosById Map created earlier
                     RoleBo nestedRole = getRoleBo(roleMemberBo.getMemberId());
                     //it is possible that the the roleTypeService is coming from a remote application
                     // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
                     try {
                         nestedQualification = roleTypeService.convertQualificationForMemberRoles(roleBo.getNamespaceCode(), roleBo.getName(), nestedRole.getNamespaceCode(), nestedRole.getName(), qualification);
                     } catch (Exception ex) {
                         .warn("Not able to retrieve RoleTypeService from remote system for roleBo Id: " + roleBo.getId(), ex);
                     }
                 }
                 List<StringnestedRoleId = new ArrayList<String>(1);
                 nestedRoleId.add(roleMemberBo.getMemberId());
                 // if the user has the given role, add the qualifier the *nested role* has with the
                 // originally queries role
                 if (principalHasRole(principalIdnestedRoleIdnestedQualificationfalse)) {
                     results.add(roleMemberBo.getAttributes());
                 }
             }
         }
         for (Map.Entry<StringList<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) {
             RoleTypeService roleTypeService = getRoleTypeService(entry.getKey());
             //it is possible that the the roleTypeService is coming from a remote   
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
             try {
                 List<RoleMembershipmatchingMembers = roleTypeService.getMatchingRoleMemberships(qualification,
                         entry.getValue());
                 for (RoleMembership roleMembership : matchingMembers) {
                     results.add(roleMembership.getQualifier());
                 }
             } catch (Exception ex) {
                 .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex);
             }
         }
         return Collections.unmodifiableList(results);
     }
 
     @Override
     public List<RoleMembershipgetRoleMembers(List<StringroleIdsMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(roleIds"roleIds");
 
         Set<StringfoundRoleTypeMembers = new HashSet<String>();
         return getRoleMembers(roleIdsqualificationtruefoundRoleTypeMembers);
     }
 
     @Override
     public Collection<StringgetRoleMemberPrincipalIds(String namespaceCodeString roleNameMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(namespaceCode"namespaceCode");
         incomingParamCheck(roleName"roleName");
 
         Set<StringprincipalIds = new HashSet<String>();
         Set<StringfoundRoleTypeMembers = new HashSet<String>();
         List<StringroleIds = Collections.singletonList(getRoleIdByNamespaceCodeAndName(namespaceCoderoleName));
         for (RoleMembership roleMembership : getRoleMembers(roleIdsqualificationfalsefoundRoleTypeMembers)) {
             if (..equals(roleMembership.getType())) {
                 principalIds.addAll(getGroupService().getMemberPrincipalIds(roleMembership.getMemberId()));
             } else {
                 principalIds.add(roleMembership.getMemberId());
             }
         }
         return Collections.unmodifiableSet(principalIds);
     }
 
     @Override
     public boolean principalHasRole(String principalIdList<StringroleIdsMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(principalId"principalId");
         incomingParamCheck(roleIds"roleIds");
 
         return principalHasRole(principalIdroleIdsqualificationtrue);
     }
 
     @Override
     public List<StringgetPrincipalIdSubListWithRole(List<StringprincipalIds,
             String roleNamespaceCodeString roleNameMap<StringStringqualificationthrows RiceIllegalStateException {
         incomingParamCheck(principalIds"principalIds");
         incomingParamCheck(roleNamespaceCode"roleNamespaceCode");
         incomingParamCheck(roleName"roleName");
 
         List<StringsubList = new ArrayList<String>();
         RoleBo role = getRoleBoByName(roleNamespaceCoderoleName);
         for (String principalId : principalIds) {
             if (principalHasRole(principalId, Collections.singletonList(role.getId()), qualification)) {
                 subList.add(principalId);
             }
         }
         return Collections.unmodifiableList(subList);
     }
 
     @Override
     public RoleQueryResults findRoles(QueryByCriteria queryByCriteriathrows RiceIllegalStateException {
         incomingParamCheck(queryByCriteria"queryByCriteria");
 
         GenericQueryResults<RoleBoresults = getCriteriaLookupService().lookup(RoleBo.classqueryByCriteria);
 
         RoleQueryResults.Builder builder = RoleQueryResults.Builder.create();
         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
         builder.setTotalRowCount(results.getTotalRowCount());
 
         final List<Role.Builderims = new ArrayList<Role.Builder>();
         for (RoleBo bo : results.getResults()) {
             ims.add(Role.Builder.create(bo));
         }
 
         builder.setResults(ims);
         return builder.build();
     }
 
     @Override
         incomingParamCheck(roleIds"roleIds");
         if (roleIds.isEmpty()) {
             return Collections.emptyList();
         }
 
         List<RoleMemberBoroleMemberBoList = getStoredRoleMembersForRoleIds(roleIdsnullnull);
         List<RoleMembershiproleMemberships = new ArrayList<RoleMembership>();
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
             RoleMembership roleMembeship = RoleMembership.Builder.create(
                     roleMemberBo.getRoleId(),
                     roleMemberBo.getId(),
                     roleMemberBo.getMemberId(),
                     roleMemberBo.getType(),
                     roleMemberBo.getAttributes()).build();
             roleMemberships.add(roleMembeship);
         }
         return Collections.unmodifiableList(roleMemberships);
     }
 
     @Override
         incomingParamCheck(queryByCriteria"queryByCriteria");
 
         GenericQueryResults<RoleMemberBoresults = getCriteriaLookupService().lookup(RoleMemberBo.classqueryByCriteria);
 
         RoleMembershipQueryResults.Builder builder = RoleMembershipQueryResults.Builder.create();
         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
         builder.setTotalRowCount(results.getTotalRowCount());
 
         final List<RoleMembership.Builderims = new ArrayList<RoleMembership.Builder>();
         for (RoleMemberBo bo : results.getResults()) {
             RoleMembership.Builder roleMembership = RoleMembership.Builder.create(
                     bo.getRoleId(),
                     bo.getId(),
                     bo.getMemberId(),
                     bo.getType(),
                     bo.getAttributes());
             ims.add(roleMembership);
         }
 
         builder.setResults(ims);
         return builder.build();
     }
 
     @Override
         incomingParamCheck(delegationId"delegationId");
 
         DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId);
         if (delegateBo == null) {return Collections.emptyList();}
 
         return getDelegateMembersForDelegation(delegateBo);
     }
 
     @Override
         incomingParamCheck(delegationId"delegationId");
         incomingParamCheck(memberId"memberId");
 
         DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId);
         DelegateMemberBo delegationMember = getKimDelegationMemberImplByDelegationAndId(delegationIdmemberId);
 
         return getDelegateCompleteInfo(delegateBodelegationMember);
     }
 
     @Override
     public DelegateMember getDelegationMemberById(String delegationMemberIdthrows RiceIllegalStateException {
         incomingParamCheck(delegationMemberId"delegationMemberId");
 
         DelegateMemberBo delegateMemberBo = getDelegateMemberBo(delegationMemberId);
         if (delegateMemberBo == null) {
             return null;
         }
 
         DelegateTypeBo delegateBo = getKimDelegationImpl(delegateMemberBo.getDelegationId());
 
         return getDelegateCompleteInfo(delegateBodelegateMemberBo);
     }
 
     @Override
         incomingParamCheck(roleId"roleId");
 
         Map<StringStringcriteria = new HashMap<StringString>(1);
         criteria.put(..roleId);
         List<RoleResponsibilityBoroleResponsibilityBos = (List<RoleResponsibilityBo>)
                 getBusinessObjectService().findMatching(RoleResponsibilityBo.classcriteria);
         List<RoleResponsibilityroleResponsibilities = new ArrayList<RoleResponsibility>();
 
         for (RoleResponsibilityBo roleResponsibilityImpl : roleResponsibilityBos) {
             roleResponsibilities.add(RoleResponsibilityBo.to(roleResponsibilityImpl));
         }
         return Collections.unmodifiableList(roleResponsibilities);
     }
 
     @Override
         incomingParamCheck(roleId"roleId");
         incomingParamCheck(delegationType"delegationType");
 
         DelegateTypeBo delegateBo = getDelegationOfType(roleIddelegationType);
         return DelegateTypeBo.to(delegateBo);
     }
 
     @Override
         incomingParamCheck(delegationId"delegationId");
 
         DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId);
         return DelegateTypeBo.to(delegateBo);
     }
 
     protected List<RoleMembershipgetRoleMembers(List<StringroleIdsMap<StringStringqualificationboolean followDelegationsSet<StringfoundRoleTypeMembers) {
         List<RoleMembershipresults = new ArrayList<RoleMembership>();
         Set<StringallRoleIds = new HashSet<String>();
         for (String roleId : roleIds) {
             if (isRoleActive(roleId)) {
                 allRoleIds.add(roleId);
             }
         }
         // short-circuit if no roles match
         if (allRoleIds.isEmpty()) {
             return Collections.emptyList();
         }
         Set<StringmatchingRoleIds = new HashSet<String>(allRoleIds.size());
         // for efficiency, retrieve all roles and store in a map
         Map<StringRoleBoroles = getRoleBoMap(allRoleIds);
 
         List<StringcopyRoleIds = new ArrayList<String>(allRoleIds);
         List<RoleMemberBorms = new ArrayList<RoleMemberBo>();
 
         for (String roleId : allRoleIds) {
             RoleTypeService roleTypeService = getRoleTypeService(roleId);
             if (roleTypeService != null) {
                 List<StringattributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
                 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
                     copyRoleIds.remove(roleId);
                     rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), nullpopulateQualifiersForExactMatch(qualificationattributesForExactMatch)));
                 }
             }
         }
         if (CollectionUtils.isNotEmpty(copyRoleIds)) {
             rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIdsnullnull));
         }
 
         // build a map of role ID to membership information
         // this will be used for later qualification checks
         Map<StringList<RoleMembership>> roleIdToMembershipMap = new HashMap<StringList<RoleMembership>>();
         for (RoleMemberBo roleMemberBo : rms) {
             RoleMembership mi = RoleMembership.Builder.create(
                     roleMemberBo.getRoleId(),
                     roleMemberBo.getId(),
                     roleMemberBo.getMemberId(),
                     roleMemberBo.getType(),
                     roleMemberBo.getAttributes()).build();
 
             // if the qualification check does not need to be made, just add the result
             if ((qualification == null || qualification.isEmpty()) || getRoleTypeService(roleMemberBo.getRoleId()) == null) {
                 if (..equals(roleMemberBo.getType())) {
                     // if a role member type, do a non-recursive role member check
                     // to obtain the group and principal members of that role
                     // given the qualification
                     Map<StringStringnestedRoleQualification = qualification;
                     if (getRoleTypeService(roleMemberBo.getRoleId()) != null) {
                         // get the member role object
                         RoleBo memberRole = getRoleBo(mi.getMemberId());
                         nestedRoleQualification = getRoleTypeService(roleMemberBo.getRoleId())
                                 .convertQualificationForMemberRoles(
                                         roles.get(roleMemberBo.getRoleId()).getNamespaceCode(),
                                         roles.get(roleMemberBo.getRoleId()).getName(),
                                         memberRole.getNamespaceCode(),
                                         memberRole.getName(),
                                         qualification);
                     }
                     if (isRoleActive(roleMemberBo.getRoleId())) {
                         Collection<RoleMembershipnestedRoleMembers = getNestedRoleMembers(nestedRoleQualificationmifoundRoleTypeMembers);
                         if (!nestedRoleMembers.isEmpty()) {
                             results.addAll(nestedRoleMembers);
                             matchingRoleIds.add(roleMemberBo.getRoleId());
                         }
                     }
                 } else { // not a role member type
                     results.add(mi);
                     matchingRoleIds.add(roleMemberBo.getRoleId());
                 }
                 matchingRoleIds.add(roleMemberBo.getRoleId());
             } else {
                 List<RoleMembershiplrmi = roleIdToMembershipMap.get(mi.getRoleId());
                 if (lrmi == null) {
                     lrmi = new ArrayList<RoleMembership>();
                     roleIdToMembershipMap.put(mi.getRoleId(), lrmi);
                 }
                 lrmi.add(mi);
             }
         }
         // if there is anything in the role to membership map, we need to check the role type services
         // for those entries
         if (!roleIdToMembershipMap.isEmpty()) {
             // for each role, send in all the qualifiers for that role to the type service
             // for evaluation, the service will return those which match
             for (Map.Entry<StringList<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) {
                 //it is possible that the the roleTypeService is coming from a remote application
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
                 try {
                     RoleTypeService roleTypeService = getRoleTypeService(entry.getKey());
                     List<RoleMembershipmatchingMembers = roleTypeService.getMatchingRoleMemberships(qualification,
                             entry.getValue());
                     // loop over the matching entries, adding them to the results
                     for (RoleMembership roleMemberships : matchingMembers) {
                         if (..equals(roleMemberships.getType())) {
                             // if a role member type, do a non-recursive role member check
                             // to obtain the group and principal members of that role
                             // given the qualification
                             // get the member role object
                             RoleBo memberRole = getRoleBo(roleMemberships.getMemberId());
                             if (memberRole.isActive()) {
                                 Map<StringStringnestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(
                                         roles.get(roleMemberships.getRoleId()).getNamespaceCode(),
                                         roles.get(roleMemberships.getRoleId()).getName(),
                                         memberRole.getNamespaceCode(),
                                         memberRole.getName(),
                                         qualification);
                                 Collection<RoleMembershipnestedRoleMembers = getNestedRoleMembers(nestedRoleQualificationroleMembershipsfoundRoleTypeMembers);
                                 if (!nestedRoleMembers.isEmpty()) {
                                     results.addAll(nestedRoleMembers);
                                     matchingRoleIds.add(roleMemberships.getRoleId());
                                 }
                             }
                         } else { // not a role member
                             results.add(roleMemberships);
                             matchingRoleIds.add(roleMemberships.getRoleId());
                         }
                     }
                 } catch (Exception ex) {
                     .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex);
                 }
             }
         }
 
         // handle derived roles
     	for ( String roleId : allRoleIds ) {
     		RoleTypeService roleTypeService = getRoleTypeServiceroleId );
 			RoleBo role = roles.getroleId );
     		// check if a derived role
             try {
         		if ( isDerivedRoleType(role.getKimTypeId(), roleTypeService) ) {
                     // for each derived role, get the list of principals and groups which are in that role given the qualification (per the role type service)
         			List<RoleMembershiproleMembers = roleTypeService.getRoleMembersFromDerivedRole(role.getNamespaceCode(), role.getName(), qualification);
         			if ( !roleMembers.isEmpty()  ) {
         				matchingRoleIds.addroleId );
         			}
         			for ( RoleMembership rm : roleMembers ) {
                         RoleMembership.Builder builder = RoleMembership.Builder.create(rm);
                         builder.setRoleId(roleId);
                         builder.setId("*");
                         results.add(builder.build());
         			}
         		}
             } catch (Exception ex) {
                 .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleIdex);
             }
     	}
 
     	if ( followDelegations && !matchingRoleIds.isEmpty() ) {
 	    	// we have a list of RoleMembershipInfo objects
 	    	// need to get delegations for distinct list of roles in that list
 	    	Map<StringDelegateTypeBodelegationIdToDelegationMap = getStoredDelegationImplMapFromRoleIds(matchingRoleIds);
             if (!delegationIdToDelegationMap.isEmpty()) {
                 List<RoleMembership.BuildermembershipsWithDelegations =
                         applyDelegationsToRoleMembers(resultsdelegationIdToDelegationMap.values(), qualification);
                 resolveDelegationMemberRoles(membershipsWithDelegationsqualificationfoundRoleTypeMembers);
                 results = ModelObjectUtils.buildImmutableCopy(membershipsWithDelegations);
             }
     	}
     	
     	// sort the results if a single role type service can be identified for
         // all the matching role members
         if ( results.size() > 1 ) {
             // if a single role: easy case
             if ( matchingRoleIds.size() == 1 ) {
                 String roleId = matchingRoleIds.iterator().next();
                 RoleTypeService roleTypeService = getRoleTypeServiceroleId );
                 //it is possible that the the roleTypeService is coming from a remote application 
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
                 try {
                     if ( roleTypeService != null ) {
                         results = roleTypeService.sortRoleMembersresults );
                     }
                 } catch (Exception ex) {
                     .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleIdex);
                 }
             } else if ( matchingRoleIds.size() > 1 ) {
                 // if more than one, check if there is only a single role type service
                 String prevServiceName = null;
                 boolean multipleServices = false;
                 for ( String roleId : matchingRoleIds ) {
                     String serviceName = KimApiServiceLocator.getKimTypeInfoService().getKimType(getRole(roleId).getKimTypeId()).getServiceName();
                     if ( prevServiceName != null && !StringUtils.equalsprevServiceNameserviceName ) ) {
                         multipleServices = true;
                         break;
                     }
                     prevServiceName = serviceName;
                 }
                 if ( !multipleServices ) {
                     String roleId = matchingRoleIds.iterator().next();
                     //it is possible that the the roleTypeService is coming from a remote application 
                     // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
                     try {                       
                         RoleTypeService kimRoleTypeService = getRoleTypeServiceroleId );
                         if ( kimRoleTypeService != null ) {
                             results = kimRoleTypeService.sortRoleMembersresults );
                         }
                     } catch (Exception ex) {
                         .warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleIdex);
                     }
                 } else {
                     .warn"Did not sort role members - multiple role type services found.  Role Ids: " + matchingRoleIds );
                 }
             }
         }
         return Collections.unmodifiableList(results);
     }

    
Checks each of the result records to determine if there are potentially applicable delegation members for that role membership. If there are, applicable delegations and members will be linked to the RoleMemberships in the given list. An updated list will be returned from this method which includes the appropriate linked delegations.
 
             Collection<DelegateTypeBodelegationsMap<StringStringqualification) {
         MultiValueMap<StringStringroleIdToRoleMembershipIds = new LinkedMultiValueMap<StringString>();
         Map<StringRoleMembership.BuilderroleMembershipIdToBuilder = new HashMap<StringRoleMembership.Builder>();
         List<RoleMembership.BuilderroleMembershipBuilders = new ArrayList<RoleMembership.Builder>();
         // to make our algorithm less painful, let's do some indexing and load the given list of RoleMemberships into
         // builders
         for (RoleMembership roleMembership : roleMemberships) {
             roleIdToRoleMembershipIds.add(roleMembership.getRoleId(), roleMembership.getId());
             RoleMembership.Builder builder = RoleMembership.Builder.create(roleMembership);
             roleMembershipBuilders.add(builder);
             roleMembershipIdToBuilder.put(roleMembership.getId(), builder);
         }
         for (DelegateTypeBo delegation : delegations) {
             // determine the candidate role memberships where this delegation can be mapped
             List<StringcandidateRoleMembershipIds = roleIdToRoleMembershipIds.get(delegation.getRoleId());
             if (CollectionUtils.isNotEmpty(candidateRoleMembershipIds)) {
                 DelegationTypeService delegationTypeService = getDelegationTypeService(delegation.getDelegationId());
                 for (DelegateMemberBo delegationMember : delegation.getMembers()) {
                     // Make sure that the delegation member is active
     	    		if (delegationMember.isActive(DateTime.now()) && (delegationTypeService == null ||
                             delegationTypeService.doesDelegationQualifierMatchQualification(qualificationdelegationMember.getQualifier()))) {
                         DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegationMember);
                         // if the member has no role member id, check qualifications and apply to all matching role memberships on the role
 	    	    	    if (StringUtils.isBlank(delegationMember.getRoleMemberId())) {
                             RoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId());
                             for (String roleMembershipId : candidateRoleMembershipIds) {
                                 RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(roleMembershipId);
                                 if (roleTypeService == null || roleTypeService.doesRoleQualifierMatchQualification(roleMembershipBuilder.getQualifier(), delegationMember.getQualifier())) {
                                     linkDelegateToRoleMembership(delegationdelegateMemberBuilderroleMembershipBuilder);
                                 }
                             }
                         } else if (candidateRoleMembershipIds.contains(delegationMember.getRoleMemberId())) {
                             RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(delegationMember.getRoleMemberId());
                             linkDelegateToRoleMembership(delegationdelegateMemberBuilderroleMembershipBuilder);
                         }
                     }
                 }
             }
         }
         return roleMembershipBuilders;
     }
 
     protected void linkDelegateToRoleMembership(DelegateTypeBo delegationDelegateMember.Builder delegateMemberBuilder,
             RoleMembership.Builder roleMembershipBuilder) {
         DelegateType.Builder delegateBuilder = null;
         for(DelegateType.Builder existingDelegateBuilder : roleMembershipBuilder.getDelegates()) {
             if (existingDelegateBuilder.getDelegationId().equals(delegation.getDelegationId())) {
                 delegateBuilder = existingDelegateBuilder;
             }
         }
         if (delegateBuilder == null) {
             delegateBuilder = DelegateType.Builder.create(delegation);
             delegateBuilder.setMembers(new ArrayList<DelegateMember.Builder>());
             roleMembershipBuilder.getDelegates().add(delegateBuilder);
         }
         delegateBuilder.getMembers().add(delegateMemberBuilder);
 
     }

    
Once the delegations for a RoleMembershipInfo object have been determined, any "role" member types need to be resolved into groups and principals so that further KIM requests are not needed.
 
     protected void resolveDelegationMemberRoles(List<RoleMembership.BuildermembershipBuilders,
             Map<StringStringqualificationSet<StringfoundRoleTypeMembers) {
         // check delegations assigned to this role
         for (RoleMembership.Builder roleMembership : membershipBuilders) {
             // the applicable delegation IDs will already be set in the RoleMembership.Builder