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