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 }