Coverage Report - org.kuali.rice.kim.impl.role.RoleServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RoleServiceImpl
0%
0/606
0%
0/334
4.459
 
 1  
 package org.kuali.rice.kim.impl.role;
 2  
 
 3  
 import org.apache.commons.collections.CollectionUtils;
 4  
 import org.apache.commons.lang.StringUtils;
 5  
 import org.apache.log4j.Logger;
 6  
 import org.kuali.rice.core.util.jaxb.MapStringStringAdapter;
 7  
 import org.kuali.rice.kim.api.common.delegate.DelegateMember;
 8  
 import org.kuali.rice.kim.api.common.delegate.DelegateType;
 9  
 import org.kuali.rice.kim.api.group.GroupMember;
 10  
 import org.kuali.rice.kim.api.role.Role;
 11  
 import org.kuali.rice.kim.api.role.RoleMember;
 12  
 import org.kuali.rice.kim.api.role.RoleMembership;
 13  
 import org.kuali.rice.kim.api.role.RoleResponsibility;
 14  
 import org.kuali.rice.kim.api.role.RoleResponsibilityAction;
 15  
 import org.kuali.rice.kim.api.role.RoleService;
 16  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 17  
 import org.kuali.rice.kim.api.type.KimType;
 18  
 import org.kuali.rice.kim.api.type.KimTypeService;
 19  
 import org.kuali.rice.kim.framework.type.KimDelegationTypeService;
 20  
 import org.kuali.rice.kim.framework.type.KimRoleTypeService;
 21  
 import org.kuali.rice.kim.impl.common.delegate.DelegateBo;
 22  
 import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
 23  
 import org.kuali.rice.kim.impl.group.GroupMemberBo;
 24  
 import org.kuali.rice.kim.impl.services.KIMServiceLocatorInternal;
 25  
 import org.kuali.rice.kim.impl.type.KimTypeBo;
 26  
 import org.kuali.rice.kim.service.KIMServiceLocatorWeb;
 27  
 import org.kuali.rice.kim.util.KIMPropertyConstants;
 28  
 import org.kuali.rice.kim.util.KimConstants;
 29  
 
 30  
 import javax.jws.WebParam;
 31  
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 32  
 import java.sql.Timestamp;
 33  
 import java.util.ArrayList;
 34  
 import java.util.Collection;
 35  
 import java.util.Collections;
 36  
 import java.util.Date;
 37  
 import java.util.HashMap;
 38  
 import java.util.HashSet;
 39  
 import java.util.List;
 40  
 import java.util.Map;
 41  
 import java.util.Set;
 42  
 import java.util.concurrent.TimeUnit;
 43  
 
 44  0
 public class RoleServiceImpl extends RoleServiceBase implements RoleService {
 45  0
     private static final Logger LOG = Logger.getLogger(RoleServiceImpl.class);
 46  
 
 47  
     @Override
 48  
     public Role getRole(@WebParam(name = "roleId") String roleId) {
 49  0
         RoleBo roleBo = getRoleBo(roleId);
 50  0
         if (roleBo == null) {
 51  0
             return null;
 52  
         }
 53  0
         return RoleBo.to(roleBo);
 54  
     }
 55  
 
 56  
     protected Map<String, RoleBo> getRoleBoMap(Collection<String> roleIds) {
 57  
         Map<String, RoleBo> result;
 58  
         // check for a non-null result in the cache, return it if found
 59  0
         if (roleIds.size() == 1) {
 60  0
             String roleId = roleIds.iterator().next();
 61  0
             RoleBo bo = getRoleBo(roleId);
 62  0
             if (bo.isActive()) {
 63  0
                 result = Collections.singletonMap(roleId, bo);
 64  
             } else {
 65  0
                 result = Collections.emptyMap();
 66  
             }
 67  0
         } else {
 68  0
             result = new HashMap<String, RoleBo>(roleIds.size());
 69  0
             for (String roleId : roleIds) {
 70  0
                 RoleBo bo = getRoleBo(roleId);
 71  0
                 if (bo.isActive()) {
 72  0
                     result.put(roleId, bo);
 73  
                 }
 74  0
             }
 75  
         }
 76  0
         return result;
 77  
     }
 78  
 
 79  
     @Override
 80  
     public List<Role> getRoles(@WebParam(name = "roleIds") List<String> roleIds) {
 81  0
         Collection<RoleBo> roleBos = getRoleBoMap(roleIds).values();
 82  0
         List<Role> roles = new ArrayList<Role>(roleBos.size());
 83  0
         for (RoleBo bo : roleBos) {
 84  0
             roles.add(RoleBo.to(bo));
 85  
         }
 86  0
         return roles;
 87  
     }
 88  
 
 89  
     @Override
 90  
     public Role getRoleByName(@WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName) {
 91  0
         RoleBo roleBo = getRoleBoByName(namespaceCode, roleName);
 92  0
         if (roleBo != null) {
 93  0
             return RoleBo.to(roleBo);
 94  
         }
 95  0
         return null;
 96  
     }
 97  
 
 98  
     @Override
 99  
     public String getRoleIdByName(@WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName) {
 100  0
         Role role = getRoleByName(namespaceCode, roleName);
 101  0
         if (role != null) {
 102  0
             return role.getId();
 103  
         } else {
 104  0
             return null;
 105  
         }
 106  
     }
 107  
 
 108  
     @Override
 109  
     public boolean isRoleActive(@WebParam(name = "roleId") String roleId) {
 110  0
         RoleBo roleBo = getRoleBo(roleId);
 111  0
         return roleBo != null && roleBo.isActive();
 112  
     }
 113  
 
 114  
     @Override
 115  
     public List<Map<String, String>> getRoleQualifiersForPrincipal(@WebParam(name = "principalId") String principalId,
 116  
                                                             @WebParam(name = "roleIds") List<String> roleIds,
 117  
                                                             @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 118  
 
 119  0
         List<Map<String, String>> results = new ArrayList<Map<String, String>>();
 120  
 
 121  0
         List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersUsingExactMatchOnQualification(principalId, null, roleIds, qualification);
 122  
 
 123  0
         Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>();
 124  0
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
 125  
             // gather up the qualifier sets and the service they go with
 126  0
             if (roleMemberBo.getMemberTypeCode().equals(Role.PRINCIPAL_MEMBER_TYPE)) {
 127  0
                 KimRoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId());
 128  0
                 if (roleTypeService != null) {
 129  0
                     List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId());
 130  0
                     if (las == null) {
 131  0
                         las = new ArrayList<RoleMembership>();
 132  0
                         roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las);
 133  
                     }
 134  0
                     RoleMembership mi = RoleMembership.Builder.create(
 135  
                             roleMemberBo.getRoleId(),
 136  
                             roleMemberBo.getRoleMemberId(),
 137  
                             roleMemberBo.getMemberId(),
 138  
                             roleMemberBo.getMemberTypeCode(),
 139  
                             roleMemberBo.getAttributes()).build();
 140  
 
 141  0
                     las.add(mi);
 142  0
                 } else {
 143  0
                     results.add(roleMemberBo.getAttributes());
 144  
                 }
 145  0
             }
 146  
         }
 147  0
         for (String roleId : roleIdToMembershipMap.keySet()) {
 148  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 149  
             //it is possible that the the roleTypeService is coming from a remote application
 150  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 151  
             try {
 152  0
                 List<RoleMembership> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification(qualification, roleIdToMembershipMap.get(roleId));
 153  0
                 for (RoleMembership rmi : matchingMembers) {
 154  0
                     results.add(rmi.getQualifier());
 155  
                 }
 156  0
             } catch (Exception ex) {
 157  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 158  0
             }
 159  0
         }
 160  0
         return results;
 161  
     }
 162  
 
 163  
     @Override
 164  
     public List<Map<String, String>> getRoleQualifiersForPrincipal(@WebParam(name = "principalId") String principalId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 165  0
         String roleId = getRoleIdByName(namespaceCode, roleName);
 166  0
         if (roleId == null) {
 167  0
             return new ArrayList<Map<String, String>>(0);
 168  
         }
 169  0
         return getNestedRoleQualifiersForPrincipal(principalId, Collections.singletonList(roleId), qualification);
 170  
     }
 171  
 
 172  
     @Override
 173  
     public List<Map<String, String>> getNestedRoleQualifiersForPrincipal(@WebParam(name = "principalId") String principalId, @WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 174  0
         String roleId = getRoleIdByName(namespaceCode, roleName);
 175  0
         if (roleId == null) {
 176  0
             return new ArrayList<Map<String, String>>(0);
 177  
         }
 178  0
         return getNestedRoleQualifiersForPrincipal(principalId, Collections.singletonList(roleId), qualification);
 179  
     }
 180  
 
 181  
     @Override
 182  
     public List<Map<String, String>> getNestedRoleQualifiersForPrincipal(@WebParam(name = "principalId") String principalId, @WebParam(name = "roleIds") List<String> roleIds, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 183  0
         List<Map<String, String>> results = new ArrayList<Map<String, String>>();
 184  
 
 185  0
         Map<String, RoleBo> roleBosById = getRoleBoMap(roleIds);
 186  
 
 187  
         // get the person's groups
 188  0
         List<String> groupIds = getGroupService().getGroupIdsForPrincipal(principalId);
 189  0
         List<RoleMemberBo> roleMemberBos = getStoredRoleMembersUsingExactMatchOnQualification(principalId, groupIds, roleIds, qualification);
 190  
 
 191  0
         Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>();
 192  0
         for (RoleMemberBo roleMemberBo : roleMemberBos) {
 193  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId());
 194  
             // gather up the qualifier sets and the service they go with
 195  0
             if (roleMemberBo.getMemberTypeCode().equals(Role.PRINCIPAL_MEMBER_TYPE)
 196  
                     || roleMemberBo.getMemberTypeCode().equals(Role.GROUP_MEMBER_TYPE)) {
 197  0
                 if (roleTypeService != null) {
 198  0
                     List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId());
 199  0
                     if (las == null) {
 200  0
                         las = new ArrayList<RoleMembership>();
 201  0
                         roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las);
 202  
                     }
 203  0
                     RoleMembership mi = RoleMembership.Builder.create(
 204  
                             roleMemberBo.getRoleId(),
 205  
                             roleMemberBo.getRoleMemberId(),
 206  
                             roleMemberBo.getMemberId(),
 207  
                             roleMemberBo.getMemberTypeCode(),
 208  
                             roleMemberBo.getAttributes()).build();
 209  
 
 210  0
                     las.add(mi);
 211  0
                 } else {
 212  0
                     results.add(roleMemberBo.getAttributes());
 213  
                 }
 214  0
             } else if (roleMemberBo.getMemberTypeCode().equals(Role.ROLE_MEMBER_TYPE)) {
 215  
                 // find out if the user has the role
 216  
                 // need to convert qualification using this role's service
 217  0
                 Map<String, String> nestedQualification = qualification;
 218  0
                 if (roleTypeService != null) {
 219  0
                     RoleBo roleBo = roleBosById.get(roleMemberBo.getRoleId());
 220  
                     // pulling from here as the nested roleBo is not necessarily (and likely is not)
 221  
                     // in the roleBosById Map created earlier
 222  0
                     RoleBo nestedRole = getRoleBo(roleMemberBo.getMemberId());
 223  
                     //it is possible that the the roleTypeService is coming from a remote application
 224  
                     // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 225  
                     try {
 226  0
                         nestedQualification = roleTypeService.convertQualificationForMemberRoles(roleBo.getNamespaceCode(), roleBo.getName(), nestedRole.getNamespaceCode(), nestedRole.getName(), qualification);
 227  0
                     } catch (Exception ex) {
 228  0
                         LOG.warn("Not able to retrieve RoleTypeService from remote system for roleBo Id: " + roleBo.getId(), ex);
 229  0
                     }
 230  
                 }
 231  0
                 List<String> nestedRoleId = new ArrayList<String>(1);
 232  0
                 nestedRoleId.add(roleMemberBo.getMemberId());
 233  
                 // if the user has the given role, add the qualifier the *nested role* has with the
 234  
                 // originally queries role
 235  0
                 if (principalHasRole(principalId, nestedRoleId, nestedQualification, false)) {
 236  0
                     results.add(roleMemberBo.getAttributes());
 237  
                 }
 238  
             }
 239  0
         }
 240  0
         for (String roleId : roleIdToMembershipMap.keySet()) {
 241  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 242  
             //it is possible that the the roleTypeService is coming from a remote application
 243  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 244  
             try {
 245  0
                 List<RoleMembership> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification(qualification, roleIdToMembershipMap.get(roleId));
 246  0
                 for (RoleMembership roleMembership : matchingMembers) {
 247  0
                     results.add(roleMembership.getQualifier());
 248  
                 }
 249  0
             } catch (Exception ex) {
 250  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 251  0
             }
 252  0
         }
 253  0
         return results;
 254  
     }
 255  
 
 256  
     @Override
 257  
     public List<RoleMembership> getRoleMembers(@WebParam(name = "roleIds") List<String> roleIds, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 258  0
         Set<String> foundRoleTypeMembers = new HashSet<String>();
 259  0
         return getRoleMembers(roleIds, qualification, true, foundRoleTypeMembers);
 260  
     }
 261  
 
 262  
     @Override
 263  
     public Collection<String> getRoleMemberPrincipalIds(@WebParam(name = "namespaceCode") String namespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 264  0
         Set<String> principalIds = new HashSet<String>();
 265  0
         Set<String> foundRoleTypeMembers = new HashSet<String>();
 266  0
         List<String> roleIds = Collections.singletonList(getRoleIdByName(namespaceCode, roleName));
 267  0
         for (RoleMembership roleMembership : getRoleMembers(roleIds, qualification, false, foundRoleTypeMembers)) {
 268  0
             if (Role.GROUP_MEMBER_TYPE.equals(roleMembership.getMemberTypeCode())) {
 269  0
                 principalIds.addAll(getGroupService().getMemberPrincipalIds(roleMembership.getMemberId()));
 270  
             } else {
 271  0
                 principalIds.add(roleMembership.getMemberId());
 272  
             }
 273  
         }
 274  0
         return principalIds;
 275  
     }
 276  
 
 277  
     @Override
 278  
     public boolean principalHasRole(@WebParam(name = "principalId") String principalId, @WebParam(name = "roleIds") List<String> roleIds, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 279  0
         return principalHasRole(principalId, roleIds, qualification, true);
 280  
     }
 281  
 
 282  
     @Override
 283  
     public List<String> getPrincipalIdSubListWithRole(@WebParam(name = "principalIds") List<String> principalIds, @WebParam(name = "roleNamespaceCode") String roleNamespaceCode, @WebParam(name = "roleName") String roleName, @WebParam(name = "qualification") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> qualification) {
 284  0
         List<String> subList = new ArrayList<String>();
 285  0
         RoleBo role = getRoleBoByName(roleNamespaceCode, roleName);
 286  0
         for (String principalId : principalIds) {
 287  0
             if (principalHasRole(principalId, Collections.singletonList(role.getId()), qualification)) {
 288  0
                 subList.add(principalId);
 289  
             }
 290  
         }
 291  0
         return subList;
 292  
     }
 293  
 
 294  
     @Override
 295  
     public List<Role> getRolesSearchResults(@XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(name = "fieldValues") Map<String, String> fieldValues) {
 296  0
         List<RoleBo> roleBoList = getRoleDao().getRoles(fieldValues);
 297  0
         List<Role> roles = new ArrayList<Role>();
 298  0
         for (RoleBo roleBo : roleBoList) {
 299  0
             roles.add(RoleBo.to(roleBo));
 300  
         }
 301  0
         return roles;
 302  
     }
 303  
 
 304  
     @Override
 305  
     public void principalInactivated(@WebParam(name = "principalId") String principalId) {
 306  0
         long oneDayInMillis = TimeUnit.DAYS.toMillis(1);
 307  0
         Timestamp yesterday = new Timestamp(System.currentTimeMillis() - oneDayInMillis);
 308  
 
 309  0
         inactivatePrincipalRoleMemberships(principalId, yesterday);
 310  0
         inactivatePrincipalGroupMemberships(principalId, yesterday);
 311  0
         inactivatePrincipalDelegations(principalId, yesterday);
 312  0
         inactivateApplicationRoleMemberships(principalId, yesterday);
 313  0
     }
 314  
 
 315  
     @Override
 316  
     public void roleInactivated(@WebParam(name = "roleId") String roleId) {
 317  0
         long oneDayInMillis = TimeUnit.DAYS.toMillis(1);
 318  0
         Timestamp yesterday = new Timestamp(System.currentTimeMillis() - oneDayInMillis);
 319  
 
 320  0
         List<String> roleIds = new ArrayList<String>();
 321  0
         roleIds.add(roleId);
 322  0
         inactivateRoleMemberships(roleIds, yesterday);
 323  0
         inactivateRoleDelegations(roleIds, yesterday);
 324  0
         inactivateMembershipsForRoleAsMember(roleIds, yesterday);
 325  0
     }
 326  
 
 327  
     @Override
 328  
     public void groupInactivated(@WebParam(name = "groupId") String groupId) {
 329  0
         long oneDayInMillis = TimeUnit.DAYS.toMillis(1);
 330  0
         Timestamp yesterday = new Timestamp(System.currentTimeMillis() - oneDayInMillis);
 331  
 
 332  0
         List<String> groupIds = new ArrayList<String>();
 333  0
         groupIds.add(groupId);
 334  0
         inactivatePrincipalGroupMemberships(groupIds, yesterday);
 335  0
         inactivateGroupRoleMemberships(groupIds, yesterday);
 336  0
     }
 337  
 
 338  
     @Override
 339  
     public List<RoleMembership> getFirstLevelRoleMembers(@WebParam(name = "roleIds") List<String> roleIds) {
 340  0
         List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersForRoleIds(roleIds, null, null);
 341  0
         List<RoleMembership> roleMemberships = new ArrayList<RoleMembership>();
 342  0
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
 343  0
             RoleMembership roleMembeship = RoleMembership.Builder.create(
 344  
                     roleMemberBo.getRoleId(),
 345  
                     roleMemberBo.getRoleMemberId(),
 346  
                     roleMemberBo.getMemberId(),
 347  
                     roleMemberBo.getMemberTypeCode(),
 348  
                     roleMemberBo.getAttributes()).build();
 349  0
             roleMemberships.add(roleMembeship);
 350  0
         }
 351  0
         return roleMemberships;
 352  
     }
 353  
 
 354  
     @Override
 355  
     public List<RoleMembership> findRoleMemberships(@XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(name = "fieldValues") Map<String, String> fieldValues) {
 356  0
         return getRoleDao().getRoleMembers(fieldValues);
 357  
     }
 358  
 
 359  
     @Override
 360  
     public List<String> getMemberParentRoleIds(String memberType, String memberId) {
 361  0
         return super.getMemberParentRoleIds(memberType, memberId);
 362  
     }
 363  
 
 364  
     @Override
 365  
     public List<RoleMember> findRoleMembers(@XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(name = "fieldValues") Map<String, String> fieldValues) {
 366  0
         return super.findRoleMembers(fieldValues);
 367  
     }
 368  
 
 369  
     @Override
 370  
     public List<DelegateMember> findDelegateMembers(@XmlJavaTypeAdapter(value = MapStringStringAdapter.class) @WebParam(name = "fieldValues") Map<String, String> fieldValues) {
 371  0
         return super.findDelegateMembers(fieldValues);
 372  
     }
 373  
 
 374  
     @Override
 375  
     public List<DelegateMember> getDelegationMembersByDelegationId(@WebParam(name = "delegationId") String delegationId) {
 376  0
         DelegateBo delegateBo = getKimDelegationImpl(delegationId);
 377  0
         if (delegateBo == null) {return null;}
 378  
 
 379  0
         return getDelegateMembersForDelegation(delegateBo);
 380  
     }
 381  
 
 382  
     @Override
 383  
     public DelegateMember getDelegationMemberByDelegationAndMemberId(@WebParam(name = "delegationId") String delegationId, @WebParam(name = "memberId") String memberId) {
 384  0
         DelegateBo delegateBo = getKimDelegationImpl(delegationId);
 385  0
         DelegateMemberBo delegationMember = getKimDelegationMemberImplByDelegationAndId(delegationId, memberId);
 386  
 
 387  0
         return getDelegateCompleteInfo(delegateBo, delegationMember);
 388  
     }
 389  
 
 390  
     @Override
 391  
     public DelegateMember getDelegationMemberById(@WebParam(name = "assignedToId") String delegationMemberId) {
 392  
 
 393  0
         DelegateMemberBo delegateMemberBo = getDelegateMemberBo(delegationMemberId);
 394  0
         if (delegateMemberBo == null) {
 395  0
             return null;
 396  
         }
 397  
 
 398  0
         DelegateBo delegateBo = getKimDelegationImpl(delegateMemberBo.getDelegationId());
 399  
 
 400  0
         return getDelegateCompleteInfo(delegateBo, delegateMemberBo);
 401  
     }
 402  
 
 403  
     @Override
 404  
     public List<RoleResponsibility> getRoleResponsibilities(@WebParam(name = "roleId") String roleId) {
 405  0
         Map<String, String> criteria = new HashMap<String, String>(1);
 406  0
         criteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId);
 407  0
         List<RoleResponsibilityBo> roleResponsibilityBos = (List<RoleResponsibilityBo>)
 408  
                 getBusinessObjectService().findMatching(RoleResponsibilityBo.class, criteria);
 409  0
         List<RoleResponsibility> roleResponsibilities = new ArrayList<RoleResponsibility>();
 410  
 
 411  0
         for (RoleResponsibilityBo roleResponsibilityImpl : roleResponsibilityBos) {
 412  0
             roleResponsibilities.add(RoleResponsibilityBo.to(roleResponsibilityImpl));
 413  
         }
 414  0
         return roleResponsibilities;
 415  
     }
 416  
 
 417  
     @Override
 418  
     public List<RoleResponsibilityAction> getRoleMemberResponsibilityActions(@WebParam(name = "roleMemberId") String roleMemberId) {
 419  0
         return super.getRoleMemberResponsibilityActions(roleMemberId);
 420  
     }
 421  
 
 422  
     @Override
 423  
     public DelegateType getDelegateTypeInfo(@WebParam(name = "roleId") String roleId, @WebParam(name = "delegationTypeCode") String delegationTypeCode) {
 424  0
         DelegateBo delegateBo = getDelegationOfType(roleId, delegationTypeCode);
 425  0
         return DelegateBo.to(delegateBo);
 426  
     }
 427  
 
 428  
     @Override
 429  
     public DelegateType getDelegateTypeInfoById(@WebParam(name = "delegationId") String delegationId) {
 430  0
         if (delegationId == null) {
 431  0
             return null;
 432  
         }
 433  0
         DelegateBo delegateBo = getKimDelegationImpl(delegationId);
 434  0
         return DelegateBo.to(delegateBo);
 435  
     }
 436  
 
 437  
     @Override
 438  
     public void applicationRoleMembershipChanged(@WebParam(name = "roleId") String roleId) {
 439  0
         getResponsibilityInternalService().updateActionRequestsForRoleChange(roleId);
 440  0
     }
 441  
 
 442  
     @Override
 443  
     public List<Role> lookupRoles(@WebParam(name = "searchCriteria") @XmlJavaTypeAdapter(value = MapStringStringAdapter.class) Map<String, String> searchCriteria) {
 444  0
         Collection<RoleBo> roleBoCollection = getBusinessObjectService().findMatching(RoleBo.class, searchCriteria);
 445  0
         ArrayList<Role> roleList = new ArrayList<Role>();
 446  0
         for (RoleBo roleBo : roleBoCollection) {
 447  0
             roleList.add(RoleBo.to(roleBo));
 448  
         }
 449  0
         return roleList;
 450  
     }
 451  
 
 452  
     @Override
 453  
     public void flushInternalRoleCache() {
 454  0
         super.flushInternalRoleCache();
 455  0
     }
 456  
 
 457  
     @Override
 458  
     public void flushInternalRoleMemberCache() {
 459  0
         super.flushInternalRoleMemberCache();
 460  0
     }
 461  
 
 462  
     @Override
 463  
     public void flushInternalDelegationCache() {
 464  0
         super.flushInternalDelegationCache();
 465  0
     }
 466  
 
 467  
     @Override
 468  
     public void flushInternalDelegationMemberCache() {
 469  0
         super.flushInternalDelegationMemberCache();
 470  0
     }
 471  
 
 472  
 
 473  
     @SuppressWarnings("unchecked")
 474  
     protected void inactivateApplicationRoleMemberships(String principalId, Timestamp yesterday) {
 475  
         // get all role type services
 476  0
         Collection<KimType> types = KimApiServiceLocator.getKimTypeInfoService().findAllKimTypes();
 477  
         // create sub list of only application role types
 478  0
         ArrayList<KimType> applicationRoleTypes = new ArrayList<KimType>(types.size());
 479  0
         for (KimType typeInfo : types) {
 480  0
             KimRoleTypeService service = getRoleTypeService(typeInfo);
 481  
             try {//log service unavailable as WARN error
 482  0
                 if (isApplicationRoleType(typeInfo.getId(), service)) {
 483  0
                     applicationRoleTypes.add(typeInfo);
 484  
                 }
 485  0
             } catch (Exception e) {
 486  0
                 LOG.warn(e.getMessage(), e);
 487  0
             }
 488  0
         }
 489  
 
 490  0
         Map<String, Object> roleLookupMap = new HashMap<String, Object>(2);
 491  0
         roleLookupMap.put(KIMPropertyConstants.Role.ACTIVE, "Y");
 492  
         // loop over application types
 493  0
         for (KimType typeInfo : applicationRoleTypes) {
 494  0
             KimRoleTypeService service = getRoleTypeService(typeInfo);
 495  
             // get all roles for that type
 496  0
             roleLookupMap.put(KIMPropertyConstants.Role.KIM_TYPE_ID, typeInfo.getId());
 497  0
             Collection<RoleBo> roles = getBusinessObjectService().findMatching(RoleBo.class, roleLookupMap);
 498  
             // loop over all roles in those types
 499  0
             for (RoleBo role : roles) {
 500  
                 // call the principalInactivated() on the role type service for each role
 501  0
                 service.principalInactivated(principalId, role.getNamespaceCode(), role.getName());
 502  
             }
 503  0
         }
 504  0
     }
 505  
 
 506  
 
 507  
     protected void inactivatePrincipalRoleMemberships(String principalId, Timestamp yesterday) {
 508  
         // go through all roles and post-date them
 509  0
         List<RoleMemberBo> roleMembers = getStoredRolePrincipalsForPrincipalIdAndRoleIds(null, principalId, null);
 510  0
         Set<String> roleIds = new HashSet<String>(roleMembers.size());
 511  0
         for (RoleMemberBo roleMemberBo : roleMembers) {
 512  0
             roleMemberBo.setActiveToDate(yesterday);
 513  0
             roleIds.add(roleMemberBo.getRoleId()); // add to the set of IDs
 514  
         }
 515  0
         getBusinessObjectService().save(roleMembers);
 516  
         // find all distinct role IDs and type services
 517  0
         for (String roleId : roleIds) {
 518  0
             RoleBo role = getRoleBo(roleId);
 519  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 520  
             try {
 521  0
                 if (roleTypeService != null) {
 522  0
                     roleTypeService.principalInactivated(principalId, role.getNamespaceCode(), role.getName());
 523  
                 }
 524  0
             } catch (Exception ex) {
 525  0
                 LOG.error("Problem notifying role type service of principal inactivation: " + role.getKimRoleType().getServiceName(), ex);
 526  0
             }
 527  0
         }
 528  0
         getIdentityManagementNotificationService().roleUpdated();
 529  0
     }
 530  
 
 531  
     protected void inactivateGroupRoleMemberships(List<String> groupIds, Timestamp yesterday) {
 532  0
         List<RoleMemberBo> roleMemberBosOfGroupType = getStoredRoleGroupsForGroupIdsAndRoleIds(null, groupIds, null);
 533  0
         for (RoleMemberBo roleMemberbo : roleMemberBosOfGroupType) {
 534  0
             roleMemberbo.setActiveToDate(yesterday);
 535  
         }
 536  0
         getBusinessObjectService().save(roleMemberBosOfGroupType);
 537  0
         getIdentityManagementNotificationService().roleUpdated();
 538  0
     }
 539  
 
 540  
     protected void inactivatePrincipalGroupMemberships(String principalId, Timestamp yesterday) {
 541  0
         List<GroupMember> groupMembers = getRoleDao().getGroupPrincipalsForPrincipalIdAndGroupIds(null, principalId);
 542  0
         List<GroupMemberBo> groupMemberBoList = new ArrayList<GroupMemberBo>(groupMembers.size());
 543  0
         for (GroupMember gm : groupMembers) {
 544  0
             GroupMember.Builder builder = GroupMember.Builder.create(gm);
 545  0
             builder.setActiveToDate(yesterday);
 546  0
             groupMemberBoList.add(GroupMemberBo.from(builder.build()));
 547  0
         }
 548  0
         getBusinessObjectService().save(groupMemberBoList);
 549  0
     }
 550  
 
 551  
     protected void inactivatePrincipalGroupMemberships(List<String> groupIds, Timestamp yesterday) {
 552  0
         List<GroupMember> groupMembers = getRoleDao().getGroupMembers(groupIds);
 553  0
         List<GroupMemberBo> groupMemberBoList = new ArrayList<GroupMemberBo>(groupMembers.size());
 554  0
         for (GroupMember groupMember : groupMembers) {
 555  0
             GroupMember.Builder builder = GroupMember.Builder.create(groupMember);
 556  0
             builder.setActiveToDate(yesterday);
 557  0
             groupMemberBoList.add(GroupMemberBo.from(builder.build()));
 558  0
         }
 559  0
         getBusinessObjectService().save(groupMemberBoList);
 560  0
     }
 561  
 
 562  
     protected void inactivatePrincipalDelegations(String principalId, Timestamp yesterday) {
 563  0
         List<DelegateMemberBo> delegationMembers = getStoredDelegationPrincipalsForPrincipalIdAndDelegationIds(null, principalId);
 564  0
         for (DelegateMemberBo delegateMemberBo : delegationMembers) {
 565  0
             delegateMemberBo.setActiveToDate(yesterday);
 566  
         }
 567  0
         getBusinessObjectService().save(delegationMembers);
 568  0
         getIdentityManagementNotificationService().delegationUpdated();
 569  0
     }
 570  
 
 571  
 
 572  
     protected List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification, boolean followDelegations, Set<String> foundRoleTypeMembers) {
 573  0
         List<RoleMembership> results = new ArrayList<RoleMembership>();
 574  0
         Set<String> allRoleIds = new HashSet<String>();
 575  0
         for (String roleId : roleIds) {
 576  0
             if (isRoleActive(roleId)) {
 577  0
                 allRoleIds.add(roleId);
 578  
             }
 579  
         }
 580  
         // short-circuit if no roles match
 581  0
         if (allRoleIds.isEmpty()) {
 582  0
             return results;
 583  
         }
 584  0
         Set<String> matchingRoleIds = new HashSet<String>(allRoleIds.size());
 585  
         // for efficiency, retrieve all roles and store in a map
 586  0
         Map<String, RoleBo> roles = getRoleBoMap(allRoleIds);
 587  
 
 588  0
         List<String> copyRoleIds = new ArrayList<String>(allRoleIds);
 589  0
         List<RoleMemberBo> rms = new ArrayList<RoleMemberBo>();
 590  
 
 591  0
         for (String roleId : allRoleIds) {
 592  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 593  0
             if (roleTypeService != null) {
 594  0
                 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 595  0
                 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 596  0
                     copyRoleIds.remove(roleId);
 597  0
                     rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), null, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 598  
                 }
 599  
             }
 600  0
         }
 601  0
         if (CollectionUtils.isNotEmpty(copyRoleIds)) {
 602  0
             rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIds, null, null));
 603  
         }
 604  
 
 605  
         // build a map of role ID to membership information
 606  
         // this will be used for later qualification checks
 607  0
         Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>();
 608  0
         for (RoleMemberBo roleMemberBo : rms) {
 609  0
             RoleMembership mi = RoleMembership.Builder.create(
 610  
                     roleMemberBo.getRoleId(),
 611  
                     roleMemberBo.getRoleMemberId(),
 612  
                     roleMemberBo.getMemberId(),
 613  
                     roleMemberBo.getMemberTypeCode(),
 614  
                     roleMemberBo.getAttributes()).build();
 615  
 
 616  
             // if the qualification check does not need to be made, just add the result
 617  0
             if ((qualification == null || qualification.isEmpty()) || getRoleTypeService(roleMemberBo.getRoleId()) == null) {
 618  0
                 if (roleMemberBo.getMemberTypeCode().equals(Role.ROLE_MEMBER_TYPE)) {
 619  
                     // if a role member type, do a non-recursive role member check
 620  
                     // to obtain the group and principal members of that role
 621  
                     // given the qualification
 622  0
                     Map<String, String> nestedRoleQualification = qualification;
 623  0
                     if (getRoleTypeService(roleMemberBo.getRoleId()) != null) {
 624  
                         // get the member role object
 625  0
                         RoleBo memberRole = getRoleBo(mi.getMemberId());
 626  0
                         nestedRoleQualification = getRoleTypeService(roleMemberBo.getRoleId())
 627  
                                 .convertQualificationForMemberRoles(
 628  
                                         roles.get(roleMemberBo.getRoleId()).getNamespaceCode(),
 629  
                                         roles.get(roleMemberBo.getRoleId()).getName(),
 630  
                                         memberRole.getNamespaceCode(),
 631  
                                         memberRole.getName(),
 632  
                                         qualification);
 633  
                     }
 634  0
                     if (isRoleActive(roleMemberBo.getRoleId())) {
 635  0
                         Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, mi, foundRoleTypeMembers);
 636  0
                         if (!nestedRoleMembers.isEmpty()) {
 637  0
                             results.addAll(nestedRoleMembers);
 638  0
                             matchingRoleIds.add(roleMemberBo.getRoleId());
 639  
                         }
 640  
                     }
 641  0
                 } else { // not a role member type
 642  0
                     results.add(mi);
 643  0
                     matchingRoleIds.add(roleMemberBo.getRoleId());
 644  
                 }
 645  0
                 matchingRoleIds.add(roleMemberBo.getRoleId());
 646  
             } else {
 647  0
                 List<RoleMembership> lrmi = roleIdToMembershipMap.get(mi.getRoleId());
 648  0
                 if (lrmi == null) {
 649  0
                     lrmi = new ArrayList<RoleMembership>();
 650  0
                     roleIdToMembershipMap.put(mi.getRoleId(), lrmi);
 651  
                 }
 652  0
                 lrmi.add(mi);
 653  
             }
 654  0
         }
 655  
         // if there is anything in the role to membership map, we need to check the role type services
 656  
         // for those entries
 657  0
         if (!roleIdToMembershipMap.isEmpty()) {
 658  
             // for each role, send in all the qualifiers for that role to the type service
 659  
             // for evaluation, the service will return those which match
 660  0
             for (String roleId : roleIdToMembershipMap.keySet()) {
 661  
                 //it is possible that the the roleTypeService is coming from a remote application
 662  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 663  
                 try {
 664  0
                     KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 665  0
                     List<RoleMembership> matchingMembers = roleTypeService.doRoleQualifiersMatchQualification(qualification, roleIdToMembershipMap.get(roleId));
 666  
                     // loop over the matching entries, adding them to the results
 667  0
                     for (RoleMembership roleMemberships : matchingMembers) {
 668  0
                         if (roleMemberships.getMemberTypeCode().equals(Role.ROLE_MEMBER_TYPE)) {
 669  
                             // if a role member type, do a non-recursive role member check
 670  
                             // to obtain the group and principal members of that role
 671  
                             // given the qualification
 672  
                             // get the member role object
 673  0
                             RoleBo memberRole = getRoleBo(roleMemberships.getMemberId());
 674  0
                             if (memberRole.isActive()) {
 675  0
                                 Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(
 676  
                                         roles.get(roleMemberships.getRoleId()).getNamespaceCode(),
 677  
                                         roles.get(roleMemberships.getRoleId()).getName(),
 678  
                                         memberRole.getNamespaceCode(),
 679  
                                         memberRole.getName(),
 680  
                                         qualification);
 681  0
                                 Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, roleMemberships, foundRoleTypeMembers);
 682  0
                                 if (!nestedRoleMembers.isEmpty()) {
 683  0
                                     results.addAll(nestedRoleMembers);
 684  0
                                     matchingRoleIds.add(roleMemberships.getRoleId());
 685  
                                 }
 686  
                             }
 687  0
                         } else { // not a role member
 688  0
                             results.add(roleMemberships);
 689  0
                             matchingRoleIds.add(roleMemberships.getRoleId());
 690  
                         }
 691  
                     }
 692  0
                 } catch (Exception ex) {
 693  0
                     LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 694  0
                 }
 695  
             }
 696  
         }
 697  0
         return results;
 698  
     }
 699  
 
 700  
 
 701  
     protected boolean principalHasRole(String principalId, List<String> roleIds, Map<String, String> qualification, boolean checkDelegations) {
 702  0
         if (StringUtils.isBlank(principalId)) {
 703  0
             return false;
 704  
         }
 705  0
         Set<String> allRoleIds = new HashSet<String>();
 706  
         // remove inactive roles
 707  0
         for (String roleId : roleIds) {
 708  0
             if (isRoleActive(roleId)) {
 709  0
                 allRoleIds.add(roleId);
 710  
             }
 711  
         }
 712  
         // short-circuit if no roles match
 713  0
         if (allRoleIds.isEmpty()) {
 714  0
             return false;
 715  
         }
 716  
         // for efficiency, retrieve all roles and store in a map
 717  0
         Map<String, RoleBo> roles = getRoleBoMap(allRoleIds);
 718  
         // get all roles to which the principal is assigned
 719  0
         List<String> copyRoleIds = new ArrayList<String>(allRoleIds);
 720  0
         List<RoleMemberBo> rps = new ArrayList<RoleMemberBo>();
 721  
 
 722  0
         for (String roleId : allRoleIds) {
 723  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 724  0
             if (roleTypeService != null) {
 725  0
                 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 726  0
                 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 727  0
                     copyRoleIds.remove(roleId);
 728  0
                     rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collections.singletonList(roleId), principalId, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 729  
                 }
 730  
             }
 731  0
         }
 732  0
         if (CollectionUtils.isNotEmpty(copyRoleIds)) {
 733  0
             rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(copyRoleIds, principalId, null));
 734  
         }
 735  
 
 736  
         // if the qualification is null and the role list is not, then any role in the list will match
 737  
         // so since the role ID list is not blank, we can return true at this point
 738  0
         if ((qualification == null || qualification.isEmpty()) && !rps.isEmpty()) {
 739  0
             return true;
 740  
         }
 741  
 
 742  
         // check each membership to see if the principal matches
 743  
 
 744  
         // build a map of role ID to membership information
 745  
         // this will be used for later qualification checks
 746  0
         Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>();
 747  0
         if (getRoleIdToMembershipMap(roleIdToMembershipMap, rps)) {
 748  0
             return true;
 749  
         }
 750  
 
 751  
         // perform the checks against the role type services
 752  0
         for (String roleId : roleIdToMembershipMap.keySet()) {
 753  
             try {
 754  0
                 KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 755  0
                 if (!roleTypeService.doRoleQualifiersMatchQualification(qualification, roleIdToMembershipMap.get(roleId)).isEmpty()) {
 756  0
                     return true;
 757  
                 }
 758  0
             } catch (Exception ex) {
 759  0
                 LOG.warn("Unable to find role type service with id: " + roleId);
 760  0
             }
 761  
         }
 762  
 
 763  
         // find the groups that the principal belongs to
 764  0
         List<String> principalGroupIds = getGroupService().getGroupIdsForPrincipal(principalId);
 765  
         // find the role/group associations
 766  0
         if (!principalGroupIds.isEmpty()) {
 767  0
             List<RoleMemberBo> rgs = getStoredRoleGroupsUsingExactMatchOnQualification(principalGroupIds, allRoleIds, qualification);
 768  0
             roleIdToMembershipMap.clear(); // clear the role/member map for further use
 769  0
             if (getRoleIdToMembershipMap(roleIdToMembershipMap, rgs)) {
 770  0
                 return true;
 771  
             }
 772  
 
 773  
             // perform the checks against the role type services
 774  0
             for (String roleId : roleIdToMembershipMap.keySet()) {
 775  
                 try {
 776  0
                     KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 777  0
                     if (!roleTypeService.doRoleQualifiersMatchQualification(qualification, roleIdToMembershipMap.get(roleId)).isEmpty()) {
 778  0
                         return true;
 779  
                     }
 780  0
                 } catch (Exception ex) {
 781  0
                     LOG.warn("Unable to find role type service with id: " + roleId);
 782  0
                 }
 783  
             }
 784  
         }
 785  
 
 786  
         // check member roles
 787  
         // first, check that the qualifiers on the role membership match
 788  
         // then, perform a principalHasRole on the embedded role
 789  0
         List<RoleMemberBo> roleMemberBos = getStoredRoleMembersForRoleIds(roleIds, Role.ROLE_MEMBER_TYPE, null);
 790  0
         for (RoleMemberBo roleMemberBo : roleMemberBos) {
 791  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId());
 792  0
             if (roleTypeService != null) {
 793  
                 //it is possible that the the roleTypeService is coming from a remote application
 794  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 795  
                 try {
 796  0
                     if (roleTypeService.doesRoleQualifierMatchQualification(qualification, roleMemberBo.getAttributes())) {
 797  0
                         RoleBo memberRole = getRoleBo(roleMemberBo.getMemberId());
 798  0
                         Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(
 799  
                                 roles.get(roleMemberBo.getRoleId()).getNamespaceCode(),
 800  
                                 roles.get(roleMemberBo.getRoleId()).getName(),
 801  
                                 memberRole.getNamespaceCode(),
 802  
                                 memberRole.getName(),
 803  
                                 qualification);
 804  0
                         ArrayList<String> roleIdTempList = new ArrayList<String>(1);
 805  0
                         roleIdTempList.add(roleMemberBo.getMemberId());
 806  0
                         if (principalHasRole(principalId, roleIdTempList, nestedRoleQualification, true)) {
 807  0
                             return true;
 808  
                         }
 809  
                     }
 810  0
                 } catch (Exception ex) {
 811  0
                     LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleMemberBo.getRoleId(), ex);
 812  
                     //return false;
 813  0
                 }
 814  
             } else {
 815  
                 // no qualifiers - role is always used - check membership
 816  0
                 ArrayList<String> roleIdTempList = new ArrayList<String>(1);
 817  0
                 roleIdTempList.add(roleMemberBo.getMemberId());
 818  
                 // no role type service, so can't convert qualification - just pass as is
 819  0
                 if (principalHasRole(principalId, roleIdTempList, qualification, true)) {
 820  0
                     return true;
 821  
                 }
 822  
             }
 823  
 
 824  0
         }
 825  
 
 826  
 
 827  
         // check for application roles and extract principals and groups from that - then check them against the
 828  
         // role type service passing in the qualification and principal - the qualifier comes from the
 829  
         // external system (application)
 830  
 
 831  
         // loop over the allRoleIds list
 832  0
         for (String roleId : allRoleIds) {
 833  0
             RoleBo role = roles.get(roleId);
 834  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 835  
             // check if an application role
 836  
             //it is possible that the the roleTypeService is coming from a remote application
 837  
             // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 838  
             try {
 839  0
                 if (isApplicationRoleType(role.getKimTypeId(), roleTypeService)) {
 840  0
                     if (roleTypeService.hasApplicationRole(principalId, principalGroupIds, role.getNamespaceCode(), role.getName(), qualification)) {
 841  0
                         return true;
 842  
                     }
 843  
                 }
 844  0
             } catch (Exception ex) {
 845  0
                 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
 846  
                 //return false;
 847  0
             }
 848  0
         }
 849  
 
 850  
         // delegations
 851  0
         if (checkDelegations) {
 852  0
             if (matchesOnDelegation(allRoleIds, principalId, principalGroupIds, qualification)) {
 853  0
                 return true;
 854  
             }
 855  
         }
 856  
 
 857  
         // NOTE: this logic is a little different from the getRoleMembers method
 858  
         // If there is no primary (matching non-delegate), this method will still return true
 859  0
         return false;
 860  
     }
 861  
 
 862  
 
 863  
     protected boolean isApplicationRoleType(String roleTypeId, KimRoleTypeService service) {
 864  0
         Boolean result = getApplicationRoleTypeCache().get(roleTypeId);
 865  0
         if (result == null) {
 866  0
             if (service != null) {
 867  0
                 result = service.isApplicationRoleType();
 868  
             } else {
 869  0
                 result = Boolean.FALSE;
 870  
             }
 871  
         }
 872  0
         return result;
 873  
     }
 874  
 
 875  
     /**
 876  
      * Support method for principalHasRole.  Checks delegations on the passed in roles for the given principal and groups.  (It's assumed that the principal
 877  
      * belongs to the given groups.)
 878  
      * <p/>
 879  
      * Delegation checks are mostly the same as role checks except that the delegateBo itself is qualified against the original role (like a RolePrincipal
 880  
      * or RoleGroup.)  And then, the members of that delegateBo may have additional qualifiers which are not part of the original role qualifiers.
 881  
      * <p/>
 882  
      * For example:
 883  
      * <p/>
 884  
      * 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
 885  
      * for that organization (not their authority - the delegateBo is attached to the org.)  So, in this case the delegateBo has a qualifier of the organization
 886  
      * when it is attached to the role.
 887  
      * <p/>
 888  
      * The principals then attached to that delegateBo (which is specific to the organization), may have additional qualifiers.
 889  
      * For Example: dollar amount range, effective dates, document types.
 890  
      * As a subsequent step, those qualifiers are checked against the qualification passed in from the client.
 891  
      */
 892  
     protected boolean matchesOnDelegation(Set<String> allRoleIds, String principalId, List<String> principalGroupIds, Map<String, String> qualification) {
 893  
         // get the list of delegations for the roles
 894  0
         Map<String, DelegateBo> delegations = getStoredDelegationImplMapFromRoleIds(allRoleIds);
 895  
         // loop over the delegations - determine those which need to be inspected more directly
 896  0
         for (DelegateBo delegation : delegations.values()) {
 897  
             // check if each one matches via the original role type service
 898  0
             if (!delegation.isActive()) {
 899  0
                 continue;
 900  
             }
 901  0
             KimRoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId());
 902  0
             for (DelegateMemberBo delegateMemberBo : delegation.getMembers()) {
 903  0
                 if (!delegateMemberBo.isActive(new Timestamp(new Date().getTime()))) {
 904  0
                     continue;
 905  
                 }
 906  
                 // check if this delegateBo record applies to the given person
 907  0
                 if (delegateMemberBo.getTypeCode().equals(Role.PRINCIPAL_MEMBER_TYPE)
 908  
                         && !delegateMemberBo.getMemberId().equals(principalId)) {
 909  0
                     continue; // no match on principal
 910  
                 }
 911  
                 // or if a group
 912  0
                 if (delegateMemberBo.getTypeCode().equals(Role.GROUP_MEMBER_TYPE)
 913  
                         && !principalGroupIds.contains(delegateMemberBo.getMemberId())) {
 914  0
                     continue; // no match on group
 915  
                 }
 916  
                 // or if a role
 917  0
                 if (delegateMemberBo.getTypeCode().equals(Role.ROLE_MEMBER_TYPE)
 918  
                         && !principalHasRole(principalId, Collections.singletonList(delegateMemberBo.getMemberId()), qualification, false)) {
 919  0
                     continue; // no match on role
 920  
                 }
 921  
                 // OK, the member matches the current user, now check the qualifications
 922  
 
 923  
                 // NOTE: this compare is slightly different than the member enumeration
 924  
                 // since the requested qualifier is always being used rather than
 925  
                 // the role qualifier for the member (which is not available)
 926  
 
 927  
                 //it is possible that the the roleTypeService is coming from a remote application
 928  
                 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 929  
                 try {
 930  
                     //TODO: remove reference to Attributes here and use Attributes instead.
 931  0
                     if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) {
 932  0
                         continue; // no match - skip to next record
 933  
                     }
 934  0
                 } catch (Exception ex) {
 935  0
                     LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + delegateMemberBo.getQualifier(), ex);
 936  0
                     continue;
 937  0
                 }
 938  
 
 939  
                 // role service matches this qualifier
 940  
                 // now try the delegateBo service
 941  0
                 KimDelegationTypeService delegationTypeService = getDelegationTypeService(delegateMemberBo.getDelegationId());
 942  
                 // QUESTION: does the qualifier map need to be merged with the main delegateBo qualification?
 943  0
                 if (delegationTypeService != null && !delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) {
 944  0
                     continue; // no match - skip to next record
 945  
                 }
 946  
                 // check if a role member ID is present on the delegateBo record
 947  
                 // if so, check that the original role member would match the given qualifiers
 948  0
                 if (StringUtils.isNotBlank(delegateMemberBo.getRoleMemberId())) {
 949  0
                     RoleMemberBo rm = getRoleMemberBo(delegateMemberBo.getRoleMemberId());
 950  0
                     if (rm != null) {
 951  
                         // check that the original role member's is active and that their
 952  
                         // qualifier would have matched this request's
 953  
                         // qualifications (that the original person would have the permission/responsibility
 954  
                         // for an action)
 955  
                         // this prevents a role-membership based delegateBo from surviving the inactivation/
 956  
                         // changing of the main person's role membership
 957  0
                         if (!rm.isActive(new Timestamp(new Date().getTime()))) {
 958  0
                             continue;
 959  
                         }
 960  0
                         Map<String, String> roleQualifier = rm.getAttributes();
 961  
                         //it is possible that the the roleTypeService is coming from a remote application
 962  
                         // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
 963  
                         try {
 964  0
                             if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, roleQualifier)) {
 965  0
                                 continue;
 966  
                             }
 967  0
                         } catch (Exception ex) {
 968  0
                             LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + roleQualifier, ex);
 969  0
                             continue;
 970  0
                         }
 971  0
                     } else {
 972  0
                         LOG.warn("Unknown role member ID cited in the delegateBo member table:");
 973  0
                         LOG.warn("       assignedToId: " + delegateMemberBo.getDelegationMemberId() + " / roleMemberId: " + delegateMemberBo.getRoleMemberId());
 974  
                     }
 975  
                 }
 976  
                 // all tests passed, return true
 977  0
                 return true;
 978  
             }
 979  0
         }
 980  0
         return false;
 981  
     }
 982  
 
 983  
     /**
 984  
      * Helper method used by principalHasRole to build the role ID -> list of members map.
 985  
      *
 986  
      * @return <b>true</b> if no further checks are needed because no role service is defined
 987  
      */
 988  
     protected boolean getRoleIdToMembershipMap(Map<String, List<RoleMembership>> roleIdToMembershipMap, List<RoleMemberBo> roleMembers) {
 989  0
         for (RoleMemberBo roleMemberBo : roleMembers) {
 990  0
             RoleMembership roleMembership = RoleMembership.Builder.create(
 991  
                     roleMemberBo.getRoleId(),
 992  
                     roleMemberBo.getRoleMemberId(),
 993  
                     roleMemberBo.getMemberId(),
 994  
                     roleMemberBo.getMemberTypeCode(),
 995  
                     roleMemberBo.getAttributes()).build();
 996  
 
 997  
             // if the role type service is null, assume that all qualifiers match
 998  0
             if (getRoleTypeService(roleMemberBo.getRoleId()) == null) {
 999  0
                 return true;
 1000  
             }
 1001  0
             List<RoleMembership> lrmi = roleIdToMembershipMap.get(roleMembership.getRoleId());
 1002  0
             if (lrmi == null) {
 1003  0
                 lrmi = new ArrayList<RoleMembership>();
 1004  0
                 roleIdToMembershipMap.put(roleMembership.getRoleId(), lrmi);
 1005  
             }
 1006  0
             lrmi.add(roleMembership);
 1007  0
         }
 1008  0
         return false;
 1009  
     }
 1010  
 
 1011  
     /**
 1012  
      * Retrieves a KimDelegationImpl object by its ID. If the delegateBo already exists in the cache, this method will return the cached
 1013  
      * version; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 1014  
      */
 1015  
     protected DelegateBo getKimDelegationImpl(String delegationId) {
 1016  0
         if (StringUtils.isBlank(delegationId)) {
 1017  0
             return null;
 1018  
         }
 1019  
 
 1020  
         // If the KimDelegationImpl exists in the cache, return the cached one.
 1021  0
         DelegateBo tempDelegate = getDelegationFromCache(delegationId);
 1022  0
         if (tempDelegate != null) {
 1023  0
             return tempDelegate;
 1024  
         }
 1025  
         // Otherwise, retrieve it normally.
 1026  0
         tempDelegate = (DelegateBo) getBusinessObjectService().findByPrimaryKey(DelegateBo.class,
 1027  
                 Collections.singletonMap(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId));
 1028  0
         this.addDelegationBoToCache(tempDelegate);
 1029  0
         return tempDelegate;
 1030  
     }
 1031  
 
 1032  
     /**
 1033  
      * Retrieves the role type service associated with the given role ID
 1034  
      *
 1035  
      * @param roleId the role ID to get the role type service for
 1036  
      * @return the Role Type Service
 1037  
      */
 1038  
     protected KimRoleTypeService getRoleTypeService(String roleId) {
 1039  0
         KimRoleTypeService service = getRoleTypeServiceCache().get(roleId);
 1040  0
         if (service == null && !getRoleTypeServiceCache().containsKey(roleId)) {
 1041  0
             RoleBo roleBo = getRoleBo(roleId);
 1042  0
             KimType roleType = KimTypeBo.to(roleBo.getKimRoleType());
 1043  0
             if (roleType != null) {
 1044  0
                 service = getRoleTypeService(roleType);
 1045  
             }
 1046  0
             getRoleTypeServiceCache().put(roleId, service);
 1047  
         }
 1048  0
         return service;
 1049  
     }
 1050  
 
 1051  
     protected KimRoleTypeService getRoleTypeService(KimType typeInfo) {
 1052  0
         String serviceName = typeInfo.getServiceName();
 1053  0
         if (serviceName != null) {
 1054  
             try {
 1055  0
                 KimTypeService service = (KimTypeService) KIMServiceLocatorInternal.getService(serviceName);
 1056  0
                 if (service != null && service instanceof KimRoleTypeService) {
 1057  0
                     return (KimRoleTypeService) service;
 1058  
                 }
 1059  0
                 return (KimRoleTypeService) KIMServiceLocatorInternal.getService("kimNoMembersRoleTypeService");
 1060  0
             } catch (Exception ex) {
 1061  0
                 LOG.error("Unable to find role type service with name: " + serviceName, ex);
 1062  0
                 return (KimRoleTypeService) KIMServiceLocatorInternal.getService("kimNoMembersRoleTypeService");
 1063  
             }
 1064  
         }
 1065  0
         return null;
 1066  
     }
 1067  
 
 1068  
     protected KimDelegationTypeService getDelegationTypeService(String delegationId) {
 1069  0
         KimDelegationTypeService service = getDelegationTypeServiceCache().get(delegationId);
 1070  0
         if (service == null && !getDelegationTypeServiceCache().containsKey(delegationId)) {
 1071  0
             DelegateBo delegateBo = getKimDelegationImpl(delegationId);
 1072  0
             KimType delegationType = KimApiServiceLocator.getKimTypeInfoService().getKimType(delegateBo.getKimTypeId());
 1073  0
             if (delegationType != null) {
 1074  0
                 KimTypeService tempService = KIMServiceLocatorWeb.getKimTypeService(delegationType);
 1075  0
                 if (tempService != null && tempService instanceof KimDelegationTypeService) {
 1076  0
                     service = (KimDelegationTypeService) tempService;
 1077  
                 } else {
 1078  0
                     LOG.error("Service returned for type " + delegationType + "(" + delegationType.getName() + ") was not a KimDelegationTypeService.  Was a " + tempService.getClass());
 1079  
                 }
 1080  0
             } else { // delegateBo has no type - default to role type if possible
 1081  0
                 KimRoleTypeService roleTypeService = getRoleTypeService(delegateBo.getRoleId());
 1082  0
                 if (roleTypeService != null && roleTypeService instanceof KimDelegationTypeService) {
 1083  0
                     service = (KimDelegationTypeService) roleTypeService;
 1084  
                 }
 1085  
             }
 1086  0
             getDelegationTypeServiceCache().put(delegationId, service);
 1087  
         }
 1088  0
         return service;
 1089  
     }
 1090  
 
 1091  
     protected Collection<RoleMembership> getNestedRoleMembers(Map<String, String> qualification, RoleMembership rm, Set<String> foundRoleTypeMembers) {
 1092  
         // If this role has already been traversed, skip it
 1093  0
         if (foundRoleTypeMembers.contains(rm.getMemberId())) {
 1094  0
             return new ArrayList<RoleMembership>();  // return an empty list
 1095  
         }
 1096  0
         foundRoleTypeMembers.add(rm.getMemberId());
 1097  
 
 1098  0
         ArrayList<String> roleIdList = new ArrayList<String>(1);
 1099  0
         roleIdList.add(rm.getMemberId());
 1100  
 
 1101  
         // get the list of members from the nested role - ignore delegations on those sub-roles
 1102  0
         Collection<RoleMembership> currentNestedRoleMembers = getRoleMembers(roleIdList, qualification, false, foundRoleTypeMembers);
 1103  
 
 1104  
         // add the roles whose members matched to the list for delegateBo checks later
 1105  0
         Collection<RoleMembership> returnRoleMembers = new ArrayList<RoleMembership>();
 1106  0
         for (RoleMembership roleMembership : currentNestedRoleMembers) {
 1107  0
             RoleMembership.Builder rmBuilder = RoleMembership.Builder.create(roleMembership);
 1108  
 
 1109  
             // use the member ID of the parent role (needed for responsibility joining)
 1110  0
             rmBuilder.setRoleMemberId(rm.getRoleMemberId());
 1111  
             // store the role ID, so we know where this member actually came from
 1112  0
             rmBuilder.setRoleId(rm.getRoleId());
 1113  0
             rmBuilder.setEmbeddedRoleId(rm.getMemberId());
 1114  0
             returnRoleMembers.add(rmBuilder.build());
 1115  0
         }
 1116  0
         return returnRoleMembers;
 1117  
     }
 1118  
 
 1119  
     /**
 1120  
      * Retrieves a KimDelegationMemberImpl object by its ID and the ID of the delegation it belongs to. If the delegation member exists in the cache,
 1121  
      * this method will return the cached one; otherwise, it will retrieve the uncached version from the database and then cache it before returning it.
 1122  
      */
 1123  
     protected DelegateMemberBo getKimDelegationMemberImplByDelegationAndId(String delegationId, String delegationMemberId) {
 1124  0
         if (StringUtils.isBlank(delegationId) || StringUtils.isBlank(delegationMemberId)) {
 1125  0
             return null;
 1126  
         }
 1127  
 
 1128  
         // If the KimDelegationMemberImpl exists in the cache, return the cached one.
 1129  0
         DelegateMemberBo tempDelegationMember = getDelegationMemberByDelegationAndIdFromCache(delegationId, delegationMemberId);
 1130  0
         if (tempDelegationMember != null) {
 1131  0
             return tempDelegationMember;
 1132  
         }
 1133  
         // Otherwise, retrieve it normally.
 1134  0
         Map<String, String> searchCriteria = new HashMap<String, String>();
 1135  0
         searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId);
 1136  0
         searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMemberId);
 1137  0
         List<DelegateMemberBo> memberList =
 1138  
                 (List<DelegateMemberBo>) getBusinessObjectService().findMatching(DelegateMemberBo.class, searchCriteria);
 1139  0
         if (memberList != null && !memberList.isEmpty()) {
 1140  0
             tempDelegationMember = memberList.get(0);
 1141  0
             addDelegateMemberBoToCache(tempDelegationMember);
 1142  
         }
 1143  0
         return tempDelegationMember;
 1144  
     }
 1145  
 
 1146  
     private List<RoleMemberBo> getStoredRoleMembersUsingExactMatchOnQualification(String principalId, List<String> groupIds, List<String> roleIds, Map<String, String> qualification) {
 1147  0
         List<String> copyRoleIds = new ArrayList<String>(roleIds);
 1148  0
         List<RoleMemberBo> roleMemberBoList = new ArrayList<RoleMemberBo>();
 1149  
 
 1150  0
         for (String roleId : roleIds) {
 1151  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 1152  0
             if (roleTypeService != null) {
 1153  0
                 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 1154  0
                 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 1155  0
                     copyRoleIds.remove(roleId);
 1156  0
                     roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(Collections.singletonList(roleId), principalId, groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 1157  
                 }
 1158  
             }
 1159  0
         }
 1160  0
         if (CollectionUtils.isNotEmpty(copyRoleIds)) {
 1161  0
             roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(copyRoleIds, principalId, groupIds, null));
 1162  
         }
 1163  0
         return roleMemberBoList;
 1164  
     }
 1165  
 
 1166  
     private Map<String, String> populateQualifiersForExactMatch(Map<String, String> defaultQualification, List<String> attributes) {
 1167  0
         Map<String,String> qualifiersForExactMatch = new HashMap<String,String>();
 1168  0
         if (defaultQualification != null && CollectionUtils.isNotEmpty(defaultQualification.keySet())) {
 1169  0
             for (String attributeName : attributes) {
 1170  0
                 if (StringUtils.isNotEmpty(defaultQualification.get(attributeName))) {
 1171  0
                     qualifiersForExactMatch.put(attributeName, defaultQualification.get(attributeName));
 1172  
                 }
 1173  
             }
 1174  
         }
 1175  0
         return qualifiersForExactMatch;
 1176  
     }
 1177  
 
 1178  
     private List<RoleMemberBo> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, Set<String> roleIds, Map<String, String> qualification) {
 1179  0
         List<String> copyRoleIds = new ArrayList<String>(roleIds);
 1180  0
         List<RoleMemberBo> roleMemberBos = new ArrayList<RoleMemberBo>();
 1181  
 
 1182  0
         for (String roleId : roleIds) {
 1183  0
             KimRoleTypeService roleTypeService = getRoleTypeService(roleId);
 1184  0
             if (roleTypeService != null) {
 1185  0
                 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
 1186  0
                 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
 1187  0
                     copyRoleIds.remove(roleId);
 1188  0
                     roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(roleId), groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
 1189  
                 }
 1190  
             }
 1191  0
         }
 1192  0
         if (CollectionUtils.isNotEmpty(copyRoleIds)) {
 1193  0
             roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(copyRoleIds, groupIds, null));
 1194  
         }
 1195  0
         return roleMemberBos;
 1196  
     }
 1197  
 
 1198  
     private void inactivateRoleMemberships(List<String> roleIds, Timestamp yesterday) {
 1199  0
         List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersForRoleIds(roleIds, null, null);
 1200  0
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
 1201  0
             roleMemberBo.setActiveToDate(yesterday);
 1202  
         }
 1203  0
         getBusinessObjectService().save(roleMemberBoList);
 1204  0
         getIdentityManagementNotificationService().roleUpdated();
 1205  0
     }
 1206  
 
 1207  
     private void inactivateRoleDelegations(List<String> roleIds, Timestamp yesterday) {
 1208  0
         List<DelegateBo> delegations = getStoredDelegationImplsForRoleIds(roleIds);
 1209  0
         for (DelegateBo delegation : delegations) {
 1210  0
             delegation.setActive(false);
 1211  0
             for (DelegateMemberBo delegationMember : delegation.getMembers()) {
 1212  0
                 delegationMember.setActiveToDate(yesterday);
 1213  
             }
 1214  
         }
 1215  0
         getBusinessObjectService().save(delegations);
 1216  0
         getIdentityManagementNotificationService().delegationUpdated();
 1217  0
     }
 1218  
 
 1219  
     private void inactivateMembershipsForRoleAsMember(List<String> roleIds, Timestamp yesterday) {
 1220  0
         List<RoleMemberBo> roleMemberBoList = getStoredRoleMembershipsForRoleIdsAsMembers(roleIds, null);
 1221  0
         for (RoleMemberBo roleMemberBo : roleMemberBoList) {
 1222  0
             roleMemberBo.setActiveToDate(yesterday);
 1223  
         }
 1224  0
         getBusinessObjectService().save(roleMemberBoList);
 1225  0
         getIdentityManagementNotificationService().roleUpdated();
 1226  0
     }
 1227  
 
 1228  
     private List<DelegateMember> getDelegateMembersForDelegation(DelegateBo delegateBo) {
 1229  0
         if (delegateBo == null || delegateBo.getMembers() == null) {return null;}
 1230  0
         List<DelegateMember> delegateMembersReturnList = new ArrayList<DelegateMember>();
 1231  0
         for (DelegateMemberBo delegateMemberBo : delegateBo.getMembers()) {
 1232  0
             DelegateMember delegateMember = getDelegateCompleteInfo(delegateBo, delegateMemberBo);
 1233  
 
 1234  0
             delegateMembersReturnList.add(DelegateMemberBo.to(delegateMemberBo));
 1235  0
         }
 1236  0
         return delegateMembersReturnList;
 1237  
     }
 1238  
 
 1239  
     private DelegateMember getDelegateCompleteInfo(DelegateBo delegateBo, DelegateMemberBo delegateMemberBo) {
 1240  0
         if (delegateBo == null || delegateMemberBo == null) {return null;}
 1241  
 
 1242  0
         DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegateMemberBo);
 1243  0
         delegateMemberBuilder.setTypeCode(delegateBo.getDelegationTypeCode());
 1244  0
         return delegateMemberBuilder.build();
 1245  
     }
 1246  
 }