Coverage Report - org.kuali.rice.kim.document.rule.IdentityManagementPersonDocumentRule
 
Classes in this File Line Coverage Branch Coverage Complexity
IdentityManagementPersonDocumentRule
0%
0/372
0%
0/260
4.525
 
 1  
 /*
 2  
  * Copyright 2007-2008 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.document.rule;
 17  
 
 18  
 import org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.core.util.AttributeSet;
 21  
 import org.kuali.rice.core.util.RiceKeyConstants;
 22  
 import org.kuali.rice.kim.api.entity.principal.Principal;
 23  
 import org.kuali.rice.kim.api.entity.services.IdentityService;
 24  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 25  
 import org.kuali.rice.kim.api.type.KimType;
 26  
 import org.kuali.rice.kim.bo.entity.dto.KimEntityDefaultInfo;
 27  
 import org.kuali.rice.kim.bo.role.impl.RoleMemberImpl;
 28  
 import org.kuali.rice.kim.bo.types.dto.AttributeDefinitionMap;
 29  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
 30  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
 31  
 import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
 32  
 import org.kuali.rice.kim.bo.ui.PersonDocumentBoDefaultBase;
 33  
 import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
 34  
 import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
 35  
 import org.kuali.rice.kim.bo.ui.PersonDocumentName;
 36  
 import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
 37  
 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
 38  
 import org.kuali.rice.kim.document.IdentityManagementPersonDocument;
 39  
 import org.kuali.rice.kim.document.authorization.IdentityManagementKimDocumentAuthorizer;
 40  
 import org.kuali.rice.kim.impl.entity.principal.PrincipalBo;
 41  
 import org.kuali.rice.kim.impl.type.KimTypeBo;
 42  
 import org.kuali.rice.kim.rule.event.ui.AddGroupEvent;
 43  
 import org.kuali.rice.kim.rule.event.ui.AddPersonDelegationMemberEvent;
 44  
 import org.kuali.rice.kim.rule.event.ui.AddRoleEvent;
 45  
 import org.kuali.rice.kim.rule.ui.AddGroupRule;
 46  
 import org.kuali.rice.kim.rule.ui.AddPersonDelegationMemberRule;
 47  
 import org.kuali.rice.kim.rule.ui.AddPersonDocumentRoleQualifierRule;
 48  
 import org.kuali.rice.kim.rule.ui.AddRoleRule;
 49  
 import org.kuali.rice.kim.rules.ui.PersonDocumentDelegationMemberRule;
 50  
 import org.kuali.rice.kim.rules.ui.PersonDocumentGroupRule;
 51  
 import org.kuali.rice.kim.rules.ui.PersonDocumentRoleRule;
 52  
 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
 53  
 import org.kuali.rice.kim.service.KIMServiceLocatorWeb;
 54  
 import org.kuali.rice.kim.service.RoleService;
 55  
 import org.kuali.rice.kim.service.UiDocumentService;
 56  
 import org.kuali.rice.kim.service.support.KimTypeService;
 57  
 import org.kuali.rice.kim.util.KIMPropertyConstants;
 58  
 import org.kuali.rice.kns.datadictionary.AttributeDefinition;
 59  
 import org.kuali.rice.kns.document.Document;
 60  
 import org.kuali.rice.kns.rules.TransactionalDocumentRuleBase;
 61  
 import org.kuali.rice.kns.service.BusinessObjectService;
 62  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 63  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 64  
 import org.kuali.rice.kns.util.GlobalVariables;
 65  
 import org.kuali.rice.kns.util.KNSConstants;
 66  
 import org.kuali.rice.kns.util.ObjectUtils;
 67  
 
 68  
 import java.sql.Timestamp;
 69  
 import java.util.ArrayList;
 70  
 import java.util.HashMap;
 71  
 import java.util.HashSet;
 72  
 import java.util.List;
 73  
 import java.util.Map;
 74  
 import java.util.Set;
 75  
 
 76  
 /**
 77  
  * This is a description of what this class does - shyu don't forget to fill this in.
 78  
  *
 79  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 80  
  *
 81  
  */
 82  0
 public class IdentityManagementPersonDocumentRule extends TransactionalDocumentRuleBase implements AddGroupRule, AddRoleRule, AddPersonDocumentRoleQualifierRule, AddPersonDelegationMemberRule {
 83  
 
 84  
 //        protected static final Logger LOG = Logger.getLogger( IdentityManagementPersonDocumentRule.class );
 85  
 
 86  
         protected AddGroupRule addGroupRule;
 87  
         protected AddRoleRule  addRoleRule;
 88  
         protected AddPersonDelegationMemberRule addPersonDelegationMemberRule;
 89  
         protected IdentityManagementKimDocumentAuthorizer authorizer;
 90  
         protected BusinessObjectService businessObjectService;
 91  
         protected IdentityService identityService;
 92  
         protected RoleService roleService;
 93  
         protected UiDocumentService uiDocumentService;
 94  0
         protected Class<? extends AddGroupRule> addGroupRuleClass = PersonDocumentGroupRule.class;
 95  0
         protected Class<? extends AddRoleRule> addRoleRuleClass = PersonDocumentRoleRule.class;
 96  0
         protected Class<? extends AddPersonDelegationMemberRule> addPersonDelegationMemberRuleClass = PersonDocumentDelegationMemberRule.class;
 97  
 
 98  0
         protected AttributeValidationHelper attributeValidationHelper = new AttributeValidationHelper();
 99  
 
 100  
     @Override
 101  
     protected boolean processCustomSaveDocumentBusinessRules(Document document) {
 102  0
         if (!(document instanceof IdentityManagementPersonDocument)) {
 103  0
             return false;
 104  
         }
 105  
 
 106  0
         IdentityManagementPersonDocument personDoc = (IdentityManagementPersonDocument)document;
 107  0
         boolean valid = true;
 108  
 
 109  0
         GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 110  
 
 111  
         //KNSServiceLocatorInternal.getDictionaryValidationService().validateDocument(document);
 112  0
         getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document, getMaxDictionaryValidationDepth(), true, false);
 113  0
         valid &= validDuplicatePrincipalName(personDoc);
 114  0
         KimEntityDefaultInfo origEntity = getIdentityManagementService().getEntityDefaultInfo(personDoc.getEntityId());
 115  0
         boolean isCreatingNew = origEntity==null?true:false;
 116  0
         if(getUIDocumentService().canModifyEntity(GlobalVariables.getUserSession().getPrincipalId(), personDoc.getPrincipalId()) || isCreatingNew)
 117  0
                 valid &= validateEntityInformation(isCreatingNew, personDoc);
 118  
         // kimtypeservice.validateAttributes is not working yet.
 119  0
         valid &= validateRoleQualifier (personDoc.getRoles());
 120  0
         valid &= validateDelegationMemberRoleQualifier(personDoc.getDelegationMembers());
 121  0
         if (StringUtils.isNotBlank(personDoc.getPrincipalName())) {
 122  0
                 valid &= doesPrincipalNameExist (personDoc.getPrincipalName(), personDoc.getPrincipalId());
 123  
         }
 124  
 
 125  0
         valid &= validActiveDatesForRole (personDoc.getRoles());
 126  0
         valid &= validActiveDatesForGroup (personDoc.getGroups());
 127  0
         valid &= validActiveDatesForDelegations (personDoc.getDelegationMembers());
 128  
 
 129  
 
 130  
         // all failed at this point.
 131  
 //        valid &= checkUnassignableRoles(personDoc);
 132  
 //        valid &= checkUnpopulatableGroups(personDoc);
 133  
 
 134  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 135  
 
 136  0
         return valid;
 137  
     }
 138  
 
 139  
     protected boolean validateEntityInformation(boolean isCreatingNew, IdentityManagementPersonDocument personDoc){
 140  0
         boolean valid = true;
 141  0
         boolean canOverridePrivacyPreferences = getUIDocumentService().canOverrideEntityPrivacyPreferences(GlobalVariables.getUserSession().getPrincipalId(), personDoc.getPrincipalId());
 142  0
         valid &= checkMultipleDefault (personDoc.getAffiliations(), "affiliations");
 143  0
         if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressName())
 144  0
                 valid &= checkMultipleDefault (personDoc.getNames(), "names");
 145  0
         if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressAddress())
 146  0
                 valid &= checkMultipleDefault (personDoc.getAddrs(), "addrs");
 147  0
         if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressPhone())
 148  0
                 valid &= checkMultipleDefault (personDoc.getPhones(), "phones");
 149  0
         if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressEmail())
 150  0
                 valid &= checkMultipleDefault (personDoc.getEmails(), "emails");
 151  0
         valid &= checkPrimaryEmploymentInfo (personDoc.getAffiliations());
 152  0
         valid &= validEmployeeIDForAffiliation(personDoc.getAffiliations());
 153  0
         valid &= checkAffiliationTypeChange (personDoc.getAffiliations());
 154  0
         valid &= checkUniqueAffiliationTypePerCampus(personDoc.getAffiliations());
 155  0
             return valid;
 156  
     }
 157  
 
 158  
     @SuppressWarnings("unchecked")
 159  
         protected boolean validDuplicatePrincipalName(IdentityManagementPersonDocument personDoc){
 160  0
             Map<String, String> criteria = new HashMap<String, String>();
 161  0
             criteria.put("principalName", personDoc.getPrincipalName());
 162  0
             List<PrincipalBo> prncplImpls = (List<PrincipalBo>)getBusinessObjectService().findMatching(PrincipalBo.class, criteria);
 163  0
             boolean rulePassed = true;
 164  0
             if(prncplImpls!=null && prncplImpls.size()>0){
 165  0
                     if(prncplImpls.size()==1 && prncplImpls.get(0).getPrincipalId().equals(personDoc.getPrincipalId()))
 166  0
                             rulePassed = true;
 167  
                     else{
 168  0
                             GlobalVariables.getMessageMap().putError("document.principalName",
 169  
                                             RiceKeyConstants.ERROR_DUPLICATE_ENTRY, new String[] {"Principal Name"});
 170  0
                             rulePassed = false;
 171  
                     }
 172  
             }
 173  0
             return rulePassed;
 174  
     }
 175  
 
 176  
         protected boolean checkUnassignableRoles(IdentityManagementPersonDocument document) {
 177  0
                 boolean valid = true;
 178  0
             Map<String,Set<String>> unassignableRoles = getAuthorizer( document ).getUnassignableRoles(document, GlobalVariables.getUserSession().getPerson());
 179  0
         for (String namespaceCode : unassignableRoles.keySet()) {
 180  0
                 for (String roleName : unassignableRoles.get(namespaceCode)) {
 181  0
                         int i = 0;
 182  0
                         for (PersonDocumentRole role : document.getRoles()) {
 183  0
                                 if (role.isEditable() && namespaceCode.endsWith(role.getNamespaceCode()) && roleName.equals(role.getRoleName())) {
 184  0
                                         GlobalVariables.getMessageMap().putError("roles["+i+"].roleId", RiceKeyConstants.ERROR_ASSIGN_ROLE, new String[] {namespaceCode, roleName});
 185  0
                                 valid = false;
 186  
                                 }
 187  0
                                 i++;
 188  
                         }
 189  0
                 }
 190  
         }
 191  0
         return valid;
 192  
         }
 193  
 
 194  
         protected boolean checkUnpopulatableGroups(IdentityManagementPersonDocument document) {
 195  0
                 boolean valid = true;
 196  0
             Map<String,Set<String>> unpopulatableGroups = getAuthorizer( document ).getUnpopulateableGroups(document, GlobalVariables.getUserSession().getPerson());
 197  0
         for (String namespaceCode : unpopulatableGroups.keySet()) {
 198  0
                 for (String groupName : unpopulatableGroups.get(namespaceCode)) {
 199  0
                         int i = 0;
 200  0
                         for (PersonDocumentGroup group : document.getGroups()) {
 201  0
                                 if ( (group.getNamespaceCode() != null && namespaceCode.endsWith(group.getNamespaceCode())) && (group.getGroupName() != null && groupName.equals(group.getGroupName()))) {
 202  0
                                         GlobalVariables.getMessageMap().putError("groups["+i+"].groupId", RiceKeyConstants.ERROR_POPULATE_GROUP, new String[] {namespaceCode, groupName});
 203  
                                 }
 204  0
                                 i++;
 205  
                         }
 206  0
                 }
 207  0
                 valid = false;
 208  
         }
 209  0
         return valid;
 210  
         }
 211  
 
 212  
     @Override
 213  
         protected boolean processCustomRouteDocumentBusinessRules(Document document) {
 214  0
                 super.processCustomRouteDocumentBusinessRules(document);
 215  0
         IdentityManagementPersonDocument personDoc = (IdentityManagementPersonDocument)document;
 216  0
         boolean valid = true;
 217  0
         GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 218  0
         valid &= validateAffiliationAndName( personDoc );
 219  0
         valid &= checkAffiliationEithOneEMpInfo (personDoc.getAffiliations());
 220  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 221  
 
 222  0
         return valid;
 223  
         }
 224  
 
 225  
 
 226  
         protected boolean checkMultipleDefault (List <? extends PersonDocumentBoDefaultBase> boList, String listName) {
 227  0
             boolean valid = true;
 228  0
             boolean isDefaultSet = false;
 229  0
             int i = 0;
 230  0
             for (PersonDocumentBoDefaultBase item : boList) {
 231  0
                      if (item.isDflt()) {
 232  0
                              if (isDefaultSet) {
 233  0
                                      GlobalVariables.getMessageMap().putError(listName+"[" + i + "].dflt",RiceKeyConstants.ERROR_MULTIPLE_DEFAULT_SELETION);
 234  0
                                      valid = false;
 235  
                              } else {
 236  0
                                      isDefaultSet = true;
 237  
                              }
 238  
                      }
 239  0
                      i++;
 240  
             }
 241  0
             if (!boList.isEmpty() && !isDefaultSet) {
 242  0
                                 GlobalVariables.getMessageMap().putError(listName+"[0].dflt",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
 243  
             }
 244  0
             return valid;
 245  
     }
 246  
 
 247  
     protected boolean checkPrimaryEmploymentInfo (List <PersonDocumentAffiliation> affiliations) {
 248  0
             boolean valid = true;
 249  0
             int i = 0;
 250  0
             int firstAfflnCounter = -1;
 251  0
             boolean isPrimarySet = false;
 252  0
             for (PersonDocumentAffiliation affiliation : affiliations) {
 253  0
                     int j = 0;
 254  0
                     for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
 255  0
                              if(firstAfflnCounter==-1)
 256  0
                                      firstAfflnCounter = i;
 257  0
                             if (empInfo.isPrimary()) {
 258  0
                                      if (isPrimarySet) {
 259  
                                              // primary per principal or primary per affiliation ?
 260  0
                                              GlobalVariables.getMessageMap().putError("affiliations[" + i + "].empInfos["+ j +"].primary",RiceKeyConstants.ERROR_MULTIPLE_PRIMARY_EMPLOYMENT);
 261  0
                                              valid = false;
 262  
                                      } else {
 263  0
                                              isPrimarySet = true;
 264  
                                      }
 265  0
                                      j++;
 266  
                              }
 267  
                     }
 268  0
                      i++;
 269  0
             }
 270  0
             if(!isPrimarySet && firstAfflnCounter!=-1){
 271  0
                     GlobalVariables.getMessageMap().putError("affiliations[" + firstAfflnCounter + "].empInfos[0].primary",RiceKeyConstants.ERROR_NO_PRIMARY_EMPLOYMENT);
 272  0
                     valid = false;
 273  
             }
 274  0
             return valid;
 275  
     }
 276  
 
 277  
     protected boolean checkAffiliationTypeChange (List <PersonDocumentAffiliation> affiliations) {
 278  0
             boolean valid = true;
 279  0
             int i = 0;
 280  0
             for (PersonDocumentAffiliation affiliation : affiliations) {
 281  0
                     if (affiliation.getAffiliationType() != null && !affiliation.getAffiliationTypeCode().equals(affiliation.getAffiliationType().getAffiliationTypeCode())) {
 282  0
                             PersonDocumentAffiliation copiedAffiliation = (PersonDocumentAffiliation)ObjectUtils.deepCopy(affiliation);
 283  0
                             copiedAffiliation.refreshReferenceObject("affiliationType");
 284  0
                             if (!copiedAffiliation.getAffiliationType().isEmploymentAffiliationType() && affiliation.getAffiliationType().isEmploymentAffiliationType() && !copiedAffiliation.getEmpInfos().isEmpty()) {
 285  0
                                      GlobalVariables.getMessageMap().putError("affiliations[" + i + "].affiliationTypeCode",RiceKeyConstants.ERROR_NOT_EMPLOYMENT_AFFILIATION_TYPE,new String[] {affiliation.getAffiliationType().getAffiliationTypeName(), copiedAffiliation.getAffiliationType().getAffiliationTypeName()});
 286  0
                                      valid = false;
 287  
                             }
 288  
                     }
 289  0
                 i++;
 290  
             }
 291  0
             return valid;
 292  
     }
 293  
 
 294  
     protected boolean validEmployeeIDForAffiliation(List <PersonDocumentAffiliation> affiliations) {
 295  0
             boolean valid = true;
 296  0
             int i = 0;
 297  0
             int j = 0;
 298  0
             for(PersonDocumentAffiliation affiliation : affiliations) {
 299  0
                     if(affiliation.getAffiliationType() != null && affiliation.getAffiliationType().isEmploymentAffiliationType()){
 300  0
                             if(affiliation.getEmpInfos()!=null){
 301  0
                                 j = 0;
 302  0
                                 for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
 303  0
                                         if (StringUtils.isEmpty(empInfo.getEmployeeId())) {
 304  0
                                                         GlobalVariables.getMessageMap().putError("affiliations[" + i + "].empInfos["+ j +"].employeeId", RiceKeyConstants.ERROR_REQUIRED_CONDITIONALLY, new String[] {"Employee ID", "an employee"});
 305  0
                                                         valid = false;
 306  0
                                                  j++;
 307  
                                          }
 308  
                                 }
 309  
                             }
 310  
                     }
 311  0
                 i++;
 312  
             }
 313  0
             return valid;
 314  
     }
 315  
 
 316  
     protected boolean isPersonAnEmployee(List<PersonDocumentAffiliation> affiliations){
 317  0
             boolean isEmployee = false;
 318  0
             for (PersonDocumentAffiliation affiliation : affiliations){
 319  0
                     if (affiliation.getAffiliationType() != null && affiliation.getAffiliationType().isEmploymentAffiliationType()){
 320  0
                             isEmployee = true;
 321  0
                             break;
 322  
                     }
 323  
             }
 324  0
             return isEmployee;
 325  
     }
 326  
 
 327  
     protected boolean checkUniqueAffiliationTypePerCampus (List <PersonDocumentAffiliation> affiliations) {
 328  0
             boolean valid = true;
 329  0
             int i = 0;
 330  0
             for (PersonDocumentAffiliation affiliation : affiliations) {
 331  0
                     int j = 0;
 332  0
                 for (PersonDocumentAffiliation affiliation1 : affiliations) {
 333  0
                             if (j > i && affiliation.getAffiliationTypeCode() .equals(affiliation1.getAffiliationTypeCode()) && affiliation.getCampusCode().equals(affiliation1.getCampusCode())) {
 334  0
                                              GlobalVariables.getMessageMap().putError("affiliations[" + j + "].affiliationTypeCode",RiceKeyConstants.ERROR_NOT_UNIQUE_AFFILIATION_TYPE_PER_CAMPUE, affiliation.getAffiliationType().getAffiliationTypeName());
 335  0
                                              valid = false;
 336  
                             }
 337  0
                             j++;
 338  
                 }
 339  0
                 i++;
 340  0
             }
 341  0
             return valid;
 342  
     }
 343  
 
 344  
     protected boolean checkAffiliationEithOneEMpInfo (List <PersonDocumentAffiliation> affiliations) {
 345  0
             boolean valid = true;
 346  0
             int i = 0;
 347  0
             for (PersonDocumentAffiliation affiliation : affiliations) {
 348  0
                             if (affiliation.getAffiliationType() .isEmploymentAffiliationType() && affiliation.getEmpInfos().isEmpty()) {
 349  0
                                              GlobalVariables.getMessageMap().putError("affiliations[" + i + "].affiliationTypeCode",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "Employment Information");
 350  0
                                              valid = false;
 351  
                             }
 352  0
                 i++;
 353  
             }
 354  0
             return valid;
 355  
     }
 356  
 
 357  
     /*
 358  
      * Verify at least one affiliation and one default name
 359  
      */
 360  
     protected boolean validateAffiliationAndName(IdentityManagementPersonDocument personDoc) {
 361  0
             boolean valid = true;
 362  0
             if (personDoc.getAffiliations().isEmpty()) {
 363  0
                      GlobalVariables.getMessageMap().putError("affiliations[0]",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "affiliation");
 364  0
                      valid = false;
 365  
             }
 366  0
             if (personDoc.getNames().isEmpty()) {
 367  0
                      GlobalVariables.getMessageMap().putError("names[0]",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "name");
 368  0
                      valid = false;
 369  
             } else{
 370  0
                 boolean activeExists = false;
 371  0
                 for(PersonDocumentName name: personDoc.getNames()){
 372  0
                         if(name.isActive()){
 373  0
                                 activeExists = true;
 374  
                                }
 375  
                 }
 376  0
                 if(!activeExists){
 377  0
                         GlobalVariables.getMessageMap().putError("names[0]", RiceKeyConstants.ERROR_ONE_ACTIVE_ITEM_REQUIRED, "name");
 378  0
                              valid = false;
 379  
                 }
 380  0
                 return valid;
 381  
 
 382  
             }
 383  0
             return valid;
 384  
     }
 385  
 
 386  
     protected boolean doesPrincipalNameExist (String principalName, String principalId) {
 387  0
             Principal principal = getIdentityService().getPrincipalByPrincipalName(principalName);
 388  0
             if (principal != null && (StringUtils.isBlank(principalId) || !principal.getPrincipalId().equals(principalId))) {
 389  0
                 GlobalVariables.getMessageMap().putError(KIMPropertyConstants.Person.PRINCIPAL_NAME,RiceKeyConstants.ERROR_EXIST_PRINCIPAL_NAME, principalName);
 390  0
                         return false;
 391  
             }
 392  0
             return true;
 393  
     }
 394  
 
 395  
     protected boolean validateRoleQualifier( List<PersonDocumentRole> roles ) {
 396  0
                 AttributeSet validationErrors = new AttributeSet();
 397  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 398  0
         int i = 0;
 399  0
             for(PersonDocumentRole role : roles ) {
 400  0
                     KimTypeService kimTypeService = KIMServiceLocatorWeb.getKimTypeService(KimTypeBo.to(role.getKimRoleType()));
 401  0
                 if(CollectionUtils.isEmpty(role.getRolePrncpls()) && !role.getDefinitions().isEmpty()){
 402  0
                         KimType kimTypeInfo = KimApiServiceLocator.getKimTypeInfoService().getKimType(role.getKimRoleType().getId());
 403  0
                         AttributeSet blankQualifiers = attributeValidationHelper.getBlankValueQualifiersMap(kimTypeInfo.getAttributeDefinitions());
 404  0
                         AttributeSet localErrors = kimTypeService.validateAttributes(
 405  
                                 role.getKimRoleType().getId(), blankQualifiers);
 406  0
                         if(localErrors!=null && !localErrors.isEmpty()){
 407  0
                                 GlobalVariables.getMessageMap().putError("document.roles["+i+"].newRolePrncpl.qualifiers[0].attrVal",
 408  
                                                 RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "Role Qualifier");
 409  0
                                 return false;
 410  
                         }
 411  
                 }
 412  
 
 413  0
                 final AttributeDefinitionMap attributeDefinitions = role.getDefinitions();
 414  0
                 final Set<String> uniqueQualifierAttributes = findUniqueQualificationAttributes(role, attributeDefinitions);
 415  
 
 416  0
                 if ( kimTypeService != null ) {
 417  0
                         int j = 0;
 418  0
                         for ( KimDocumentRoleMember rolePrincipal : role.getRolePrncpls() ) {
 419  0
                                 AttributeSet localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), attributeValidationHelper.convertQualifiersToMap( rolePrincipal.getQualifiers() ) );
 420  0
                                 validationErrors.putAll( attributeValidationHelper.convertErrors("roles["+i+"].rolePrncpls["+j+"]",attributeValidationHelper.convertQualifiersToAttrIdxMap(rolePrincipal.getQualifiers()),localErrors) );
 421  
 
 422  0
                                 if (uniqueQualifierAttributes.size() > 0) {
 423  0
                                         validateUniquePersonRoleQualifiersUniqueForMembership(role, rolePrincipal, j, uniqueQualifierAttributes, i, validationErrors);
 424  
                                 }
 425  
 
 426  0
                                 j++;
 427  0
                         }
 428  
                 }
 429  0
                 i++;
 430  0
             }
 431  0
         GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 432  0
             if (validationErrors.isEmpty()) {
 433  0
                     return true;
 434  
             } else {
 435  0
                     attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
 436  0
                     return false;
 437  
             }
 438  
     }
 439  
 
 440  
     /**
 441  
      * Checks all the qualifiers for the given membership, so that all qualifiers which should be unique are guaranteed to be unique
 442  
      *
 443  
      * @param membership the membership to check
 444  
      * @param attributeDefinitions the Map of attribute definitions used by the role
 445  
      * @param roleIndex the index of the role on the document (for error reporting purposes)
 446  
      * @param memberIndex the index of the person's membership in the role (for error reporting purposes)
 447  
      * @return true if all unique values are indeed unique, false otherwise
 448  
      */
 449  
     protected boolean validateUniquePersonRoleQualifiersUniqueForMembership(PersonDocumentRole role, KimDocumentRoleMember membershipToCheck, int membershipToCheckIndex, Set<String> uniqueQualifierAttributes, int roleIndex, AttributeSet validationErrors) {
 450  0
             boolean foundError = false;
 451  0
             int count = 0;
 452  
 
 453  0
             for (KimDocumentRoleMember membership : role.getRolePrncpls()) {
 454  0
                     if (membershipToCheckIndex != count) {
 455  0
                             if (sameMembershipQualifications(membershipToCheck, membership, uniqueQualifierAttributes)) {
 456  0
                                     foundError = true;
 457  
 
 458  0
                                     int qualifierCount = 0;
 459  
 
 460  0
                                         for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
 461  0
                                                 if (qualifier != null && uniqueQualifierAttributes.contains(qualifier.getKimAttrDefnId())) {
 462  0
                                                         validationErrors.put("document.roles["+roleIndex+"].rolePrncpls["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+qualifier.getKimAttribute().getAttributeName()+";"+qualifier.getAttrVal());
 463  
                                                 }
 464  0
                                                 qualifierCount += 1;
 465  
                                         }
 466  
                             }
 467  
                     }
 468  
 
 469  0
                     count += 1;
 470  
             }
 471  0
             return foundError;
 472  
     }
 473  
 
 474  
     /**
 475  
      * Determines if two seperate memberships have the same qualifications
 476  
      * @param membershipA the first membership to check
 477  
      * @param membershipB the second membership to check
 478  
      * @param uniqueQualifierAttributes the set of qualifier attributes which need to be unique
 479  
      * @return true if equal, false if otherwise
 480  
      */
 481  
     protected boolean sameMembershipQualifications(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB, Set<String> uniqueQualifierAttributes) {
 482  0
             boolean equalSoFar = true;
 483  0
             for (String uniqueQualifierAttributeDefinitionId : uniqueQualifierAttributes) {
 484  0
                     final KimDocumentRoleQualifier qualifierA = membershipA.getQualifier(uniqueQualifierAttributeDefinitionId);
 485  0
                     final KimDocumentRoleQualifier qualifierB = membershipB.getQualifier(uniqueQualifierAttributeDefinitionId);
 486  
 
 487  0
                     if (qualifierA != null && qualifierB != null) {
 488  0
                             equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
 489  
                     }
 490  0
             }
 491  0
             return equalSoFar;
 492  
     }
 493  
 
 494  
     /**
 495  
      * Finds the set of unique qualification attributes for the given role
 496  
      *
 497  
      * @param role the role associated with this person
 498  
      * @param attributeDefinitions the Map of attribute definitions where we can find out if a KimAttribute is supposed to be unique
 499  
      * @return a Set of attribute definition ids for qualifications which are supposed to be unique
 500  
      */
 501  
     public Set<String> findUniqueQualificationAttributes(PersonDocumentRole role, AttributeDefinitionMap attributeDefinitions) {
 502  0
             Set<String> uniqueQualifications = new HashSet<String>();
 503  
 
 504  0
             if (role.getRolePrncpls() != null && role.getRolePrncpls().size() > 1) {
 505  0
                     final KimDocumentRoleMember membership = role.getRolePrncpls().get(0);
 506  0
                     for (KimDocumentRoleQualifier qualifier: membership.getQualifiers()) {
 507  0
                             if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
 508  0
                                 final AttributeDefinition relatedDefinition = attributeDefinitions.getByAttributeName(qualifier.getKimAttribute().getAttributeName());
 509  
 
 510  0
                                 if (relatedDefinition != null && relatedDefinition.getUnique() != null && relatedDefinition.getUnique().booleanValue()) {
 511  0
                                         uniqueQualifications.add(qualifier.getKimAttrDefnId());
 512  
                                 }
 513  0
                             }
 514  
                     }
 515  
             }
 516  
 
 517  0
             return uniqueQualifications;
 518  
     }
 519  
 
 520  
     protected boolean validActiveDatesForRole (List<PersonDocumentRole> roles ) {
 521  0
             boolean valid = true;
 522  0
                 int i = 0;
 523  0
             for(PersonDocumentRole role : roles ) {
 524  0
                         int j = 0;
 525  0
                     for (KimDocumentRoleMember principal : role.getRolePrncpls()) {
 526  0
                             valid &= validateActiveDate("roles["+i+"].rolePrncpls["+j+"].activeToDate",principal.getActiveFromDate(), principal.getActiveToDate());
 527  0
                             j++;
 528  
                     }
 529  0
                     i++;
 530  0
             }
 531  0
             return valid;
 532  
     }
 533  
 
 534  
     protected boolean validActiveDatesForGroup (List<PersonDocumentGroup> groups ) {
 535  0
             boolean valid = true;
 536  0
                 int i = 0;
 537  0
             for(PersonDocumentGroup group : groups ) {
 538  0
                      valid &= validateActiveDate("groups["+i+"].activeToDate",group.getActiveFromDate(), group.getActiveToDate());
 539  0
                     i++;
 540  
             }
 541  0
             return valid;
 542  
     }
 543  
 
 544  
     protected boolean validActiveDatesForDelegations(List<RoleDocumentDelegationMember> delegationMembers) {
 545  0
             boolean valid = true;
 546  0
                 int i = 0;
 547  0
                 for(RoleDocumentDelegationMember delegationMember: delegationMembers){
 548  0
                      valid &= validateActiveDate("delegationMembers["+i+"].activeToDate", delegationMember.getActiveFromDate(), delegationMember.getActiveToDate());
 549  0
                     i++;
 550  
                 }
 551  0
             return valid;
 552  
     }
 553  
 
 554  
         protected boolean validateActiveDate(String errorPath, Timestamp activeFromDate, Timestamp activeToDate) {
 555  
                 // TODO : do not have detail bus rule yet, so just check this for now.
 556  0
                 boolean valid = true;
 557  0
                 if (activeFromDate != null && activeToDate !=null && activeToDate.before(activeFromDate)) {
 558  0
                 GlobalVariables.getMessageMap().putError(errorPath, RiceKeyConstants.ERROR_ACTIVE_TO_DATE_BEFORE_FROM_DATE);
 559  0
             valid = false;
 560  
                 }
 561  0
                 return valid;
 562  
         }
 563  
 
 564  
     public boolean processAddGroup(AddGroupEvent addGroupEvent) {
 565  0
         return getAddGroupRule().processAddGroup(addGroupEvent);
 566  
     }
 567  
 
 568  
     public boolean processAddRole(AddRoleEvent addRoleEvent) {
 569  0
         return getAddRoleRule().processAddRole(addRoleEvent);
 570  
     }
 571  
 
 572  
     public boolean processAddPersonDelegationMember(AddPersonDelegationMemberEvent addPersonDelegationMemberEvent){
 573  0
             return getAddPersonDelegationMemberRule().processAddPersonDelegationMember(addPersonDelegationMemberEvent);
 574  
     }
 575  
 
 576  
         public IdentityService getIdentityService() {
 577  0
                 if ( identityService == null ) {
 578  0
                         identityService = KimApiServiceLocator.getIdentityService();
 579  
                 }
 580  0
                 return identityService;
 581  
         }
 582  
 
 583  
         public RoleService getRoleService() {
 584  0
                 if ( roleService == null ) {
 585  0
                         roleService = KimApiServiceLocator.getRoleService();
 586  
                 }
 587  0
                 return roleService;
 588  
         }
 589  
 
 590  
         public UiDocumentService getUIDocumentService() {
 591  0
                 if ( uiDocumentService == null ) {
 592  0
                         uiDocumentService = KIMServiceLocatorInternal.getUiDocumentService();
 593  
                 }
 594  0
                 return uiDocumentService;
 595  
         }
 596  
 
 597  
         public IdentityManagementKimDocumentAuthorizer getAuthorizer(IdentityManagementPersonDocument document) {
 598  0
                 if ( authorizer == null ) {
 599  0
                         authorizer = (IdentityManagementKimDocumentAuthorizer) KNSServiceLocatorWeb.getDocumentHelperService().getDocumentAuthorizer(document);
 600  
                 }
 601  0
                 return authorizer;
 602  
         }
 603  
 
 604  
 
 605  
 
 606  
         /**
 607  
          * @return the addGroupRuleClass
 608  
          */
 609  
         public Class<? extends AddGroupRule> getAddGroupRuleClass() {
 610  0
                 return this.addGroupRuleClass;
 611  
         }
 612  
 
 613  
 
 614  
 
 615  
         /**
 616  
          * Can be overridden by subclasses to indicate the rule class to use when adding groups.
 617  
          *
 618  
          * @param addGroupRuleClass the addGroupRuleClass to set
 619  
          */
 620  
         public void setAddGroupRuleClass(Class<? extends AddGroupRule> addGroupRuleClass) {
 621  0
                 this.addGroupRuleClass = addGroupRuleClass;
 622  0
         }
 623  
 
 624  
 
 625  
 
 626  
         /**
 627  
          * @return the addRoleRuleClass
 628  
          */
 629  
         public Class<? extends AddRoleRule> getAddRoleRuleClass() {
 630  0
                 return this.addRoleRuleClass;
 631  
         }
 632  
 
 633  
 
 634  
 
 635  
         /**
 636  
          * Can be overridden by subclasses to indicate the rule class to use when adding roles.
 637  
          *
 638  
          * @param addRoleRuleClass the addRoleRuleClass to set
 639  
          */
 640  
         public void setAddRoleRuleClass(Class<? extends AddRoleRule> addRoleRuleClass) {
 641  0
                 this.addRoleRuleClass = addRoleRuleClass;
 642  0
         }
 643  
 
 644  
 
 645  
 
 646  
         /**
 647  
          * @return the addGroupRule
 648  
          */
 649  
         public AddGroupRule getAddGroupRule() {
 650  0
                 if ( addGroupRule == null ) {
 651  
                         try {
 652  0
                                 addGroupRule = addGroupRuleClass.newInstance();
 653  0
                         } catch ( Exception ex ) {
 654  0
                                 throw new RuntimeException( "Unable to create AddGroupRule instance using class: " + addGroupRuleClass, ex );
 655  0
                         }
 656  
                 }
 657  0
                 return addGroupRule;
 658  
         }
 659  
 
 660  
 
 661  
 
 662  
         /**
 663  
          * @return the addRoleRule
 664  
          */
 665  
         public AddRoleRule getAddRoleRule() {
 666  0
                 if ( addRoleRule == null ) {
 667  
                         try {
 668  0
                                 addRoleRule = addRoleRuleClass.newInstance();
 669  0
                         } catch ( Exception ex ) {
 670  0
                                 throw new RuntimeException( "Unable to create AddRoleRule instance using class: " + addRoleRuleClass, ex );
 671  0
                         }
 672  
                 }
 673  0
                 return addRoleRule;
 674  
         }
 675  
 
 676  
         /**
 677  
          * @return the addRoleRule
 678  
          */
 679  
         public AddPersonDelegationMemberRule getAddPersonDelegationMemberRule() {
 680  0
                 if(addPersonDelegationMemberRule == null){
 681  
                         try {
 682  0
                                 addPersonDelegationMemberRule = addPersonDelegationMemberRuleClass.newInstance();
 683  0
                         } catch ( Exception ex ) {
 684  0
                                 throw new RuntimeException( "Unable to create AddPersonDelegationMemberRuleClass instance using class: " + addPersonDelegationMemberRuleClass, ex );
 685  0
                         }
 686  
                 }
 687  0
                 return addPersonDelegationMemberRule;
 688  
         }
 689  
 
 690  
         /**
 691  
          * @return the businessObjectService
 692  
          */
 693  
         public BusinessObjectService getBusinessObjectService() {
 694  0
                 if ( businessObjectService == null ) {
 695  0
                         businessObjectService = KNSServiceLocator.getBusinessObjectService();
 696  
                 }
 697  0
                 return businessObjectService;
 698  
         }
 699  
 
 700  
         public boolean processAddPersonDocumentRoleQualifier(IdentityManagementPersonDocument document, PersonDocumentRole role, KimDocumentRoleMember kimDocumentRoleMember, int selectedRoleIdx) {
 701  0
                 boolean dateValidationSuccess = validateActiveDate("document.roles[" + selectedRoleIdx + "].newRolePrncpl.activeFromDate", kimDocumentRoleMember.getActiveFromDate(), kimDocumentRoleMember.getActiveToDate());
 702  0
                 String errorPath = "roles[" + selectedRoleIdx + "].newRolePrncpl";
 703  0
                 AttributeSet validationErrors = new AttributeSet();
 704  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 705  0
         KimTypeService kimTypeService = KIMServiceLocatorWeb.getKimTypeService(KimTypeBo.to(role.getKimRoleType()));
 706  
 
 707  
         boolean attributesUnique;
 708  
                 AttributeSet errorsAttributesAgainstExisting;
 709  0
             int i = 0;
 710  0
             boolean rulePassed = true;
 711  0
             AttributeSet newMemberQualifiers = attributeValidationHelper.convertQualifiersToMap(kimDocumentRoleMember.getQualifiers());
 712  
             AttributeSet oldMemberQualifiers;
 713  0
             List<String> roleIds = new ArrayList<String>();
 714  0
             roleIds.add(role.getRoleId());
 715  
             //List<RoleMembershipInfo> roleMembersForRole = getRoleService().getFirstLevelRoleMembers(roleIds);
 716  0
             for(KimDocumentRoleMember member: role.getRolePrncpls()){
 717  0
                     oldMemberQualifiers = member.getQualifierAsAttributeSet();
 718  0
                     errorsAttributesAgainstExisting = kimTypeService.validateAttributesAgainstExisting(
 719  
                                     role.getKimRoleType().getId(), newMemberQualifiers, oldMemberQualifiers);
 720  0
                     validationErrors.putAll(
 721  
                                         attributeValidationHelper.convertErrors(
 722  
                                                 errorPath,
 723  
                                                 attributeValidationHelper.convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()),
 724  
                                                 errorsAttributesAgainstExisting));
 725  
 
 726  0
                     attributesUnique = kimTypeService.validateUniqueAttributes(
 727  
                                     role.getKimRoleType().getId(), newMemberQualifiers, oldMemberQualifiers);
 728  0
                     if (!attributesUnique){
 729  0
                     GlobalVariables.getMessageMap().putError("document."+errorPath+".qualifiers[0].attrVal", RiceKeyConstants.ERROR_DUPLICATE_ENTRY, new String[] {"Role Qualifier"});
 730  0
                     return false;
 731  
                     }
 732  0
                     i++;
 733  
             }
 734  
 
 735  0
         if ( kimTypeService != null ) {
 736  0
                 AttributeSet localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), newMemberQualifiers );
 737  0
                 validationErrors.putAll( attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper.convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()), localErrors));
 738  
         }
 739  
 
 740  0
         GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 741  0
             if (validationErrors.isEmpty()) {
 742  0
                     rulePassed = dateValidationSuccess;
 743  
             } else {
 744  0
                     attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
 745  0
                     rulePassed = false;
 746  
             }
 747  0
             return rulePassed;
 748  
         }
 749  
 
 750  
     protected boolean validateDelegationMemberRoleQualifier(List<RoleDocumentDelegationMember> delegationMembers){
 751  0
                 AttributeSet validationErrors = new AttributeSet();
 752  
                 boolean valid;
 753  0
                 int memberCounter = 0;
 754  
                 AttributeSet errorsTemp;
 755  
                 AttributeSet attributeSetToValidate;
 756  
         KimTypeService kimTypeService;
 757  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 758  
         RoleMemberImpl roleMember;
 759  
         String errorPath;
 760  
         ArrayList<String> roleIds;
 761  
         KimType kimType;
 762  0
                 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
 763  0
                         kimType = KimTypeBo.to(delegationMember.getRoleImpl().getKimRoleType());
 764  0
                         kimTypeService = KIMServiceLocatorWeb.getKimTypeService(kimType);
 765  0
                         roleIds = new ArrayList<String>();
 766  0
                         roleIds.add(delegationMember.getRoleImpl().getRoleId());
 767  0
                         errorPath = "delegationMembers["+memberCounter+"]";
 768  0
                         attributeSetToValidate = attributeValidationHelper.convertQualifiersToMap(delegationMember.getQualifiers());
 769  0
                         errorsTemp = kimTypeService.validateAttributes(kimType.getId(), attributeSetToValidate);
 770  0
                         validationErrors.putAll(
 771  
                                         attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper.convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()), errorsTemp));
 772  
 
 773  0
                         roleMember = getUIDocumentService().getRoleMember(delegationMember.getRoleMemberId());
 774  0
                         if(roleMember==null){
 775  0
                                 valid = false;
 776  0
                                 GlobalVariables.getMessageMap().putError("document."+errorPath, RiceKeyConstants.ERROR_DELEGATE_ROLE_MEMBER_ASSOCIATION, new String[]{});
 777  
                         } else{
 778  0
                                 errorsTemp = kimTypeService.validateUnmodifiableAttributes(
 779  
                                                                 kimType.getId(), roleMember.getQualifier(), attributeSetToValidate);
 780  0
                                 validationErrors.putAll(
 781  
                                                 attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper.convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()), errorsTemp));
 782  
                         }
 783  0
                 memberCounter++;
 784  
             }
 785  0
                 GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 786  0
             if (validationErrors.isEmpty()) {
 787  0
                     valid = true;
 788  
             } else {
 789  0
                     attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
 790  0
                     valid = false;
 791  
             }
 792  0
             return valid;
 793  
     }
 794  
 
 795  
 }