Coverage Report - org.kuali.rice.kim.service.impl.RoleServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RoleServiceImpl
0%
0/670
0%
0/400
5.436
 
 1  
 /*
 2  
  * Copyright 2007 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kim.service.impl;
 17  
 
 18  
 import java.sql.Date;
 19  
 import java.sql.Timestamp;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.Collections;
 23  
 import java.util.HashMap;
 24  
 import java.util.HashSet;
 25  
 import java.util.List;
 26  
 import java.util.ListIterator;
 27  
 import java.util.Map;
 28  
 import java.util.Set;
 29  
 
 30  
 import javax.jws.WebParam;
 31  
 import javax.jws.WebService;
 32  
 
 33  
 import org.apache.commons.lang.StringUtils;
 34  
 import org.apache.log4j.Logger;
 35  
 import org.kuali.rice.kim.bo.Role;
 36  
 import org.kuali.rice.kim.bo.group.dto.GroupMembershipInfo;
 37  
 import org.kuali.rice.kim.bo.group.impl.GroupMemberImpl;
 38  
 import org.kuali.rice.kim.bo.impl.RoleImpl;
 39  
 import org.kuali.rice.kim.bo.role.dto.DelegateInfo;
 40  
 import org.kuali.rice.kim.bo.role.dto.DelegateMemberCompleteInfo;
 41  
 import org.kuali.rice.kim.bo.role.dto.DelegateTypeInfo;
 42  
 import org.kuali.rice.kim.bo.role.dto.KimRoleInfo;
 43  
 import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo;
 44  
 import org.kuali.rice.kim.bo.role.dto.RoleResponsibilityInfo;
 45  
 import org.kuali.rice.kim.bo.role.impl.KimDelegationImpl;
 46  
 import org.kuali.rice.kim.bo.role.impl.KimDelegationMemberImpl;
 47  
 import org.kuali.rice.kim.bo.role.impl.RoleMemberImpl;
 48  
 import org.kuali.rice.kim.bo.role.impl.RoleResponsibilityImpl;
 49  
 import org.kuali.rice.kim.bo.types.dto.AttributeSet;
 50  
 import org.kuali.rice.kim.bo.types.dto.KimTypeInfo;
 51  
 import org.kuali.rice.kim.service.KIMServiceLocator;
 52  
 import org.kuali.rice.kim.service.RoleService;
 53  
 import org.kuali.rice.kim.service.support.KimDelegationTypeService;
 54  
 import org.kuali.rice.kim.service.support.KimRoleTypeService;
 55  
 import org.kuali.rice.kim.service.support.KimTypeService;
 56  
 import org.kuali.rice.kim.util.KIMPropertyConstants;
 57  
 import org.kuali.rice.kim.util.KIMWebServiceConstants;
 58  
 import org.kuali.rice.kim.util.KimCommonUtils;
 59  
 import org.kuali.rice.kim.util.KimConstants;
 60  
 import org.kuali.rice.kns.bo.BusinessObject;
 61  
 import org.apache.commons.collections.CollectionUtils;
 62  
 
 63  
 /**
 64  
  * This is a description of what this class does - jonathan don't forget to fill this in.
 65  
  *
 66  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 67  
  *
 68  
  */
 69  
 @WebService(endpointInterface = KIMWebServiceConstants.RoleService.INTERFACE_CLASS, serviceName = KIMWebServiceConstants.RoleService.WEB_SERVICE_NAME, portName = KIMWebServiceConstants.RoleService.WEB_SERVICE_PORT, targetNamespace = KIMWebServiceConstants.MODULE_TARGET_NAMESPACE)
 70  0
 public class RoleServiceImpl extends RoleServiceBase implements RoleService {
 71  0
         private static final Logger LOG = Logger.getLogger( RoleServiceImpl.class );
 72  
 
 73  
         
 74  
         
 75  
     // --------------------
 76  
     // Role Data
 77  
     // --------------------
 78  
 
 79  
     
 80  
 
 81  
     
 82  
 
 83  
         /**
 84  
          * @see org.kuali.rice.kim.service.RoleService#getRole(java.lang.String)
 85  
          */
 86  
         public KimRoleInfo getRole(String roleId) {
 87  0
                 RoleImpl role = getRoleImpl( roleId );
 88  0
                 if ( role == null ) {
 89  0
                         return null;
 90  
                 }
 91  0
                 return role.toSimpleInfo();
 92  
         }
 93  
 
 94  
         /**
 95  
          * @see org.kuali.rice.kim.service.RoleService#getRoleIdByName(java.lang.String, java.lang.String)
 96  
          */
 97  
         public String getRoleIdByName(String namespaceCode, String roleName) {
 98  0
                 RoleImpl role = getRoleImplByName( namespaceCode, roleName );
 99  0
                 if ( role == null ) {
 100  0
                         return null;
 101  
                 }
 102  0
                 return role.getRoleId();
 103  
         }
 104  
 
 105  
         /**
 106  
          * @see org.kuali.rice.kim.service.RoleService#getRoleByName(java.lang.String, java.lang.String)
 107  
          */
 108  
         public KimRoleInfo getRoleByName( String namespaceCode, String roleName ) {
 109  0
                 RoleImpl role = getRoleImplByName( namespaceCode, roleName );
 110  0
                 if ( role != null ) {
 111  0
                         return role.toSimpleInfo();
 112  
                 }
 113  0
                 return null;
 114  
         }
 115  
 
 116  
         
 117  
 
 118  
         protected Map<String,RoleImpl> getRoleImplMap(Collection<String> roleIds) {
 119  0
                 Map<String,RoleImpl> result = null;
 120  
                 // check for a non-null result in the cache, return it if found
 121  0
                 if ( roleIds.size() == 1 ) {
 122  0
                         String roleId = roleIds.iterator().next();
 123  0
                         RoleImpl impl = getRoleImpl(roleId);
 124  0
                         if ( impl.isActive() ) {
 125  0
                                 result = Collections.singletonMap(roleId, getRoleImpl(roleId));
 126  
                         } else {
 127  0
                                 result = Collections.emptyMap();
 128  
                         }                        
 129  0
                 } else {
 130  0
                         result = new HashMap<String,RoleImpl>(roleIds.size());
 131  0
                         for ( String roleId : roleIds ) {
 132  0
                                 RoleImpl impl = getRoleImpl(roleId);
 133  0
                                 if ( impl.isActive() ) {
 134  0
                                         result.put(roleId, impl);
 135  
                                 }                                
 136  0
                         }
 137  
                 }
 138  0
                 return result;
 139  
         }
 140  
 
 141  
         public List<KimRoleInfo> getRoles(List<String> roleIds) {
 142  0
                 Collection<RoleImpl> roles = getRoleImplMap(roleIds).values();
 143  0
                 List<KimRoleInfo> roleInfos = new ArrayList<KimRoleInfo>( roles.size() );
 144  0
                 for ( RoleImpl r : roles ) {
 145  0
                         roleInfos.add( r.toSimpleInfo() );
 146  
                 }
 147  0
                 return roleInfos;
 148  
         }
 149  
 
 150  
 
 151  
         @SuppressWarnings("unchecked")
 152  
         public List<KimRoleInfo> lookupRoles(Map<String, String> searchCriteria) {
 153  0
                 Collection<RoleImpl> results = getBusinessObjectService().findMatching(RoleImpl.class, searchCriteria);
 154  0
                 ArrayList<KimRoleInfo> infoResults = new ArrayList<KimRoleInfo>( results.size() );
 155  0
                 for ( RoleImpl role : results ) {
 156  0
                         infoResults.add( role.toSimpleInfo() );
 157  
                 }
 158  0
                 return infoResults;
 159  
         }
 160  
 
 161  
         public boolean isRoleActive( String roleId ) {
 162  0
                 RoleImpl role = getRoleImpl( roleId );
 163  0
                 return role != null && role.isActive();
 164  
         }
 165  
 
 166  
         public List<AttributeSet> getRoleQualifiersForPrincipalIncludingNested( String principalId, String namespaceCode, String roleName, AttributeSet qualification ) {
 167  0
                 String roleId = getRoleIdByName(namespaceCode, roleName);
 168  0
                 if ( roleId == null ) {
 169  0
                         return new ArrayList<AttributeSet>(0);
 170  
                 }
 171  0
                 return getRoleQualifiersForPrincipalIncludingNested(principalId, Collections.singletonList(roleId), qualification);
 172  
         }
 173  
 
 174  
 
 175  
         private AttributeSet populateQualifiersForExactMatch(AttributeSet defaultQualification, List<String> attributes) {
 176  0
                 AttributeSet qualifiersForExactMatch = new AttributeSet();
 177  0
                 if(defaultQualification != null && CollectionUtils.isNotEmpty(defaultQualification.keySet())) {
 178  0
                         for(String attributeName : attributes) {
 179  0
                                 if(StringUtils.isNotEmpty(defaultQualification.get(attributeName))) {
 180  0
                                         qualifiersForExactMatch.put(attributeName, defaultQualification.get(attributeName));
 181  
                                 }
 182  
                         }
 183  
                 }
 184  0
                 return qualifiersForExactMatch;
 185  
         }
 186  
         
 187  
         private List<RoleMemberImpl> getStoredRoleMembersUsingExactMatchOnQualification(String principalId, List<String> groupIds, List<String> roleIds, AttributeSet qualification) {
 188  0
             List<String> copyRoleIds = new ArrayList(roleIds);
 189  0
             List<RoleMemberImpl> rms = new ArrayList<RoleMemberImpl>();
 190  
             
 191  0
             for(String roleId : roleIds) {
 192  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 193  0
                     if(roleTypeService != null) {
 194  0
                             List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 195  0
                             if(CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 196  0
                                     copyRoleIds.remove(roleId);
 197  0
                                     rms.addAll(getStoredRoleMembersForRoleIdsWithFilters(Collections.singletonList(roleId), principalId, groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 198  
                             }
 199  
                     }
 200  0
             }
 201  0
             if(CollectionUtils.isNotEmpty(copyRoleIds)) {
 202  0
                     rms.addAll(getStoredRoleMembersForRoleIdsWithFilters(copyRoleIds, principalId, groupIds, null));
 203  
             }
 204  0
             return rms;
 205  
         }
 206  
         
 207  
         public List<AttributeSet> getRoleQualifiersForPrincipalIncludingNested( String principalId, List<String> roleIds, AttributeSet qualification ) {
 208  0
                 List<AttributeSet> results = new ArrayList<AttributeSet>();
 209  
 
 210  0
             Map<String,RoleImpl> roles = getRoleImplMap(roleIds);
 211  
 
 212  
             // get the person's groups
 213  0
             List<String> groupIds = getIdentityManagementService().getGroupIdsForPrincipal(principalId);
 214  0
             List<RoleMemberImpl> rms = getStoredRoleMembersUsingExactMatchOnQualification(principalId, groupIds, roleIds, qualification);
 215  
 
 216  0
             Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap = new HashMap<String,List<RoleMembershipInfo>>();
 217  0
             for ( RoleMemberImpl rm : rms ) {
 218  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( rm.getRoleId() );
 219  
                     // gather up the qualifier sets and the service they go with
 220  0
                     if ( rm.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE )
 221  
                                         || rm.getMemberTypeCode().equals( Role.GROUP_MEMBER_TYPE ) ) {
 222  0
                             if ( roleTypeService != null ) {
 223  0
                                     List<RoleMembershipInfo> las = roleIdToMembershipMap.get( rm.getRoleId() );
 224  0
                                     if ( las == null ) {
 225  0
                                             las = new ArrayList<RoleMembershipInfo>();
 226  0
                                             roleIdToMembershipMap.put( rm.getRoleId(), las );
 227  
                                     }
 228  0
                                 RoleMembershipInfo mi = new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier() );
 229  0
                                     las.add( mi );
 230  0
                             } else {
 231  0
                                     results.add(rm.getQualifier());
 232  
                             }
 233  0
                     } else if ( rm.getMemberTypeCode().equals( Role.ROLE_MEMBER_TYPE )  ) {
 234  
                             // find out if the user has the role
 235  
                             // need to convert qualification using this role's service
 236  0
                             AttributeSet nestedQualification = qualification;
 237  0
                             if ( roleTypeService != null ) {
 238  0
                                     RoleImpl role = roles.get(rm.getRoleId());
 239  
                                     // pulling from here as the nested role is not necessarily (and likely is not)
 240  
                                     // in the roles Map created earlier
 241  0
                                     RoleImpl nestedRole = getRoleImpl(rm.getMemberId());
 242  
                                     //it is possible that the the roleTypeService is coming from a remote application 
 243  
                     // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 244  
                                     try {
 245  0
                                         nestedQualification = roleTypeService.convertQualificationForMemberRoles(role.getNamespaceCode(), role.getRoleName(), nestedRole.getNamespaceCode(), nestedRole.getRoleName(), qualification);
 246  0
                                     } catch (Exception ex) {
 247  0
                         LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + role.getRoleId(), ex);
 248  0
                     }
 249  
                             }
 250  0
                             List<String> nestedRoleId = new ArrayList<String>(1);
 251  0
                             nestedRoleId.add( rm.getMemberId() );
 252  
                             // if the user has the given role, add the qualifier the *nested role* has with the
 253  
                             // originally queries role
 254  0
                             if ( principalHasRole( principalId, nestedRoleId, nestedQualification, false ) ) {
 255  0
                                     results.add( rm.getQualifier() );
 256  
                             }
 257  
                     }
 258  0
             }
 259  0
                 for ( String roleId : roleIdToMembershipMap.keySet() ) {
 260  0
                         KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 261  
                         //it is possible that the the roleTypeService is coming from a remote application 
 262  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 263  
             try {
 264  0
                             List<RoleMembershipInfo> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification( qualification, roleIdToMembershipMap.get( roleId ) );
 265  0
                             for ( RoleMembershipInfo rmi : matchingMembers ) {
 266  0
                                     results.add( rmi.getQualifier() );
 267  
                             }
 268  0
             } catch (Exception ex) {
 269  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 270  0
             }
 271  0
                 }
 272  0
             return results;
 273  
         }
 274  
 
 275  
         public List<AttributeSet> getRoleQualifiersForPrincipal( String principalId, List<String> roleIds, AttributeSet qualification ) {
 276  0
                 List<AttributeSet> results = new ArrayList<AttributeSet>();
 277  
 
 278  
             // TODO: ? get groups for principal and get those as well?
 279  
             // this implementation may be incomplete, as groups and sub-roles are not considered
 280  0
             List<RoleMemberImpl> rms = getStoredRoleMembersUsingExactMatchOnQualification(principalId, null, roleIds, qualification);
 281  
 
 282  0
             Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap = new HashMap<String,List<RoleMembershipInfo>>();
 283  0
             for ( RoleMemberImpl rm : rms ) {
 284  
                     // gather up the qualifier sets and the service they go with
 285  0
                     if ( rm.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE )) {
 286  0
                             KimRoleTypeService roleTypeService = getRoleTypeService( rm.getRoleId() );
 287  0
                             if ( roleTypeService != null ) {
 288  0
                                     List<RoleMembershipInfo> las = roleIdToMembershipMap.get( rm.getRoleId() );
 289  0
                                     if ( las == null ) {
 290  0
                                             las = new ArrayList<RoleMembershipInfo>();
 291  0
                                             roleIdToMembershipMap.put( rm.getRoleId(), las );
 292  
                                     }
 293  0
                                 RoleMembershipInfo mi = new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier() );
 294  0
                                     las.add( mi );
 295  0
                             } else {
 296  0
                                     results.add(rm.getQualifier());
 297  
                             }
 298  0
                     }
 299  
             }
 300  0
                 for ( String roleId : roleIdToMembershipMap.keySet() ) {
 301  0
                         KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 302  
                         //it is possible that the the roleTypeService is coming from a remote application 
 303  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 304  
             try {
 305  0
                             List<RoleMembershipInfo> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification( qualification, roleIdToMembershipMap.get( roleId ) );
 306  0
                             for ( RoleMembershipInfo rmi : matchingMembers ) {
 307  0
                                     results.add( rmi.getQualifier() );
 308  
                             }
 309  0
             } catch (Exception ex) {
 310  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 311  0
             }
 312  0
                 }
 313  0
             return results;
 314  
         }
 315  
 
 316  
         public List<AttributeSet> getRoleQualifiersForPrincipal( String principalId, String namespaceCode, String roleName, AttributeSet qualification ) {
 317  0
                 return getRoleQualifiersForPrincipal(
 318  
                                 principalId,
 319  
                                 Collections.singletonList(getRoleIdByName(namespaceCode, roleName)),
 320  
                                 qualification);
 321  
         }
 322  
 
 323  
 
 324  
     // --------------------
 325  
     // Role Membership Methods
 326  
     // --------------------
 327  
 
 328  
     /**
 329  
      * @see org.kuali.rice.kim.service.RoleService#getRoleMembers(java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 330  
      */
 331  
     public List<RoleMembershipInfo> getRoleMembers(List<String> roleIds, AttributeSet qualification) {
 332  0
             Set<String> foundRoleTypeMembers = new HashSet<String>();
 333  0
             return getRoleMembers(roleIds, qualification, true, foundRoleTypeMembers);
 334  
     }
 335  
 
 336  
     
 337  
 
 338  
         public Collection<String> getRoleMemberPrincipalIds(String namespaceCode, String roleName, AttributeSet qualification) {
 339  0
                 Set<String> principalIds = new HashSet<String>();
 340  0
             Set<String> foundRoleTypeMembers = new HashSet<String>();
 341  0
                 List<String> roleIds = Collections.singletonList(getRoleIdByName(namespaceCode, roleName));
 342  0
             for (RoleMembershipInfo roleMembershipInfo : getRoleMembers(roleIds, qualification, false, foundRoleTypeMembers)) {
 343  0
                     if (Role.GROUP_MEMBER_TYPE.equals(roleMembershipInfo.getMemberTypeCode())) {
 344  0
                             principalIds.addAll(getIdentityManagementService().getGroupMemberPrincipalIds(roleMembershipInfo.getMemberId()));
 345  
                     }
 346  
                     else {
 347  0
                             principalIds.add(roleMembershipInfo.getMemberId());
 348  
                     }
 349  
                 }
 350  0
             return principalIds;
 351  
         }
 352  
 
 353  
         protected Collection<RoleMembershipInfo> getNestedRoleMembers( AttributeSet qualification, RoleMembershipInfo rm, Set<String> foundRoleTypeMembers ) {
 354  
                 // If this role has already been traversed, skip it
 355  0
                 if (foundRoleTypeMembers.contains(rm.getMemberId())){
 356  0
                         return new ArrayList<RoleMembershipInfo>();  // return an empty list
 357  
                 }
 358  0
                 foundRoleTypeMembers.add(rm.getMemberId());
 359  
 
 360  0
                 ArrayList<String> roleIdList = new ArrayList<String>( 1 );
 361  0
                 roleIdList.add( rm.getMemberId() );
 362  
 
 363  
                 // get the list of members from the nested role - ignore delegations on those sub-roles
 364  0
                 Collection<RoleMembershipInfo> nestedRoleMembers = getRoleMembers( roleIdList, qualification, false, foundRoleTypeMembers );
 365  
                 // add the roles  whose members matched to the list for delegation checks later
 366  0
                 for ( RoleMembershipInfo rmi : nestedRoleMembers ) {
 367  
                         // use the member ID of the parent role (needed for responsibility joining)
 368  0
                         rmi.setRoleMemberId( rm.getRoleMemberId() );
 369  
                         // store the role ID, so we know where this member actually came from
 370  0
                         rmi.setRoleId( rm.getRoleId() );
 371  0
                         rmi.setEmbeddedRoleId( rm.getMemberId() );
 372  
                 }
 373  0
                 return nestedRoleMembers;
 374  
         }
 375  
 
 376  
         /**
 377  
      * @see org.kuali.rice.kim.service.RoleService#getRoleMembers(java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 378  
      */
 379  
     protected List<RoleMembershipInfo> getRoleMembers(List<String> roleIds, AttributeSet qualification, boolean followDelegations, Set<String> foundRoleTypeMembers ) {
 380  0
             List<RoleMembershipInfo> results = new ArrayList<RoleMembershipInfo>();
 381  0
             Set<String> allRoleIds = new HashSet<String>();
 382  0
             for ( String roleId : roleIds ) {
 383  0
                     if ( isRoleActive(roleId) ) {
 384  0
                             allRoleIds.add(roleId);
 385  
                     }
 386  
             }
 387  
             // short-circuit if no roles match
 388  0
             if ( allRoleIds.isEmpty() ) {
 389  0
                     return results;
 390  
             }
 391  0
             Set<String> matchingRoleIds = new HashSet<String>( allRoleIds.size() );
 392  
             // for efficiency, retrieve all roles and store in a map
 393  0
             Map<String,RoleImpl> roles = getRoleImplMap(allRoleIds);
 394  
 
 395  0
             List<String> copyRoleIds = new ArrayList<String>(allRoleIds);
 396  0
             List<RoleMemberImpl> rms = new ArrayList<RoleMemberImpl>();
 397  
             
 398  0
             for(String roleId : allRoleIds) {
 399  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 400  0
                     if(roleTypeService != null) {
 401  0
                             List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 402  0
                             if(CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 403  0
                                     copyRoleIds.remove(roleId);
 404  0
                                     rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), null, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 405  
                             }  
 406  
                     }
 407  0
             }
 408  0
             if(CollectionUtils.isNotEmpty(copyRoleIds)) {
 409  0
                     rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIds, null, null));
 410  
             }
 411  
             
 412  
             // build a map of role ID to membership information
 413  
             // this will be used for later qualification checks
 414  0
             Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap = new HashMap<String,List<RoleMembershipInfo>>();
 415  0
             for ( RoleMemberImpl rm : rms ) {
 416  0
                         RoleMembershipInfo mi = new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier() );
 417  
                         // if the qualification check does not need to be made, just add the result
 418  0
                         if ( (qualification == null || qualification.isEmpty()) || getRoleTypeService( rm.getRoleId() ) == null ) {
 419  0
                                 if ( rm.getMemberTypeCode().equals( Role.ROLE_MEMBER_TYPE ) ) {
 420  
                                         // if a role member type, do a non-recursive role member check
 421  
                                         // to obtain the group and principal members of that role
 422  
                                         // given the qualification
 423  0
                                         AttributeSet nestedRoleQualification = qualification;
 424  0
                                         if ( getRoleTypeService( rm.getRoleId() ) != null ) {
 425  
                             // get the member role object
 426  0
                                             RoleImpl memberRole = getRoleImpl( mi.getMemberId() );
 427  0
                                                 nestedRoleQualification = getRoleTypeService( rm.getRoleId() )
 428  
                                                          .convertQualificationForMemberRoles(
 429  
                                                                  roles.get(rm.getRoleId()).getNamespaceCode(),
 430  
                                                                  roles.get(rm.getRoleId()).getRoleName(),
 431  
                                                                  memberRole.getNamespaceCode(),
 432  
                                                                  memberRole.getRoleName(),
 433  
                                                                  qualification );
 434  
                                         }
 435  0
                                         if ( isRoleActive( rm.getRoleId() ) ) {
 436  0
                                                 Collection<RoleMembershipInfo> nestedRoleMembers = getNestedRoleMembers( nestedRoleQualification, mi, foundRoleTypeMembers );
 437  0
                                                 if ( !nestedRoleMembers.isEmpty() ) {
 438  0
                                                         results.addAll( nestedRoleMembers );
 439  0
                                                         matchingRoleIds.add( rm.getRoleId() );
 440  
                                                 }
 441  
                                         }
 442  0
                                 } else { // not a role member type
 443  0
                                         results.add( mi );
 444  0
                                         matchingRoleIds.add( rm.getRoleId() );
 445  
                                 }
 446  0
                                 matchingRoleIds.add( rm.getRoleId() );
 447  
                         } else {
 448  0
                                 List<RoleMembershipInfo> lrmi = roleIdToMembershipMap.get( mi.getRoleId() );
 449  0
                                 if ( lrmi == null ) {
 450  0
                                         lrmi = new ArrayList<RoleMembershipInfo>();
 451  0
                                         roleIdToMembershipMap.put( mi.getRoleId(), lrmi );
 452  
                                 }
 453  0
                                 lrmi.add( mi );
 454  
                         }
 455  0
             }
 456  
             // if there is anything in the role to membership map, we need to check the role type services
 457  
             // for those entries
 458  0
             if ( !roleIdToMembershipMap.isEmpty() ) {
 459  
                     // for each role, send in all the qualifiers for that role to the type service
 460  
                     // for evaluation, the service will return those which match
 461  0
                     for ( String roleId : roleIdToMembershipMap.keySet() ) {
 462  
                         //it is possible that the the roleTypeService is coming from a remote application 
 463  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 464  
                 try {
 465  0
                                 KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 466  0
                                 List<RoleMembershipInfo> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification( qualification, roleIdToMembershipMap.get( roleId ) );
 467  
                                 // loop over the matching entries, adding them to the results
 468  0
                                 for ( RoleMembershipInfo mi : matchingMembers ) {
 469  0
                                         if ( mi.getMemberTypeCode().equals( Role.ROLE_MEMBER_TYPE ) ) {
 470  
                                                 // if a role member type, do a non-recursive role member check
 471  
                                                 // to obtain the group and principal members of that role
 472  
                                                 // given the qualification
 473  
                             // get the member role object
 474  0
                             RoleImpl memberRole = getRoleImpl( mi.getMemberId() );
 475  0
                             if ( memberRole.isActive() ) {
 476  0
                                                         AttributeSet nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(
 477  
                                                                 roles.get(mi.getRoleId()).getNamespaceCode(),
 478  
                                                                 roles.get(mi.getRoleId()).getRoleName(),
 479  
                                             memberRole.getNamespaceCode(),
 480  
                                             memberRole.getRoleName(),
 481  
                                                                 qualification );
 482  0
                                                         Collection<RoleMembershipInfo> nestedRoleMembers = getNestedRoleMembers( nestedRoleQualification, mi, foundRoleTypeMembers );
 483  0
                                                         if ( !nestedRoleMembers.isEmpty() ) {
 484  0
                                                                 results.addAll( nestedRoleMembers );
 485  0
                                                                 matchingRoleIds.add( mi.getRoleId() );
 486  
                                                         }
 487  
                             }
 488  0
                                         } else { // not a role member
 489  0
                                                 results.add( mi );
 490  0
                                                 matchingRoleIds.add( mi.getRoleId() );
 491  
                                         }
 492  
                                 }
 493  0
                         } catch (Exception ex) {
 494  0
                     LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 495  0
                 }
 496  
                     }
 497  
             }
 498  
 
 499  
             // handle application roles
 500  0
             for ( String roleId : allRoleIds ) {
 501  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 502  0
                         RoleImpl role = roles.get( roleId );
 503  
                     // check if an application role
 504  
             try {
 505  0
                         if ( isApplicationRoleType(role.getKimTypeId(), roleTypeService) ) {
 506  
                     // for each application role, get the list of principals and groups which are in that role given the qualification (per the role type service)
 507  0
                                 List<RoleMembershipInfo> roleMembers = roleTypeService.getRoleMembersFromApplicationRole(role.getNamespaceCode(), role.getRoleName(), qualification);
 508  0
                                 if ( !roleMembers.isEmpty()  ) {
 509  0
                                         matchingRoleIds.add( roleId );
 510  
                                 }
 511  0
                                 for ( RoleMembershipInfo rm : roleMembers ) {
 512  0
                                     rm.setRoleId(roleId);
 513  0
                                     rm.setRoleMemberId("*");
 514  
                                 }
 515  0
                                 results.addAll(roleMembers);
 516  
                         }
 517  0
             } catch (Exception ex) {
 518  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 519  0
             }
 520  0
             }
 521  
 
 522  0
             if ( followDelegations && !matchingRoleIds.isEmpty() ) {
 523  
                     // we have a list of RoleMembershipInfo objects
 524  
                     // need to get delegations for distinct list of roles in that list
 525  0
                     Map<String,KimDelegationImpl> delegations = getStoredDelegationImplMapFromRoleIds(matchingRoleIds);
 526  
 
 527  0
                     matchDelegationsToRoleMembers( results, delegations.values() );
 528  0
                     resolveDelegationMembers( results, qualification, foundRoleTypeMembers );
 529  
             }
 530  
 
 531  
             // sort the results if a single role type service can be identified for
 532  
             // all the matching role members
 533  0
             if ( results.size() > 1 ) {
 534  
                 // if a single role: easy case
 535  0
                 if ( matchingRoleIds.size() == 1 ) {
 536  0
                     String roleId = matchingRoleIds.iterator().next();
 537  0
                         KimRoleTypeService kimRoleTypeService = getRoleTypeService( roleId );
 538  
                         //it is possible that the the roleTypeService is coming from a remote application 
 539  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 540  
                 try {
 541  0
                             if ( kimRoleTypeService != null ) {
 542  0
                                     results = kimRoleTypeService.sortRoleMembers( results );
 543  
                             }
 544  0
                 } catch (Exception ex) {
 545  0
                     LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 546  0
                 }
 547  0
                 } else if ( matchingRoleIds.size() > 1 ) {
 548  
                         // if more than one, check if there is only a single role type service
 549  0
                     String prevServiceName = null;
 550  0
                     boolean multipleServices = false;
 551  0
                         for ( String roleId : matchingRoleIds ) {
 552  0
                                 String serviceName = getRoleImpl( roleId ).getKimRoleType().getKimTypeServiceName();
 553  0
                                 if ( prevServiceName != null && !StringUtils.equals( prevServiceName, serviceName ) ) {
 554  0
                                         multipleServices = true;
 555  0
                                         break;
 556  
                                 }
 557  0
                                     prevServiceName = serviceName;
 558  0
                         }
 559  0
                         if ( !multipleServices ) {
 560  0
                             String roleId = matchingRoleIds.iterator().next();
 561  
                             //it is possible that the the roleTypeService is coming from a remote application 
 562  
                     // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 563  
                     try {                       
 564  0
                                 KimRoleTypeService kimRoleTypeService = getRoleTypeService( roleId );
 565  0
                                 if ( kimRoleTypeService != null ) {
 566  0
                                         results = kimRoleTypeService.sortRoleMembers( results );
 567  
                                 }
 568  0
                             } catch (Exception ex) {
 569  0
                         LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 570  0
                     }
 571  0
                         } else {
 572  0
                                 LOG.warn( "Did not sort role members - multiple role type services found.  Role Ids: " + matchingRoleIds );
 573  
                         }
 574  
                 }
 575  
             }
 576  
 
 577  0
             return results;
 578  
     }
 579  
 
 580  
     protected boolean isApplicationRoleType( String roleTypeId, KimRoleTypeService service ) {
 581  0
             Boolean result = getApplicationRoleTypeCache().get( roleTypeId );
 582  0
             if ( result == null ) {
 583  0
                     if ( service != null ) {
 584  0
                             result = service.isApplicationRoleType();
 585  
                     } else {
 586  0
                             result = Boolean.FALSE;
 587  
                     }
 588  
             }
 589  0
             return result;
 590  
     }
 591  
 
 592  
     /**
 593  
      * Retrieves the role type service associated with the given role ID
 594  
      * 
 595  
      * @param roleId the role ID to get the role type service for
 596  
      * @return the Role Type Service
 597  
      */
 598  
     protected KimRoleTypeService getRoleTypeService( String roleId ) {
 599  0
         KimRoleTypeService service = getRoleTypeServiceCache().get( roleId );
 600  0
             if ( service == null && !getRoleTypeServiceCache().containsKey( roleId ) ) {
 601  0
                     RoleImpl role = getRoleImpl( roleId );
 602  0
                     KimTypeInfo roleType = role.getKimRoleType();
 603  0
                     if ( roleType != null ) {
 604  0
                         service = getRoleTypeService(roleType);
 605  
                     }
 606  0
                     getRoleTypeServiceCache().put(roleId, service);
 607  
             }
 608  0
             return service;
 609  
     }
 610  
     
 611  
     protected KimRoleTypeService getRoleTypeService( KimTypeInfo typeInfo ) {
 612  0
                 String serviceName = typeInfo.getKimTypeServiceName();
 613  0
                 if ( serviceName != null ) {
 614  
                         try {
 615  0
                                 KimTypeService service = (KimTypeService)KIMServiceLocator.getService( serviceName );
 616  0
                                 if ( service != null && service instanceof KimRoleTypeService) {
 617  0
                                         return (KimRoleTypeService)service;
 618  
                                 } else {
 619  0
                                         return (KimRoleTypeService)KIMServiceLocator.getService( "kimNoMembersRoleTypeService" );
 620  
                                 }
 621  0
                         } catch ( Exception ex ) {
 622  0
                                 LOG.error( "Unable to find role type service with name: " + serviceName );
 623  0
                                 LOG.error( ex.getClass().getName() + " : " + ex.getMessage() );
 624  0
                                 return (KimRoleTypeService)KIMServiceLocator.getService( "kimNoMembersRoleTypeService" );
 625  
                         }
 626  
                 }
 627  0
                 return null;
 628  
     }
 629  
 
 630  
     protected KimDelegationTypeService getDelegationTypeService( String delegationId ) {
 631  0
             KimDelegationTypeService service = getDelegationTypeServiceCache().get( delegationId );
 632  0
             if ( service == null && !getDelegationTypeServiceCache().containsKey( delegationId ) ) {
 633  0
                     KimDelegationImpl delegation = getKimDelegationImpl(delegationId);
 634  0
                     KimTypeInfo delegationType = delegation.getKimType();
 635  0
                     if ( delegationType != null ) {
 636  0
                             KimTypeService tempService = KimCommonUtils.getKimTypeService(delegationType);
 637  0
                             if ( tempService != null && tempService instanceof KimDelegationTypeService ) {
 638  0
                                     service = (KimDelegationTypeService)tempService;
 639  
                             } else {
 640  0
                                     LOG.error( "Service returned for type " + delegationType + "("+delegationType.getKimTypeServiceName()+") was not a KimDelegationTypeService.  Was a " + tempService.getClass() );
 641  
                             }
 642  0
                     } else { // delegation has no type - default to role type if possible
 643  0
                             KimRoleTypeService roleTypeService = getRoleTypeService( delegation.getRoleId() );
 644  0
                             if ( roleTypeService != null && roleTypeService instanceof KimDelegationTypeService ) {
 645  0
                                     service = (KimDelegationTypeService)roleTypeService;
 646  
                             }
 647  
                     }
 648  0
                     getDelegationTypeServiceCache().put(delegationId, service);
 649  
             }
 650  0
             return service;
 651  
     }
 652  
 
 653  
     /**
 654  
      * Checks each of the result records to determine if there are potentially applicable
 655  
      * delegation members for that role membership.  If so, it adds to the delegates
 656  
      * list on that RoleMembershipInfo object.
 657  
      *
 658  
      * The final determination of whether that delegation member matches the qualification happens in
 659  
      * a later step ( {@link #resolveDelegationMembers(List, Map, AttributeSet)} )
 660  
      */
 661  
     protected void matchDelegationsToRoleMembers( List<RoleMembershipInfo> results,
 662  
                     Collection<KimDelegationImpl> delegations ) {
 663  
             // check each delegation's qualifier to see if they are applicable - matching
 664  
             // against the qualifiers used for that role
 665  
             // so - for each role,
 666  0
             for ( RoleMembershipInfo mi : results ) {
 667  
                     // get the delegations specific to the role on this line
 668  0
                     for ( KimDelegationImpl delegation : delegations ) {
 669  
                             // only check at the moment if the role IDs match
 670  0
                             if ( StringUtils.equals( delegation.getRoleId(), mi.getRoleId() ) ) {
 671  0
                                 KimRoleTypeService roleTypeService = getRoleTypeService( delegation.getRoleId() );
 672  0
                                 for ( KimDelegationMemberImpl delegationMember : delegation.getMembers() ) {
 673  
                                         // first, check the delegation to see if it has a role member ID set
 674  
                                         // if so, then this is a personal delegation rather than a qualifier delegation
 675  
                                         // in this case, the qualifiers must also match, allowing a person to
 676  
                                         // delegate only part of their authority.
 677  0
                                         if ( StringUtils.isBlank( delegationMember.getRoleMemberId() )
 678  
                                                         || StringUtils.equals( delegationMember.getRoleMemberId(), mi.getRoleMemberId() ) ) {
 679  
                                             // this check is against the qualifier from the role relationship
 680  
                                             // that resulted in this record
 681  
                                             // This is to determine that the delegation
 682  
                                                 // but - don't need to check the role qualifiers against delegation qualifiers
 683  
                                                 // if the delegation is linked directly to the role member
 684  0
                                                 if ( (StringUtils.isNotBlank( delegationMember.getRoleMemberId() ) 
 685  
                                                                         && StringUtils.equals( delegationMember.getRoleMemberId(), mi.getRoleMemberId() )
 686  
                                                                         )
 687  
                                                                 || roleTypeService == null
 688  
                                                                 || roleTypeService.doesRoleQualifierMatchQualification( mi.getQualifier(), delegationMember.getQualifier() ) ) {
 689  
                                                         // add the delegate member to the role member information list
 690  
                                                         // these will be checked by a later method against the request
 691  
                                                         // qualifications
 692  0
                                                         mi.getDelegates().add(
 693  
                                                                         new DelegateInfo(
 694  
                                                                                         delegation.getDelegationId(),
 695  
                                                                                         delegation.getDelegationTypeCode(),
 696  
                                                                                         delegationMember.getMemberId(),
 697  
                                                                                         delegationMember.getMemberTypeCode(),
 698  
                                                                                         delegationMember.getRoleMemberId(),
 699  
                                                                                         delegationMember.getQualifier() ) );
 700  
                                                     }
 701  
                                         }
 702  
                                 }
 703  0
                             }
 704  
                     }
 705  
             }
 706  
 
 707  0
     }
 708  
 
 709  
     /**
 710  
      * Once the delegations for a RoleMembershipInfo object have been determined,
 711  
      * any "role" member types need to be resolved into groups and principals so that
 712  
      * further KIM requests are not needed.
 713  
      */
 714  
     protected void resolveDelegationMembers( List<RoleMembershipInfo> results,
 715  
                     AttributeSet qualification, Set<String> foundRoleTypeMembers ) {
 716  
 
 717  
                 // check delegations assigned to this role
 718  0
                 for ( RoleMembershipInfo mi : results ) {
 719  
                         // the applicable delegation IDs will already be set in the RoleMembershipInfo object
 720  
                         // this code examines those delegations and obtains the member groups and principals
 721  0
                         ListIterator<DelegateInfo> i = mi.getDelegates().listIterator();
 722  0
                         while ( i.hasNext() ) {
 723  0
                                 DelegateInfo di = i.next();
 724  0
                                 KimDelegationTypeService delegationTypeService = getDelegationTypeService( di.getDelegationId() );
 725  
                                 // get the principals and groups for this delegation
 726  
                                 // purge any entries that do not match per the type service
 727  0
                                 if ( delegationTypeService == null || delegationTypeService.doesDelegationQualifierMatchQualification( qualification, di.getQualifier() )) {
 728  
                                         // check if a role type which needs to be resolved
 729  0
                                         if ( di.getMemberTypeCode().equals( Role.ROLE_MEMBER_TYPE ) ) {
 730  0
                                             i.remove();
 731  
                                     // loop over delegation roles and extract the role IDs where the qualifications match
 732  0
                                         ArrayList<String> roleIdTempList = new ArrayList<String>( 1 );
 733  0
                                         roleIdTempList.add( di.getMemberId() );
 734  
 
 735  
                                         // get the members of this role
 736  0
                                     Collection<RoleMembershipInfo> delegateMembers = getRoleMembers(roleIdTempList, qualification, false, foundRoleTypeMembers);
 737  
                                     // loop over the role members and create the needed DelegationInfo objects
 738  0
                                     for ( RoleMembershipInfo rmi : delegateMembers ) {
 739  0
                                             i.add(
 740  
                                                             new DelegateInfo(
 741  
                                                                             di.getDelegationId(),
 742  
                                                                             di.getDelegationTypeCode(),
 743  
                                                                             rmi.getMemberId(),
 744  
                                                                             rmi.getMemberTypeCode(),
 745  
                                                                             di.getRoleMemberId(),
 746  
                                                                             di.getQualifier() ) );
 747  
                                     } // delegate member loop
 748  0
                                         } // if is role member type
 749  
                                 } else { // delegation does not match - remove from list
 750  0
                                         i.remove();
 751  
                                 }
 752  0
                         }
 753  0
                 }
 754  0
     }
 755  
 
 756  
     /**
 757  
      * @see org.kuali.rice.kim.service.RoleService#principalHasRole(java.lang.String, java.util.List, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 758  
      */
 759  
     public boolean principalHasRole(String principalId, List<String> roleIds, AttributeSet qualification) {
 760  0
             return principalHasRole( principalId, roleIds, qualification, true );
 761  
     }
 762  
 
 763  
     /**
 764  
      * @see org.kuali.rice.kim.service.RoleService#getPrincipalIdSubListWithRole(java.util.List, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
 765  
      */
 766  
     public List<String> getPrincipalIdSubListWithRole( List<String> principalIds, String roleNamespaceCode, String roleName, AttributeSet qualification ) {
 767  0
             List<String> subList = new ArrayList<String>();
 768  0
             RoleImpl role = getRoleImplByName( roleNamespaceCode, roleName );
 769  0
             for ( String principalId : principalIds ) {
 770  0
                     if ( principalHasRole( principalId, Collections.singletonList( role.getRoleId() ), qualification ) ) {
 771  0
                             subList.add( principalId );
 772  
                     }
 773  
             }
 774  0
             return subList;
 775  
     }
 776  
 
 777  
 //    protected Map<String,List<RoleMembershipInfo>> getRoleIdToMembershipMap( List<RoleMemberImpl> roleMembers, AttributeSet qualifications, Map<String,KimRoleTypeService> roleTypeServices, List<RoleMembershipInfo> finalResults, List<String> matchingRoleIds, boolean includeNullServiceMembers, boolean failFast ) {
 778  
 //            Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap = new HashMap<String,List<RoleMembershipInfo>>();
 779  
 //            for ( RoleMemberImpl rm : roleMembers ) {
 780  
 //                        RoleMembershipInfo mi = new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier() );
 781  
 //                        List<RoleMembershipInfo> lrmi = roleIdToMembershipMap.get( mi.getRoleId() );
 782  
 //                        if ( lrmi == null ) {
 783  
 //                                lrmi = new ArrayList<RoleMembershipInfo>();
 784  
 //                                roleIdToMembershipMap.put( mi.getRoleId(), lrmi );
 785  
 //                        }
 786  
 //                        lrmi.add( mi );
 787  
 //                    // if the role type service is null, assume that all qualifiers match
 788  
 //                        if ( roleTypeServices.get( rm.getRoleId() ) == null ) {
 789  
 //                                if ( failFast ) {
 790  
 //                                        return roleIdToMembershipMap;
 791  
 //                                }
 792  
 //                        } else {
 793  
 //                        }
 794  
 //            }
 795  
 //            return roleIdToMembershipMap;
 796  
 //    }
 797  
 
 798  
     /**
 799  
      * Helper method used by principalHasRole to build the role ID -> list of members map.
 800  
      *
 801  
      * @return <b>true</b> if no further checks are needed because no role service is defined
 802  
      */
 803  
     protected boolean getRoleIdToMembershipMap( Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap, List<RoleMemberImpl> roleMembers ) {
 804  0
             for ( RoleMemberImpl rm : roleMembers ) {
 805  0
                         RoleMembershipInfo mi = new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier() );
 806  
                     // if the role type service is null, assume that all qualifiers match
 807  0
                         if ( getRoleTypeService( rm.getRoleId() ) == null ) {
 808  0
                                 return true;
 809  
                         } else {
 810  0
                                 List<RoleMembershipInfo> lrmi = roleIdToMembershipMap.get( mi.getRoleId() );
 811  0
                                 if ( lrmi == null ) {
 812  0
                                         lrmi = new ArrayList<RoleMembershipInfo>();
 813  0
                                         roleIdToMembershipMap.put( mi.getRoleId(), lrmi );
 814  
                                 }
 815  0
                                 lrmi.add( mi );
 816  
                         }
 817  0
             }
 818  0
             return false;
 819  
           }
 820  
 
 821  
         private List<RoleMemberImpl> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, Set<String> roleIds, AttributeSet qualification) {
 822  0
             List<String> copyRoleIds = new ArrayList(roleIds);
 823  0
             List<RoleMemberImpl> rms = new ArrayList<RoleMemberImpl>();
 824  
             
 825  0
             for(String roleId : roleIds) {
 826  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 827  0
                     if(roleTypeService != null) {
 828  0
                             List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 829  0
                             if(CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 830  0
                                     copyRoleIds.remove(roleId);
 831  0
                                     rms.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(roleId), groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 832  
                             }
 833  
                     }
 834  0
             }
 835  0
             if(CollectionUtils.isNotEmpty(copyRoleIds)) {
 836  0
                     rms.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(copyRoleIds, groupIds, null));
 837  
             }
 838  0
             return rms;
 839  
         }
 840  
         
 841  
     protected boolean principalHasRole(String principalId, List<String> roleIds, AttributeSet qualification, boolean checkDelegations ) {
 842  0
             if ( StringUtils.isBlank( principalId ) ) {
 843  0
                     return false;
 844  
             }
 845  0
             Set<String> allRoleIds = new HashSet<String>();
 846  
             // remove inactive roles
 847  0
             for ( String roleId : roleIds ) {
 848  0
                     if ( isRoleActive(roleId) ) {
 849  0
                             allRoleIds.add(roleId);
 850  
                     }
 851  
             }
 852  
             // short-circuit if no roles match
 853  0
             if ( allRoleIds.isEmpty() ) {
 854  0
                     return false;
 855  
             }
 856  
             // for efficiency, retrieve all roles and store in a map
 857  0
             Map<String,RoleImpl> roles = getRoleImplMap(allRoleIds);
 858  
             // get all roles to which the principal is assigned
 859  0
             List<String> copyRoleIds = new ArrayList(allRoleIds);
 860  0
             List<RoleMemberImpl> rps = new ArrayList<RoleMemberImpl>();
 861  
             
 862  0
             for(String roleId : allRoleIds) {
 863  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 864  0
                     if(roleTypeService != null) {
 865  0
                             List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 866  0
                             if(CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 867  0
                                     copyRoleIds.remove(roleId);
 868  0
                                     rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collections.singletonList(roleId), principalId, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 869  
                             }  
 870  
                     }
 871  0
             }
 872  0
             if(CollectionUtils.isNotEmpty(copyRoleIds)) {
 873  0
                     rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(copyRoleIds, principalId, null));
 874  
             }
 875  
 
 876  
             // if the qualification is null and the role list is not, then any role in the list will match
 877  
             // so since the role ID list is not blank, we can return true at this point
 878  0
             if ( (qualification == null || qualification.isEmpty()) && !rps.isEmpty() ) {
 879  0
                     return true;
 880  
             }
 881  
 
 882  
             // check each membership to see if the principal matches
 883  
 
 884  
             // build a map of role ID to membership information
 885  
             // this will be used for later qualification checks
 886  0
             Map<String,List<RoleMembershipInfo>> roleIdToMembershipMap = new HashMap<String,List<RoleMembershipInfo>>();
 887  0
             if ( getRoleIdToMembershipMap( roleIdToMembershipMap, rps ) ) {
 888  0
                     return true;
 889  
             }
 890  
 
 891  
             // perform the checks against the role type services
 892  0
                 for ( String roleId : roleIdToMembershipMap.keySet() ) {
 893  
                     try {
 894  0
                             KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 895  0
                             if ( !roleTypeService.doRoleQualifiersMatchQualification( qualification, roleIdToMembershipMap.get( roleId ) ).isEmpty() ) {
 896  0
                                     return true;
 897  
                             }
 898  0
                     } catch ( Exception ex ) {
 899  0
                 LOG.warn( "Unable to find role type service with id: " + roleId );
 900  0
             }
 901  
                 }
 902  
 
 903  
             // find the groups that the principal belongs to
 904  0
             List<String> principalGroupIds = getIdentityManagementService().getGroupIdsForPrincipal(principalId);
 905  
             // find the role/group associations
 906  0
             if ( !principalGroupIds.isEmpty() ) {
 907  0
                     List<RoleMemberImpl> rgs = getStoredRoleGroupsUsingExactMatchOnQualification(principalGroupIds, allRoleIds, qualification); 
 908  0
                         roleIdToMembershipMap.clear(); // clear the role/member map for further use
 909  0
                     if ( getRoleIdToMembershipMap( roleIdToMembershipMap, rgs ) ) {
 910  0
                             return true;
 911  
                     }
 912  
 
 913  
                     // perform the checks against the role type services
 914  0
                         for ( String roleId : roleIdToMembershipMap.keySet() ) {
 915  
                             try {
 916  0
                                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 917  0
                                     if ( !roleTypeService.doRoleQualifiersMatchQualification( qualification, roleIdToMembershipMap.get( roleId ) ).isEmpty() ) {
 918  0
                                             return true;
 919  
                                     }
 920  0
                             } catch ( Exception ex ) {
 921  0
                     LOG.warn( "Unable to find role type service with id: " + roleId );
 922  0
                 }
 923  
                         }
 924  
             }
 925  
 
 926  
             // check member roles
 927  
             // first, check that the qualifiers on the role membership match
 928  
             // then, perform a principalHasRole on the embedded role
 929  0
             List<RoleMemberImpl> rrs = getStoredRoleMembersForRoleIds( roleIds, Role.ROLE_MEMBER_TYPE, null );
 930  0
             for ( RoleMemberImpl rr : rrs ) {
 931  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( rr.getRoleId() );
 932  0
                     if ( roleTypeService != null ) {
 933  
                             //it is possible that the the roleTypeService is coming from a remote application 
 934  
                         // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 935  
                         try {
 936  0
                             if ( roleTypeService.doesRoleQualifierMatchQualification( qualification, rr.getQualifier() ) ) {
 937  0
                         RoleImpl memberRole = getRoleImpl( rr.getMemberId() );
 938  0
                                             AttributeSet nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(
 939  
                                                     roles.get(rr.getRoleId()).getNamespaceCode(),
 940  
                                                     roles.get(rr.getRoleId()).getRoleName(),
 941  
                                 memberRole.getNamespaceCode(),
 942  
                                 memberRole.getRoleName(),
 943  
                                 qualification );
 944  0
                         ArrayList<String> roleIdTempList = new ArrayList<String>( 1 );
 945  0
                         roleIdTempList.add( rr.getMemberId() );
 946  0
                                         if ( principalHasRole( principalId, roleIdTempList, nestedRoleQualification, true ) ) {
 947  0
                                                 return true;
 948  
                                         }
 949  
                                 }        
 950  0
                             } catch (Exception ex) {
 951  0
                     LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + rr.getRoleId(), ex);
 952  
                     //return false; 
 953  0
                 }
 954  
                     } else {
 955  
                             // no qualifiers - role is always used - check membership
 956  0
                                 ArrayList<String> roleIdTempList = new ArrayList<String>( 1 );
 957  0
                                 roleIdTempList.add( rr.getMemberId() );
 958  
                                 // no role type service, so can't convert qualification - just pass as is
 959  0
                                 if ( principalHasRole( principalId, roleIdTempList, qualification, true ) ) {
 960  0
                                         return true;
 961  
                                 }
 962  
                     }
 963  
                 
 964  0
             }
 965  
 
 966  
 
 967  
             // check for application roles and extract principals and groups from that - then check them against the
 968  
             // role type service passing in the qualification and principal - the qualifier comes from the
 969  
             // external system (application)
 970  
 
 971  
             // loop over the allRoleIds list
 972  0
             for ( String roleId : allRoleIds ) {
 973  0
                         RoleImpl role = roles.get( roleId );
 974  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( roleId );
 975  
                     // check if an application role
 976  
                     //it is possible that the the roleTypeService is coming from a remote application 
 977  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 978  
             try {
 979  0
                         if ( isApplicationRoleType(role.getKimTypeId(), roleTypeService)  ) {
 980  0
                                 if ( roleTypeService.hasApplicationRole(principalId, principalGroupIds, role.getNamespaceCode(), role.getRoleName(), qualification) ) {
 981  0
                                         return true;
 982  
                                 }
 983  
                         }
 984  0
             } catch (Exception ex) {
 985  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 986  
                 //return false; 
 987  0
             }
 988  0
             }
 989  
 
 990  
             // delegations
 991  0
             if ( checkDelegations ) {
 992  0
                     if ( matchesOnDelegation( allRoleIds, principalId, principalGroupIds, qualification ) ) {
 993  0
                             return true;
 994  
                     }
 995  
             }
 996  
 
 997  
             // NOTE: this logic is a little different from the getRoleMembers method
 998  
             // If there is no primary (matching non-delegate), this method will still return true
 999  0
             return false;
 1000  
     }
 1001  
 
 1002  
     /**
 1003  
      * Support method for principalHasRole.  Checks delegations on the passed in roles for the given principal and groups.  (It's assumed that the principal
 1004  
      * belongs to the given groups.)
 1005  
      *
 1006  
      * Delegation checks are mostly the same as role checks except that the delegation itself is qualified against the original role (like a RolePrincipal
 1007  
      * or RoleGroup.)  And then, the members of that delegation may have additional qualifiers which are not part of the original role qualifiers.
 1008  
      *
 1009  
      * For example:
 1010  
      *
 1011  
      * A role could be qualified by organization.  So, there is a person in the organization with primary authority for that org.  But, then they delegate authority
 1012  
      * for that organization (not their authority - the delegation is attached to the org.)  So, in this case the delegation has a qualifier of the organization
 1013  
      * when it is attached to the role.
 1014  
      *
 1015  
      * The principals then attached to that delegation (which is specific to the organization), may have additional qualifiers.
 1016  
      * For Example: dollar amount range, effective dates, document types.
 1017  
      * As a subsequent step, those qualifiers are checked against the qualification passed in from the client.
 1018  
      */
 1019  
     protected boolean matchesOnDelegation( Set<String> allRoleIds, String principalId, List<String> principalGroupIds, AttributeSet qualification ) {
 1020  
             // get the list of delegations for the roles
 1021  0
             Map<String,KimDelegationImpl> delegations = getStoredDelegationImplMapFromRoleIds(allRoleIds);
 1022  
             // loop over the delegations - determine those which need to be inspected more directly
 1023  0
             for ( KimDelegationImpl delegation : delegations.values() ) {
 1024  
                 // check if each one matches via the original role type service
 1025  0
                     if ( !delegation.isActive() ) {
 1026  0
                             continue;
 1027  
                     }
 1028  0
                     KimRoleTypeService roleTypeService = getRoleTypeService( delegation.getRoleId() );
 1029  0
                     for ( KimDelegationMemberImpl dmi : delegation.getMembers() ) {
 1030  0
                             if ( !dmi.isActive() ) {
 1031  0
                                     continue;
 1032  
                             }
 1033  
                             // check if this delegation record applies to the given person
 1034  0
                             if ( dmi.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE )
 1035  
                                             && !dmi.getMemberId().equals( principalId ) ) {
 1036  0
                                     continue; // no match on principal
 1037  
                             }
 1038  
                             // or if a group
 1039  0
                             if ( dmi.getMemberTypeCode().equals( Role.GROUP_MEMBER_TYPE )
 1040  
                                             && !principalGroupIds.contains( dmi.getMemberId() ) ) {
 1041  0
                                     continue; // no match on group
 1042  
                             }
 1043  
                             // or if a role
 1044  0
                             if ( dmi.getMemberTypeCode().equals( Role.ROLE_MEMBER_TYPE )
 1045  
                                             && !principalHasRole( principalId, Collections.singletonList( dmi.getMemberId() ), qualification, false ) ) {
 1046  0
                                     continue; // no match on role
 1047  
                             }
 1048  
                             // OK, the member matches the current user, now check the qualifications
 1049  
 
 1050  
                             // NOTE: this compare is slightly different than the member enumeration
 1051  
                             // since the requested qualifier is always being used rather than
 1052  
                             // the role qualifier for the member (which is not available)
 1053  
                             
 1054  
                                //it is possible that the the roleTypeService is coming from a remote application 
 1055  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 1056  
                             try {
 1057  0
                                     if ( roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification( qualification, dmi.getQualifier() ) ) {
 1058  0
                                             continue; // no match - skip to next record
 1059  
                                     }
 1060  0
                             } catch (Exception ex) {
 1061  0
                                     LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + dmi.getQualifier(), ex);
 1062  0
                                     continue;
 1063  0
                             }
 1064  
                             
 1065  
                                     // role service matches this qualifier
 1066  
                                 // now try the delegation service
 1067  0
                                 KimDelegationTypeService delegationTypeService = getDelegationTypeService( dmi.getDelegationId());
 1068  
                                 // QUESTION: does the qualifier map need to be merged with the main delegation qualification?
 1069  0
                                 if ( delegationTypeService != null && !delegationTypeService.doesDelegationQualifierMatchQualification(qualification, dmi.getQualifier())) {
 1070  0
                                         continue; // no match - skip to next record
 1071  
                                 }
 1072  
                                 // check if a role member ID is present on the delegation record
 1073  
                                 // if so, check that the original role member would match the given qualifiers
 1074  0
                                 if ( StringUtils.isNotBlank( dmi.getRoleMemberId() ) ) {
 1075  0
                                         RoleMemberImpl rm = getRoleMemberImpl( dmi.getRoleMemberId() );
 1076  0
                                         if ( rm != null ) {
 1077  
                                                 // check that the original role member's is active and that their
 1078  
                                                 // qualifier would have matched this request's
 1079  
                                                 // qualifications (that the original person would have the permission/responsibility
 1080  
                                                 // for an action)
 1081  
                                                 // this prevents a role-membership based delegation from surviving the inactivation/
 1082  
                                                 // changing of the main person's role membership
 1083  0
                                                 if ( !rm.isActive() ) {
 1084  0
                                                         continue;
 1085  
                                                 }
 1086  0
                                                 AttributeSet roleQualifier = rm.getQualifier();
 1087  
                                                //it is possible that the the roleTypeService is coming from a remote application 
 1088  
                                // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 1089  
                                                try {
 1090  0
                                                        if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, roleQualifier) ) {
 1091  0
                                                                continue;
 1092  
                                                        }
 1093  0
                                                } catch (Exception ex) {
 1094  0
                                                        LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + roleQualifier, ex);
 1095  0
                                                 continue;
 1096  0
                                         }
 1097  0
                                 } else {
 1098  0
                                         LOG.warn( "Unknown role member ID cited in the delegation member table:" );
 1099  0
                                         LOG.warn( "       delegationMemberId: " + dmi.getDelegationMemberId() + " / roleMemberId: " + dmi.getRoleMemberId() );
 1100  
                                 }
 1101  
                         }
 1102  
                         // all tests passed, return true
 1103  0
                         return true;
 1104  
                     }
 1105  0
             }
 1106  0
             return false;
 1107  
     }
 1108  
 
 1109  
     
 1110  
     // --------------------
 1111  
     // Support Methods
 1112  
     // --------------------
 1113  
 
 1114  
         
 1115  
 
 1116  
     public List<RoleImpl> getRolesSearchResults(java.util.Map<String,String> fieldValues) {
 1117  0
             return getRoleDao().getRoles(fieldValues);
 1118  
     }
 1119  
 
 1120  
     /**
 1121  
      * @see org.kuali.rice.kim.service.RoleService#roleInactivated(java.lang.String)
 1122  
      */
 1123  
     public void roleInactivated(String roleId){
 1124  0
             Timestamp yesterday = new Timestamp( new java.util.Date().getTime() - (24*60*60*1000) );
 1125  0
             List<String> roleIds = new ArrayList<String>();
 1126  0
             roleIds.add(roleId);
 1127  0
             inactivateRoleMemberships(roleIds, yesterday);
 1128  0
             inactivateRoleDelegations(roleIds, yesterday);
 1129  0
             inactivateMembershipsForRoleAsMember(roleIds, yesterday);
 1130  0
     }
 1131  
     
 1132  
     private void inactivateRoleMemberships(List<String> roleIds, Timestamp yesterday){
 1133  0
             List<RoleMemberImpl> roleMembers = getStoredRoleMembersForRoleIds(roleIds, null, null);
 1134  0
             for(RoleMemberImpl rm: roleMembers){
 1135  0
                     rm.setActiveToDate(yesterday);
 1136  
             }
 1137  0
             getBusinessObjectService().save(roleMembers);
 1138  0
             getIdentityManagementNotificationService().roleUpdated();
 1139  0
     }
 1140  
 
 1141  
     private void inactivateMembershipsForRoleAsMember(List<String> roleIds, Timestamp yesterday){
 1142  0
             List<RoleMemberImpl> roleMembers = getStoredRoleMembershipsForRoleIdsAsMembers(roleIds, null);
 1143  0
             for(RoleMemberImpl rm: roleMembers){
 1144  0
                     rm.setActiveToDate(yesterday);
 1145  
             }
 1146  0
             getBusinessObjectService().save(roleMembers);
 1147  0
             getIdentityManagementNotificationService().roleUpdated();
 1148  0
     }
 1149  
 
 1150  
     private void inactivateRoleDelegations(List<String> roleIds, Timestamp yesterday){
 1151  0
             List<KimDelegationImpl> delegations = getStoredDelegationImplsForRoleIds(roleIds);
 1152  0
             for(KimDelegationImpl delegation: delegations){
 1153  0
                     delegation.setActive(false);
 1154  0
                     for(KimDelegationMemberImpl delegationMember: delegation.getMembers()){
 1155  0
                             delegationMember.setActiveToDate(yesterday);
 1156  
                     }
 1157  
             }
 1158  0
             getBusinessObjectService().save(delegations);
 1159  0
             getIdentityManagementNotificationService().delegationUpdated();
 1160  0
     }
 1161  
     
 1162  
     /**
 1163  
      * @see org.kuali.rice.kim.service.RoleService#principalInactivated(java.lang.String)
 1164  
      */
 1165  
     public void principalInactivated(String principalId) {
 1166  0
             Timestamp yesterday = new Timestamp( System.currentTimeMillis() - (24*60*60*1000) );
 1167  0
             inactivatePrincipalRoleMemberships(principalId, yesterday);
 1168  0
             inactivatePrincipalGroupMemberships(principalId, yesterday);
 1169  0
             inactivatePrincipalDelegations(principalId, yesterday);
 1170  0
             inactivateApplicationRoleMemberships( principalId, yesterday );
 1171  0
     }
 1172  
 
 1173  
     @SuppressWarnings("unchecked")
 1174  
         protected void inactivateApplicationRoleMemberships( String principalId, Timestamp yesterday){
 1175  
             // get all role type services
 1176  0
             Collection<KimTypeInfo> types = KIMServiceLocator.getTypeInfoService().getAllTypes();
 1177  
             // create sub list of only application role types
 1178  0
             ArrayList<KimTypeInfo> applicationRoleTypes = new ArrayList<KimTypeInfo>( types.size() );
 1179  0
             for ( KimTypeInfo typeInfo : types ) {
 1180  0
                     KimRoleTypeService service = getRoleTypeService(typeInfo);
 1181  
                 try {//log service unavailable as WARN error
 1182  0
                             if ( isApplicationRoleType(typeInfo.getKimTypeId(), service)) {
 1183  0
                                             applicationRoleTypes.add(typeInfo);
 1184  
                                     }
 1185  0
                 }catch(Exception e) {
 1186  0
                             LOG.warn(e.getMessage(), e);
 1187  0
                     }
 1188  0
             }                        
 1189  
                         
 1190  0
             Map<String,Object> roleLookupMap = new HashMap<String, Object>(2);
 1191  0
             roleLookupMap.put( KIMPropertyConstants.Role.ACTIVE, "Y");
 1192  
             // loop over application types
 1193  0
             for ( KimTypeInfo typeInfo : applicationRoleTypes ) {
 1194  0
                     KimRoleTypeService service = getRoleTypeService(typeInfo);
 1195  
                     // get all roles for that type
 1196  0
                 roleLookupMap.put( KIMPropertyConstants.Role.KIM_TYPE_ID, typeInfo.getKimTypeId());
 1197  0
                     Collection<RoleImpl> roles = getBusinessObjectService().findMatching( RoleImpl.class, roleLookupMap);
 1198  
                 // loop over all roles in those types
 1199  0
                     for ( RoleImpl role : roles ) {
 1200  
                         // call the principalInactivated() on the role type service for each role
 1201  0
                             service.principalInactivated(principalId, role.getNamespaceCode(), role.getRoleName());
 1202  
                     }
 1203  0
             }
 1204  0
     }
 1205  
     
 1206  
     protected void inactivatePrincipalRoleMemberships(String principalId, Timestamp yesterday){
 1207  
             // go through all roles and post-date them
 1208  0
             List<RoleMemberImpl> roleMembers = getStoredRolePrincipalsForPrincipalIdAndRoleIds(null, principalId, null);
 1209  0
             Set<String> roleIds = new HashSet<String>( roleMembers.size() );
 1210  0
             for ( RoleMemberImpl rm : roleMembers ) {
 1211  0
                     rm.setActiveToDate(yesterday);
 1212  0
                     roleIds.add(rm.getRoleId()); // add to the set of IDs
 1213  
             }
 1214  0
             getBusinessObjectService().save(roleMembers);
 1215  
             // find all distinct role IDs and type services
 1216  0
             for ( String roleId : roleIds ) {
 1217  0
                     RoleImpl role = getRoleImpl(roleId);
 1218  0
                     KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 1219  
                     try {
 1220  0
                             if ( roleTypeService != null ) {
 1221  0
                                     roleTypeService.principalInactivated( principalId, role.getNamespaceCode(), role.getRoleName() );
 1222  
                             }
 1223  0
                     } catch ( Exception ex ) {
 1224  0
                             LOG.error( "Problem notifying role type service of principal inactivation: " + role.getKimRoleType().getKimTypeServiceName(), ex );
 1225  0
                     }
 1226  0
             }
 1227  0
             getIdentityManagementNotificationService().roleUpdated();
 1228  0
     }
 1229  
     
 1230  
     protected void inactivatePrincipalGroupMemberships(String principalId, Timestamp yesterday){
 1231  0
         List<GroupMembershipInfo> groupMemberInfos = getRoleDao().getGroupPrincipalsForPrincipalIdAndGroupIds(null, principalId);
 1232  0
         List<GroupMemberImpl> groupMembers = new ArrayList<GroupMemberImpl>(groupMemberInfos.size());
 1233  0
         for ( GroupMembershipInfo rm : groupMemberInfos ) {
 1234  0
             rm.setActiveToDate( new Date(yesterday.getTime()) );
 1235  0
             groupMembers.add(toGroupMemberImpl(rm));
 1236  
         }
 1237  
         
 1238  0
             getBusinessObjectService().save(groupMembers);
 1239  0
     }
 1240  
 
 1241  
     protected void inactivatePrincipalDelegations(String principalId, Timestamp yesterday){
 1242  0
             List<KimDelegationMemberImpl> delegationMembers = getStoredDelegationPrincipalsForPrincipalIdAndDelegationIds(null, principalId);
 1243  0
             for ( KimDelegationMemberImpl rm : delegationMembers ) {
 1244  0
                     rm.setActiveToDate(yesterday);
 1245  
             }
 1246  0
             getBusinessObjectService().save(delegationMembers);
 1247  0
             getIdentityManagementNotificationService().delegationUpdated();
 1248  0
     }
 1249  
 
 1250  
     public List<RoleMembershipInfo> getFirstLevelRoleMembers(List<String> roleIds){
 1251  0
             List<RoleMemberImpl> rms = getStoredRoleMembersForRoleIds(roleIds, null, null);
 1252  0
             List<RoleMembershipInfo> roleMembershipInfoList = new ArrayList<RoleMembershipInfo>();
 1253  0
             for ( RoleMemberImpl rm : rms ) {
 1254  0
                     roleMembershipInfoList.add(new RoleMembershipInfo( rm.getRoleId(), rm.getRoleMemberId(), rm.getMemberId(), rm.getMemberTypeCode(), rm.getQualifier()));
 1255  
             }
 1256  0
             return roleMembershipInfoList;
 1257  
     }
 1258  
     
 1259  
 
 1260  
     /**
 1261  
      * When a group is inactivated, inactivate the memberships of principals in that group 
 1262  
          * and the memberships of that group in roles 
 1263  
      * 
 1264  
      * @see org.kuali.rice.kim.service.GroupUpdateService#groupInactivated(java.lang.String)
 1265  
      */
 1266  
     public void groupInactivated(String groupId) {
 1267  0
             Timestamp yesterday = new Timestamp( System.currentTimeMillis() - (24*60*60*1000) );
 1268  0
             List<String> groupIds = new ArrayList<String>();
 1269  0
             groupIds.add(groupId);
 1270  0
             inactivatePrincipalGroupMemberships(groupIds, yesterday);
 1271  0
             inactivateGroupRoleMemberships(groupIds, yesterday);
 1272  0
     }
 1273  
     
 1274  
     protected void inactivatePrincipalGroupMemberships(List<String> groupIds, Timestamp yesterday){
 1275  0
         List<GroupMembershipInfo> groupMemberInfos = getRoleDao().getGroupMembers(groupIds);
 1276  0
         List<GroupMemberImpl> groupMembers = new ArrayList<GroupMemberImpl>(groupMemberInfos.size());
 1277  0
         for ( GroupMembershipInfo rm : groupMemberInfos ) {
 1278  0
             rm.setActiveToDate( new Date(yesterday.getTime()) );
 1279  0
             groupMembers.add(toGroupMemberImpl(rm));
 1280  
         }
 1281  0
             getBusinessObjectService().save(groupMembers);
 1282  0
     }
 1283  
 
 1284  
     protected void inactivateGroupRoleMemberships(List<String> groupIds, Timestamp yesterday){
 1285  0
             List<RoleMemberImpl> roleMembersOfGroupType = getStoredRoleGroupsForGroupIdsAndRoleIds(null, groupIds, null);
 1286  0
             for(RoleMemberImpl rm: roleMembersOfGroupType){
 1287  0
                     rm.setActiveToDate(yesterday);
 1288  
             }
 1289  0
             getBusinessObjectService().save(roleMembersOfGroupType);
 1290  0
             getIdentityManagementNotificationService().roleUpdated();
 1291  0
     }
 1292  
     
 1293  
     protected GroupMemberImpl toGroupMemberImpl(GroupMembershipInfo kimGroupMember) {
 1294  0
         GroupMemberImpl groupMemberImpl = null;
 1295  
 
 1296  0
         if (kimGroupMember != null) {
 1297  0
             groupMemberImpl = new GroupMemberImpl();
 1298  0
             groupMemberImpl.setGroupId(kimGroupMember.getGroupId());
 1299  0
             groupMemberImpl.setGroupMemberId(kimGroupMember.getGroupMemberId());
 1300  0
             groupMemberImpl.setMemberId(kimGroupMember.getMemberId());
 1301  0
             groupMemberImpl.setMemberTypeCode(kimGroupMember.getMemberTypeCode());
 1302  0
                         if (kimGroupMember.getActiveFromDate() != null) {
 1303  0
                                 groupMemberImpl.setActiveFromDate(new java.sql.Timestamp(kimGroupMember.getActiveFromDate().getTime()));
 1304  
                         }
 1305  0
                         if (kimGroupMember.getActiveToDate() != null) {
 1306  0
                                 groupMemberImpl.setActiveToDate(new java.sql.Timestamp(kimGroupMember.getActiveToDate().getTime()));
 1307  
                         }
 1308  0
             groupMemberImpl.setVersionNumber(kimGroupMember.getVersionNumber());
 1309  
         }
 1310  
 
 1311  0
         return groupMemberImpl;
 1312  
     }
 1313  
 
 1314  
     public List<RoleMembershipInfo> findRoleMembers(Map<String,String> fieldValues){
 1315  0
             return getRoleDao().getRoleMembers(fieldValues);
 1316  
     }
 1317  
     
 1318  
     public List<DelegateMemberCompleteInfo> findDelegateMembersCompleteInfo(final Map<String, String> fieldValues){
 1319  0
             List<DelegateMemberCompleteInfo> delegateMembersCompleteInfo = new ArrayList<DelegateMemberCompleteInfo>();
 1320  
             DelegateMemberCompleteInfo delegateMemberCompleteInfo;
 1321  0
             List<KimDelegationImpl> delegations = (List<KimDelegationImpl>)getLookupService().findCollectionBySearchHelper(
 1322  
                                 KimDelegationImpl.class, fieldValues, true);
 1323  0
             if(delegations!=null && !delegations.isEmpty()){
 1324  0
                     Map<String, String> delegationMemberFieldValues = new HashMap<String, String>();
 1325  0
                     for(String key: fieldValues.keySet()){
 1326  0
                             if(key.startsWith(KimConstants.KimUIConstants.MEMBER_ID_PREFIX)){
 1327  0
                                     delegationMemberFieldValues.put(
 1328  
                                                     key.substring(key.indexOf(
 1329  
                                                     KimConstants.KimUIConstants.MEMBER_ID_PREFIX)+KimConstants.KimUIConstants.MEMBER_ID_PREFIX.length()), 
 1330  
                                                     fieldValues.get(key));
 1331  
                             }
 1332  
                     }
 1333  0
                         StringBuffer memberQueryString = new StringBuffer();
 1334  0
                     for(KimDelegationImpl delegation: delegations)
 1335  0
                             memberQueryString.append(delegation.getDelegationId()+KimConstants.KimUIConstants.OR_OPERATOR);
 1336  0
                     delegationMemberFieldValues.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, 
 1337  
                                     KimCommonUtils.stripEnd(memberQueryString.toString(), KimConstants.KimUIConstants.OR_OPERATOR));
 1338  0
                     List<KimDelegationMemberImpl> delegateMembers = (List<KimDelegationMemberImpl>)getLookupService().findCollectionBySearchHelper(
 1339  
                                         KimDelegationMemberImpl.class, delegationMemberFieldValues, true);
 1340  
                     KimDelegationImpl delegationTemp;
 1341  0
                     for(KimDelegationMemberImpl delegateMember: delegateMembers){
 1342  0
                             delegateMemberCompleteInfo = delegateMember.toSimpleInfo();
 1343  0
                             delegationTemp = getDelegationImpl(delegations, delegateMember.getDelegationId());
 1344  0
                             delegateMemberCompleteInfo.setRoleId(delegationTemp.getRoleId());
 1345  0
                             delegateMemberCompleteInfo.setDelegationTypeCode(delegationTemp.getDelegationTypeCode());
 1346  0
                                 Object member = getMember(delegateMemberCompleteInfo.getMemberTypeCode(), delegateMemberCompleteInfo.getMemberId());
 1347  0
                                 delegateMemberCompleteInfo.setMemberName(getMemberName(member));
 1348  0
                                 delegateMemberCompleteInfo.setMemberNamespaceCode(getMemberNamespaceCode(member));
 1349  0
                                 delegateMembersCompleteInfo.add(delegateMemberCompleteInfo);
 1350  0
                     }
 1351  
 
 1352  
             }
 1353  0
             return delegateMembersCompleteInfo;
 1354  
     }
 1355  
 
 1356  
     public DelegateTypeInfo getDelegateTypeInfo(String roleId, String delegationTypeCode){
 1357  0
             KimDelegationImpl delegation = getDelegationOfType(roleId, delegationTypeCode);
 1358  0
             if(delegation==null) return null;
 1359  0
             return delegation.toSimpleInfo();
 1360  
     }
 1361  
 
 1362  
     public DelegateTypeInfo getDelegateTypeInfoById(String delegationId){
 1363  0
                 if(delegationId==null) return null;
 1364  0
                 KimDelegationImpl delegation = getKimDelegationImpl(delegationId);
 1365  0
             if(delegation==null) return null;
 1366  0
         return delegation.toSimpleInfo();
 1367  
     }
 1368  
 
 1369  
         public List<DelegateMemberCompleteInfo> getDelegationMembersByDelegationId(String delegationId){
 1370  0
                 KimDelegationImpl delegation = getKimDelegationImpl(delegationId);
 1371  0
         if(delegation==null) return null;
 1372  
         
 1373  0
         return getDelegationInfoForDelegation(delegation);
 1374  
         }
 1375  
         
 1376  
         public DelegateMemberCompleteInfo getDelegationMemberByDelegationAndMemberId(String delegationId, String delegationMemberId){
 1377  0
                 KimDelegationImpl delegation = getKimDelegationImpl(delegationId);
 1378  0
         KimDelegationMemberImpl delegationMember = getKimDelegationMemberImplByDelegationAndId(delegationId, delegationMemberId);
 1379  
 
 1380  0
         return getDelegateCompleteInfo(delegation, delegationMember);
 1381  
         }
 1382  
         
 1383  
         public DelegateMemberCompleteInfo getDelegationMemberById(@WebParam(name="delegationMemberId") String delegationMemberId){
 1384  0
                 KimDelegationMemberImpl delegationMember = getKimDelegationMemberImpl(delegationMemberId);
 1385  0
         if(delegationMember==null) return null;
 1386  
         
 1387  0
         KimDelegationImpl delegation = getKimDelegationImpl(delegationMember.getDelegationId());
 1388  
 
 1389  0
         return getDelegateCompleteInfo(delegation, delegationMember);
 1390  
         }
 1391  
 
 1392  
         private List<DelegateMemberCompleteInfo> getDelegationInfoForDelegation(KimDelegationImpl delegation){
 1393  0
                 if(delegation==null || delegation.getMembers()==null) return null;
 1394  0
         List<DelegateMemberCompleteInfo> delegateInfoList = new ArrayList<DelegateMemberCompleteInfo>();
 1395  0
                 for(KimDelegationMemberImpl delegationMember: delegation.getMembers()){
 1396  0
                 delegateInfoList.add(getDelegateCompleteInfo(delegation, delegationMember));
 1397  
         }
 1398  0
         return delegateInfoList;
 1399  
         }
 1400  
 
 1401  
         private DelegateMemberCompleteInfo getDelegateCompleteInfo(KimDelegationImpl delegation, KimDelegationMemberImpl delegationMember){
 1402  0
                 if(delegation==null || delegationMember==null) return null;
 1403  0
                 DelegateMemberCompleteInfo delegateMemberCompleteInfo = delegationMember.toSimpleInfo();
 1404  0
                 delegateMemberCompleteInfo.setDelegationTypeCode(delegation.getDelegationTypeCode());
 1405  0
                 Object member = getMember(delegationMember.getMemberTypeCode(), delegationMember.getMemberId());
 1406  0
                 delegateMemberCompleteInfo.setMemberName(getMemberName(member));
 1407  0
                 delegateMemberCompleteInfo.setMemberNamespaceCode(getMemberNamespaceCode(member));
 1408  0
                 return delegateMemberCompleteInfo;
 1409  
         }
 1410  
 
 1411  
         public List<RoleResponsibilityInfo> getRoleResponsibilities(String roleId){
 1412  0
                 Map<String, String> criteria = new HashMap<String, String>(1);                
 1413  0
                 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, roleId);
 1414  0
                 List<RoleResponsibilityImpl> responsibilityImpls = (List<RoleResponsibilityImpl>)
 1415  
                         getBusinessObjectService().findMatching(RoleResponsibilityImpl.class, criteria);
 1416  0
                 List<RoleResponsibilityInfo> roleResponsibilities = new ArrayList<RoleResponsibilityInfo>();
 1417  
                 RoleResponsibilityInfo roleResponsibilityInfo;
 1418  0
                 for(RoleResponsibilityImpl roleResponsibilityImpl: responsibilityImpls){
 1419  0
                         roleResponsibilityInfo = new RoleResponsibilityInfo();
 1420  0
                         KimCommonUtils.copyProperties(roleResponsibilityInfo, roleResponsibilityImpl);
 1421  0
                         roleResponsibilities.add(roleResponsibilityInfo);
 1422  
                 }
 1423  0
                 return roleResponsibilities;
 1424  
         }
 1425  
 
 1426  
     public void applicationRoleMembershipChanged( String roleId ) {
 1427  0
             getResponsibilityInternalService().updateActionRequestsForRoleChange(roleId);
 1428  0
     }
 1429  
 
 1430  
 }