001 /** 002 * Copyright 2005-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kim.document; 017 018 import org.apache.commons.collections.CollectionUtils; 019 import org.apache.commons.lang.StringUtils; 020 import org.hibernate.annotations.Fetch; 021 import org.hibernate.annotations.FetchMode; 022 import org.hibernate.annotations.GenericGenerator; 023 import org.hibernate.annotations.Parameter; 024 import org.hibernate.annotations.Type; 025 import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange; 026 import org.kuali.rice.kim.api.KimConstants; 027 import org.kuali.rice.kim.api.identity.employment.EntityEmployment; 028 import org.kuali.rice.kim.api.role.Role; 029 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 030 import org.kuali.rice.kim.api.type.KimType; 031 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember; 032 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier; 033 import org.kuali.rice.kim.bo.ui.PersonDocumentAddress; 034 import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation; 035 import org.kuali.rice.kim.bo.ui.PersonDocumentCitizenship; 036 import org.kuali.rice.kim.bo.ui.PersonDocumentEmail; 037 import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo; 038 import org.kuali.rice.kim.bo.ui.PersonDocumentGroup; 039 import org.kuali.rice.kim.bo.ui.PersonDocumentName; 040 import org.kuali.rice.kim.bo.ui.PersonDocumentPhone; 041 import org.kuali.rice.kim.bo.ui.PersonDocumentPrivacy; 042 import org.kuali.rice.kim.bo.ui.PersonDocumentRole; 043 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember; 044 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier; 045 import org.kuali.rice.kim.impl.identity.principal.PrincipalBo; 046 import org.kuali.rice.kim.impl.type.KimTypeAttributesHelper; 047 import org.kuali.rice.kim.service.KIMServiceLocatorInternal; 048 import org.kuali.rice.kim.service.UiDocumentService; 049 import org.kuali.rice.kns.service.DocumentHelperService; 050 import org.kuali.rice.kns.service.KNSServiceLocator; 051 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 052 import org.kuali.rice.krad.service.SequenceAccessorService; 053 import org.kuali.rice.krad.util.GlobalVariables; 054 055 import javax.persistence.AssociationOverride; 056 import javax.persistence.AssociationOverrides; 057 import javax.persistence.AttributeOverride; 058 import javax.persistence.AttributeOverrides; 059 import javax.persistence.CascadeType; 060 import javax.persistence.Column; 061 import javax.persistence.Entity; 062 import javax.persistence.FetchType; 063 import javax.persistence.GeneratedValue; 064 import javax.persistence.JoinColumn; 065 import javax.persistence.OneToMany; 066 import javax.persistence.OneToOne; 067 import javax.persistence.Table; 068 import javax.persistence.Transient; 069 import java.util.ArrayList; 070 import java.util.HashMap; 071 import java.util.List; 072 import java.util.Map; 073 074 /** 075 * This is a description of what this class does - shyu don't forget to fill 076 * this in. 077 * 078 * @author Kuali Rice Team (rice.collab@kuali.org) 079 * 080 */ 081 @Entity 082 @AttributeOverrides({ 083 @AttributeOverride(name="documentNumber",column=@Column(name="FDOC_NBR")) 084 }) 085 @AssociationOverrides({ 086 @AssociationOverride(name="documentHeader",joinColumns=@JoinColumn(name="FDOC_NBR",referencedColumnName="DOC_HDR_ID",insertable=false,updatable=false)) 087 }) 088 @Table(name="KRIM_PERSON_DOCUMENT_T") 089 public class IdentityManagementPersonDocument extends IdentityManagementKimDocument { 090 091 protected static final long serialVersionUID = -534993712085516925L; 092 // principal data 093 094 @GeneratedValue(generator="KRIM_PRNCPL_ID_S") 095 @GenericGenerator(name="KRIM_PRNCPL_ID_S",strategy="org.kuali.rice.core.jpa.spring.RiceNumericStringSequenceStyleGenerator",parameters={ 096 @Parameter(name="sequence_name",value="KRIM_PRNCPL_ID_S"), 097 @Parameter(name="value_column",value="id") 098 }) 099 @Column(name="PRNCPL_ID") 100 protected String principalId; 101 @Column(name="PRNCPL_NM") 102 protected String principalName; 103 @GeneratedValue(generator="KRIM_ENTITY_ID_S") 104 @GenericGenerator(name="KRIM_ENTITY_ID_S",strategy="org.kuali.rice.core.jpa.spring.RiceNumericStringSequenceStyleGenerator",parameters={ 105 @Parameter(name="sequence_name",value="KRIM_ENTITY_ID_S"), 106 @Parameter(name="value_column",value="id") 107 }) 108 @Column(name="ENTITY_ID") 109 protected String entityId; 110 @Type(type="org.kuali.rice.krad.util.HibernateKualiHashType") 111 @Column(name="PRNCPL_PSWD") 112 protected String password; 113 114 protected String univId = ""; 115 // affiliation data 116 @OneToMany(targetEntity=PersonDocumentAffiliation.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 117 @Fetch(value = FetchMode.SELECT) 118 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 119 protected List<PersonDocumentAffiliation> affiliations; 120 121 @Transient 122 protected String campusCode = ""; 123 // external identifier data 124 @Transient 125 protected Map<String, String> externalIdentifiers = null; 126 127 @Column(name="ACTV_IND") 128 @Type(type="yes_no") 129 protected boolean active; 130 131 // citizenship 132 @Transient 133 protected List<PersonDocumentCitizenship> citizenships; 134 // protected List<DocEmploymentInfo> employmentInformations; 135 @OneToMany(targetEntity=PersonDocumentName.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 136 @Fetch(value = FetchMode.SELECT) 137 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 138 protected List<PersonDocumentName> names; 139 @OneToMany(targetEntity=PersonDocumentAddress.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 140 @Fetch(value = FetchMode.SELECT) 141 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 142 protected List<PersonDocumentAddress> addrs; 143 @OneToMany(targetEntity=PersonDocumentPhone.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 144 @Fetch(value = FetchMode.SELECT) 145 @JoinColumn(name="FDOC_NBR") 146 protected List<PersonDocumentPhone> phones; 147 @OneToMany(targetEntity=PersonDocumentEmail.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 148 @Fetch(value = FetchMode.SELECT) 149 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 150 protected List<PersonDocumentEmail> emails; 151 @OneToMany(targetEntity=PersonDocumentGroup.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 152 @Fetch(value = FetchMode.SELECT) 153 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 154 protected List<PersonDocumentGroup> groups; 155 @OneToMany(targetEntity=PersonDocumentRole.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 156 @Fetch(value = FetchMode.SELECT) 157 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 158 protected List<PersonDocumentRole> roles; 159 160 @OneToOne(targetEntity=PersonDocumentPrivacy.class, fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 161 @JoinColumn(name="FDOC_NBR",insertable=false,updatable=false) 162 protected PersonDocumentPrivacy privacy; 163 164 public IdentityManagementPersonDocument() { 165 affiliations = new ArrayList<PersonDocumentAffiliation>(); 166 citizenships = new ArrayList<PersonDocumentCitizenship>(); 167 // employmentInformations = new ArrayList<DocEmploymentInfo>(); 168 names = new ArrayList<PersonDocumentName>(); 169 addrs = new ArrayList<PersonDocumentAddress>(); 170 phones = new ArrayList<PersonDocumentPhone>(); 171 emails = new ArrayList<PersonDocumentEmail>(); 172 groups = new ArrayList<PersonDocumentGroup>(); 173 roles = new ArrayList<PersonDocumentRole>(); 174 privacy = new PersonDocumentPrivacy(); 175 this.active = true; 176 // privacy.setDocumentNumber(documentNumber); 177 } 178 179 public String getPrincipalId() { 180 return this.principalId; 181 } 182 183 public void setPrincipalId(String principalId) { 184 this.principalId = principalId; 185 } 186 187 public String getPrincipalName() { 188 return this.principalName; 189 } 190 191 /* 192 * sets the principal name. 193 * Principal names are converted to lower case. 194 */ 195 public void setPrincipalName(String principalName) { 196 this.principalName = principalName; // != null ? principalName.toLowerCase() : principalName ; 197 } 198 199 public String getEntityId() { 200 return this.entityId; 201 } 202 203 public void setEntityId(String entityId) { 204 this.entityId = entityId; 205 } 206 207 public List<PersonDocumentAffiliation> getAffiliations() { 208 return this.affiliations; 209 } 210 211 public void setAffiliations(List<PersonDocumentAffiliation> affiliations) { 212 this.affiliations = affiliations; 213 } 214 215 public String getCampusCode() { 216 return this.campusCode; 217 } 218 219 public void setCampusCode(String campusCode) { 220 this.campusCode = campusCode; 221 } 222 223 public Map<String, String> getExternalIdentifiers() { 224 return this.externalIdentifiers; 225 } 226 227 public void setExternalIdentifiers(Map<String, String> externalIdentifiers) { 228 this.externalIdentifiers = externalIdentifiers; 229 } 230 231 public String getPassword() { 232 return this.password; 233 } 234 235 public void setPassword(String password) { 236 this.password = password; 237 } 238 239 public boolean isActive() { 240 return this.active; 241 } 242 243 public void setActive(boolean active) { 244 this.active = active; 245 } 246 247 public List<PersonDocumentCitizenship> getCitizenships() { 248 return this.citizenships; 249 } 250 251 public void setCitizenships(List<PersonDocumentCitizenship> citizenships) { 252 this.citizenships = citizenships; 253 } 254 255 public List<PersonDocumentName> getNames() { 256 return this.names; 257 } 258 259 public void setNames(List<PersonDocumentName> names) { 260 this.names = names; 261 } 262 263 public List<PersonDocumentAddress> getAddrs() { 264 return this.addrs; 265 } 266 267 public void setAddrs(List<PersonDocumentAddress> addrs) { 268 this.addrs = addrs; 269 } 270 271 public List<PersonDocumentPhone> getPhones() { 272 return this.phones; 273 } 274 275 public void setPhones(List<PersonDocumentPhone> phones) { 276 this.phones = phones; 277 } 278 279 public List<PersonDocumentEmail> getEmails() { 280 return this.emails; 281 } 282 283 public void setEmails(List<PersonDocumentEmail> emails) { 284 this.emails = emails; 285 } 286 287 public void setGroups(List<PersonDocumentGroup> groups) { 288 this.groups = groups; 289 } 290 291 public List<PersonDocumentRole> getRoles() { 292 return this.roles; 293 } 294 295 public void setRoles(List<PersonDocumentRole> roles) { 296 this.roles = roles; 297 } 298 299 public List<PersonDocumentGroup> getGroups() { 300 return this.groups; 301 } 302 303 public String getUnivId() { 304 return this.univId; 305 } 306 307 public void setUnivId(String univId) { 308 this.univId = univId; 309 } 310 311 public PersonDocumentPrivacy getPrivacy() { 312 return this.privacy; 313 } 314 315 public void setPrivacy(PersonDocumentPrivacy privacy) { 316 this.privacy = privacy; 317 } 318 319 public void initializeDocumentForNewPerson() { 320 if(StringUtils.isBlank(this.principalId)){ 321 this.principalId = getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_PRNCPL_ID_S, this.getClass()).toString(); 322 } 323 if(StringUtils.isBlank(this.entityId)){ 324 this.entityId = getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_ENTITY_ID_S, this.getClass()).toString(); 325 } 326 } 327 328 @SuppressWarnings("unchecked") 329 @Override 330 public List buildListOfDeletionAwareLists() { 331 List managedLists = super.buildListOfDeletionAwareLists(); 332 List<PersonDocumentEmploymentInfo> empInfos = new ArrayList<PersonDocumentEmploymentInfo>(); 333 for (PersonDocumentAffiliation affiliation : getAffiliations()) { 334 empInfos.addAll(affiliation.getEmpInfos()); 335 } 336 337 managedLists.add(empInfos); 338 managedLists.add(getAffiliations()); 339 managedLists.add(getCitizenships()); 340 managedLists.add(getPhones()); 341 managedLists.add(getAddrs()); 342 managedLists.add(getEmails()); 343 managedLists.add(getNames()); 344 managedLists.add(getGroups()); 345 managedLists.add(getRoles()); 346 return managedLists; 347 } 348 349 /** 350 * @see org.kuali.rice.krad.document.DocumentBase#doRouteStatusChange(org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange) 351 */ 352 @Override 353 public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) { 354 super.doRouteStatusChange(statusChangeEvent); 355 if (getDocumentHeader().getWorkflowDocument().isProcessed()) { 356 setIfRolesEditable(); 357 KIMServiceLocatorInternal.getUiDocumentService().saveEntityPerson(this); 358 } 359 } 360 361 362 @Override 363 public void prepareForSave(){ 364 if (StringUtils.isBlank(getPrivacy().getDocumentNumber())) { 365 getPrivacy().setDocumentNumber( 366 getDocumentNumber()); 367 } 368 setEmployeeRecordIds(); 369 for (PersonDocumentRole role : getRoles()) { 370 role.setDocumentNumber(getDocumentNumber()); 371 //if (StringUtils.isEmpty(role.getRoleId())) { 372 // SequenceAccessorService sas = getSequenceAccessorService(); 373 // Long nextSeq = sas.getNextAvailableSequenceNumber( 374 // "KRIM_ROLE_ID_S", this.getClass()); 375 // String roleId = nextSeq.toString(); 376 // role.setRoleId(roleId); 377 //} 378 for (KimDocumentRoleMember rolePrncpl : role.getRolePrncpls()) { 379 rolePrncpl.setDocumentNumber(getDocumentNumber()); 380 rolePrncpl.setRoleId(role.getRoleId()); 381 if (StringUtils.isEmpty(rolePrncpl.getRoleMemberId())) { 382 SequenceAccessorService sas = getSequenceAccessorService(); 383 Long nextSeq = sas.getNextAvailableSequenceNumber( 384 "KRIM_ROLE_MBR_ID_S", this.getClass()); 385 String roleMemberId = nextSeq.toString(); 386 rolePrncpl.setRoleMemberId(roleMemberId); 387 } 388 for (KimDocumentRoleQualifier qualifier : rolePrncpl.getQualifiers()) { 389 qualifier.setDocumentNumber(getDocumentNumber()); 390 qualifier.setKimTypId(role.getKimTypeId()); 391 } 392 } 393 } 394 if(getDelegationMembers()!=null){ 395 for(RoleDocumentDelegationMember delegationMember: getDelegationMembers()){ 396 delegationMember.setDocumentNumber(getDocumentNumber()); 397 for (RoleDocumentDelegationMemberQualifier qualifier: delegationMember.getQualifiers()) { 398 qualifier.setDocumentNumber(getDocumentNumber()); 399 qualifier.setKimTypId(delegationMember.getRoleBo().getKimTypeId()); 400 } 401 addDelegationMemberToDelegation(delegationMember); 402 } 403 } 404 if (getAddrs() != null) { 405 String entityAddressId; 406 for(PersonDocumentAddress address : getAddrs()) { 407 address.setDocumentNumber(getDocumentNumber()); 408 if (StringUtils.isEmpty(address.getEntityAddressId())) { 409 SequenceAccessorService sas = getSequenceAccessorService(); 410 Long nextSeq = sas.getNextAvailableSequenceNumber( 411 "KRIM_ENTITY_ADDR_ID_S", this.getClass()); 412 entityAddressId = nextSeq.toString(); 413 address.setEntityAddressId(entityAddressId); 414 } 415 } 416 } 417 if (getAffiliations() != null) { 418 String affiliationId; 419 for(PersonDocumentAffiliation affiliation : getAffiliations()) { 420 affiliation.setDocumentNumber(getDocumentNumber()); 421 if (StringUtils.isEmpty(affiliation.getEntityAffiliationId())) { 422 SequenceAccessorService sas = getSequenceAccessorService(); 423 Long nextSeq = sas.getNextAvailableSequenceNumber( 424 "KRIM_ENTITY_AFLTN_ID_S", this.getClass()); 425 affiliationId = nextSeq.toString(); 426 affiliation.setEntityAffiliationId(affiliationId); 427 } 428 } 429 } 430 if (getEmails() != null) { 431 String entityEmailId; 432 for(PersonDocumentEmail email : getEmails()) { 433 email.setDocumentNumber(getDocumentNumber()); 434 if (StringUtils.isEmpty(email.getEntityEmailId())) { 435 SequenceAccessorService sas = getSequenceAccessorService(); 436 Long nextSeq = sas.getNextAvailableSequenceNumber( 437 "KRIM_ENTITY_EMAIL_ID_S", this.getClass()); 438 entityEmailId = nextSeq.toString(); 439 email.setEntityEmailId(entityEmailId); 440 } 441 } 442 } 443 if (getGroups() != null) { 444 String groupMemberId; 445 for(PersonDocumentGroup group : getGroups()) { 446 group.setDocumentNumber(getDocumentNumber()); 447 if (StringUtils.isEmpty(group.getGroupMemberId())) { 448 SequenceAccessorService sas = getSequenceAccessorService(); 449 Long nextSeq = sas.getNextAvailableSequenceNumber( 450 "KRIM_GRP_MBR_ID_S", this.getClass()); 451 groupMemberId = nextSeq.toString(); 452 group.setGroupMemberId(groupMemberId); 453 } 454 } 455 } 456 if (getNames() != null) { 457 String entityNameId; 458 for(PersonDocumentName name : getNames()) { 459 name.setDocumentNumber(getDocumentNumber()); 460 if (StringUtils.isEmpty(name.getEntityNameId())) { 461 SequenceAccessorService sas = getSequenceAccessorService(); 462 Long nextSeq = sas.getNextAvailableSequenceNumber( 463 "KRIM_ENTITY_NM_ID_S", this.getClass()); 464 entityNameId = nextSeq.toString(); 465 name.setEntityNameId(entityNameId); 466 } 467 } 468 } 469 if (getPhones() != null) { 470 String entityPhoneId; 471 for(PersonDocumentPhone phone : getPhones()) { 472 phone.setDocumentNumber(getDocumentNumber()); 473 if (StringUtils.isEmpty(phone.getEntityPhoneId())) { 474 SequenceAccessorService sas = getSequenceAccessorService(); 475 Long nextSeq = sas.getNextAvailableSequenceNumber( 476 "KRIM_ENTITY_PHONE_ID_S", this.getClass()); 477 entityPhoneId = nextSeq.toString(); 478 phone.setEntityPhoneId(entityPhoneId); 479 } 480 } 481 } 482 483 } 484 485 protected void setEmployeeRecordIds(){ 486 List<EntityEmployment> empInfos = getUiDocumentService().getEntityEmploymentInformationInfo(getEntityId()); 487 for(PersonDocumentAffiliation affiliation: getAffiliations()) { 488 int employeeRecordCounter = CollectionUtils.isEmpty(empInfos) ? 0 : empInfos.size(); 489 for(PersonDocumentEmploymentInfo empInfo: affiliation.getEmpInfos()){ 490 if(CollectionUtils.isNotEmpty(empInfos)){ 491 for(EntityEmployment origEmpInfo: empInfos){ 492 if (origEmpInfo.getId().equals(empInfo.getEntityEmploymentId())) { 493 empInfo.setEmploymentRecordId(origEmpInfo.getEmploymentRecordId()); 494 } 495 } 496 } 497 if(StringUtils.isEmpty(empInfo.getEmploymentRecordId())){ 498 employeeRecordCounter++; 499 empInfo.setEmploymentRecordId(employeeRecordCounter+""); 500 } 501 } 502 } 503 } 504 505 public KimTypeAttributesHelper getKimTypeAttributesHelper(String roleId) { 506 Role role = KimApiServiceLocator.getRoleService().getRole(roleId); 507 KimType kimTypeInfo = KimApiServiceLocator.getKimTypeInfoService().getKimType(role.getKimTypeId()); 508 return new KimTypeAttributesHelper(kimTypeInfo); 509 //addDelegationRoleKimTypeAttributeHelper(roleId, helper); 510 } 511 512 public void setIfRolesEditable(){ 513 if(CollectionUtils.isNotEmpty(getRoles())){ 514 for(PersonDocumentRole role: getRoles()){ 515 role.setEditable(validAssignRole(role)); 516 } 517 } 518 } 519 520 public boolean validAssignRole(PersonDocumentRole role){ 521 boolean rulePassed = true; 522 if(StringUtils.isNotEmpty(role.getNamespaceCode())){ 523 Map<String,String> additionalPermissionDetails = new HashMap<String,String>(); 524 additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, role.getNamespaceCode()); 525 additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, role.getRoleName()); 526 if (!getDocumentHelperService().getDocumentAuthorizer(this).isAuthorizedByTemplate( 527 this, 528 KimConstants.NAMESPACE_CODE, 529 KimConstants.PermissionTemplateNames.ASSIGN_ROLE, 530 GlobalVariables.getUserSession().getPrincipalId(), 531 additionalPermissionDetails, null)){ 532 rulePassed = false; 533 } 534 } 535 return rulePassed; 536 } 537 538 @Transient 539 protected transient DocumentHelperService documentHelperService; 540 @Transient 541 protected transient UiDocumentService uiDocumentService; 542 543 protected DocumentHelperService getDocumentHelperService() { 544 if ( documentHelperService == null ) { 545 documentHelperService = KNSServiceLocator.getDocumentHelperService(); 546 } 547 return this.documentHelperService; 548 } 549 550 protected UiDocumentService getUiDocumentService() { 551 if (uiDocumentService == null ) { 552 uiDocumentService = KIMServiceLocatorInternal.getUiDocumentService(); 553 } 554 return this.uiDocumentService; 555 } 556 557 }