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