001 /*
002 * Copyright 2007-2008 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 java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 import javax.persistence.AssociationOverride;
024 import javax.persistence.AssociationOverrides;
025 import javax.persistence.AttributeOverride;
026 import javax.persistence.AttributeOverrides;
027 import javax.persistence.CascadeType;
028 import javax.persistence.Column;
029 import javax.persistence.Entity;
030 import javax.persistence.FetchType;
031 import javax.persistence.GeneratedValue;
032 import javax.persistence.JoinColumn;
033 import javax.persistence.OneToMany;
034 import javax.persistence.OneToOne;
035 import javax.persistence.Table;
036 import javax.persistence.Transient;
037
038 import org.apache.commons.collections.CollectionUtils;
039 import org.apache.commons.lang.StringUtils;
040 import org.hibernate.annotations.Fetch;
041 import org.hibernate.annotations.FetchMode;
042 import org.hibernate.annotations.GenericGenerator;
043 import org.hibernate.annotations.Parameter;
044 import org.hibernate.annotations.Type;
045 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO;
046 import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
047 import org.kuali.rice.kim.api.role.Role;
048 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
049 import org.kuali.rice.kim.api.type.KimType;
050 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
051 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
052 import org.kuali.rice.kim.bo.ui.PersonDocumentAddress;
053 import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
054 import org.kuali.rice.kim.bo.ui.PersonDocumentCitizenship;
055 import org.kuali.rice.kim.bo.ui.PersonDocumentEmail;
056 import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
057 import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
058 import org.kuali.rice.kim.bo.ui.PersonDocumentName;
059 import org.kuali.rice.kim.bo.ui.PersonDocumentPhone;
060 import org.kuali.rice.kim.bo.ui.PersonDocumentPrivacy;
061 import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
062 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
063 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
064 import org.kuali.rice.kim.impl.type.KimTypeAttributesHelper;
065 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
066 import org.kuali.rice.kim.service.UiDocumentService;
067 import org.kuali.rice.kim.util.KimConstants;
068 import org.kuali.rice.krad.service.DocumentHelperService;
069 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
070 import org.kuali.rice.krad.service.SequenceAccessorService;
071 import org.kuali.rice.krad.util.GlobalVariables;
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.dto.DocumentRouteStatusChangeDTO)
350 */
351 @Override
352 public void doRouteStatusChange(DocumentRouteStatusChangeDTO 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 = KRADServiceLocatorWeb.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 }