001/**
002 * Copyright 2005-2015 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 */
016package org.kuali.rice.kim.impl.identity.entity;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import javax.persistence.Cacheable;
022import javax.persistence.CascadeType;
023import javax.persistence.Column;
024import javax.persistence.Convert;
025import javax.persistence.GeneratedValue;
026import javax.persistence.Id;
027import javax.persistence.JoinColumn;
028import javax.persistence.OneToMany;
029import javax.persistence.OneToOne;
030import javax.persistence.PrimaryKeyJoinColumn;
031import javax.persistence.Table;
032
033import org.apache.commons.collections.CollectionUtils;
034import org.apache.commons.lang.StringUtils;
035import org.eclipse.persistence.annotations.BatchFetch;
036import org.eclipse.persistence.annotations.JoinFetch;
037import org.eclipse.persistence.annotations.JoinFetchType;
038import org.kuali.rice.kim.api.KimConstants;
039import org.kuali.rice.kim.api.identity.EntityUtils;
040import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
041import org.kuali.rice.kim.api.identity.citizenship.EntityCitizenship;
042import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
043import org.kuali.rice.kim.api.identity.entity.Entity;
044import org.kuali.rice.kim.api.identity.entity.EntityContract;
045import org.kuali.rice.kim.api.identity.entity.EntityDefault;
046import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifier;
047import org.kuali.rice.kim.api.identity.name.EntityName;
048import org.kuali.rice.kim.api.identity.name.EntityNameContract;
049import org.kuali.rice.kim.api.identity.personal.EntityEthnicity;
050import org.kuali.rice.kim.api.identity.principal.Principal;
051import org.kuali.rice.kim.api.identity.residency.EntityResidency;
052import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
053import org.kuali.rice.kim.api.identity.visa.EntityVisa;
054import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
055import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipBo;
056import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
057import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierBo;
058import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
059import org.kuali.rice.kim.impl.identity.personal.EntityBioDemographicsBo;
060import org.kuali.rice.kim.impl.identity.personal.EntityEthnicityBo;
061import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
062import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
063import org.kuali.rice.kim.impl.identity.residency.EntityResidencyBo;
064import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
065import org.kuali.rice.kim.impl.identity.visa.EntityVisaBo;
066import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
067import org.kuali.rice.krad.bo.DataObjectBase;
068import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
069import org.kuali.rice.krad.data.jpa.converters.BooleanYNConverter;
070import org.kuali.rice.krad.data.platform.MaxValueIncrementerFactory;
071import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
072
073@javax.persistence.Entity
074@Cacheable(false)
075@Table(name = "KRIM_ENTITY_T")
076public class EntityBo extends DataObjectBase implements EntityContract {
077
078    private static final long serialVersionUID = -2448541334029932773L;
079
080    @PortableSequenceGenerator(name = "KRIM_ENTITY_ID_S")
081    @GeneratedValue(generator = "KRIM_ENTITY_ID_S")
082    @Id
083    @Column(name = "ENTITY_ID")
084    private String id;
085
086    @JoinFetch(value= JoinFetchType.OUTER)
087    @OneToMany(targetEntity = EntityNameBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
088    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
089    private List<EntityNameBo> names = new ArrayList<EntityNameBo>();
090
091    @JoinFetch(value= JoinFetchType.OUTER)
092    @OneToMany(targetEntity = PrincipalBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
093    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
094    private List<PrincipalBo> principals = new ArrayList<PrincipalBo>();
095
096    @JoinFetch(value= JoinFetchType.OUTER)
097    @OneToMany(targetEntity = EntityExternalIdentifierBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
098    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
099    private List<EntityExternalIdentifierBo> externalIdentifiers = new ArrayList<EntityExternalIdentifierBo>();
100
101    @JoinFetch(value= JoinFetchType.OUTER)
102    @OneToMany(targetEntity = EntityAffiliationBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
103    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
104    private List<EntityAffiliationBo> affiliations = new ArrayList<EntityAffiliationBo>();
105
106    @JoinFetch(value= JoinFetchType.OUTER)
107    @OneToMany(targetEntity = EntityEmploymentBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
108    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
109    private List<EntityEmploymentBo> employmentInformation = new ArrayList<EntityEmploymentBo>();
110
111    @JoinFetch(value= JoinFetchType.OUTER)
112    @OneToMany(targetEntity = EntityTypeContactInfoBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
113    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
114    private List<EntityTypeContactInfoBo> entityTypeContactInfos = new ArrayList<EntityTypeContactInfoBo>();
115
116    @JoinFetch(value= JoinFetchType.OUTER)
117    @OneToOne(targetEntity = EntityPrivacyPreferencesBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
118    @PrimaryKeyJoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID")
119    private EntityPrivacyPreferencesBo privacyPreferences;
120
121    @JoinFetch(value= JoinFetchType.OUTER)
122    @OneToOne(targetEntity = EntityBioDemographicsBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
123    @PrimaryKeyJoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID")
124    private EntityBioDemographicsBo bioDemographics;
125
126    @JoinFetch(value= JoinFetchType.OUTER)
127    @OneToMany(targetEntity = EntityCitizenshipBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
128    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
129    private List<EntityCitizenshipBo> citizenships = new ArrayList<EntityCitizenshipBo>();
130
131    @JoinFetch(value= JoinFetchType.OUTER)
132    @OneToMany(targetEntity = EntityEthnicityBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
133    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
134    private List<EntityEthnicityBo> ethnicities = new ArrayList<EntityEthnicityBo>();
135
136    @JoinFetch(value= JoinFetchType.OUTER)
137    @OneToMany(targetEntity = EntityResidencyBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
138    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
139    private List<EntityResidencyBo> residencies = new ArrayList<EntityResidencyBo>();
140
141    @JoinFetch(value= JoinFetchType.OUTER)
142    @OneToMany(targetEntity = EntityVisaBo.class, orphanRemoval = true, cascade = CascadeType.ALL)
143    @JoinColumn(name = "ENTITY_ID", referencedColumnName = "ENTITY_ID", insertable = false, updatable = false)
144    private List<EntityVisaBo> visas = new ArrayList<EntityVisaBo>();
145
146    @Column(name = "ACTV_IND")
147    @Convert(converter = BooleanYNConverter.class)
148    private boolean active;
149
150    public static org.kuali.rice.kim.api.identity.entity.Entity to(EntityBo bo) {
151        if (bo == null) {
152            return null;
153        }
154        return Entity.Builder.create(bo).build();
155    }
156
157    public static EntityDefault toDefault(EntityBo bo) {
158        if (bo == null) {
159            return null;
160        }
161        return EntityDefault.Builder.create(bo).build();
162    }
163
164    public static EntityBo from(org.kuali.rice.kim.api.identity.entity.Entity immutable) {
165        return fromAndUpdate(immutable, null);
166    }
167
168    /**
169     * Creates a EntityBo business object from an immutable representation of a Entity.
170     *
171     * @param immutable an immutable Entity
172     * @return a EntityBo
173     */
174    public static EntityBo fromAndUpdate(Entity immutable, EntityBo toUpdate) {
175        String entityId;
176
177        if (immutable == null) {
178            return null;
179        }
180        EntityBo bo = toUpdate;
181        if (toUpdate == null) {
182            bo = new EntityBo();
183        }
184        bo.active = immutable.isActive();
185        bo.id = immutable.getId();
186        if (StringUtils.isBlank(bo.id)) {
187            DataFieldMaxValueIncrementer incrementer = MaxValueIncrementerFactory.getIncrementer(
188                    KimImplServiceLocator.getDataSource(), KimConstants.SequenceNames.KRIM_ENTITY_ID_S);
189            entityId = incrementer.nextStringValue();
190            bo.id = entityId;
191        } else {
192            entityId = bo.id;
193        }
194
195        bo.names = new ArrayList<EntityNameBo>();
196        if (CollectionUtils.isNotEmpty(immutable.getNames())) {
197            for (EntityName name : immutable.getNames()) {
198                bo.names.add(EntityNameBo.from(name));
199            }
200
201            for (EntityNameBo nameBo : bo.getNames()) {
202                if (StringUtils.isBlank(nameBo.getEntityId())) {
203                    nameBo.setEntityId(entityId);
204                }
205            }
206        }
207
208        bo.principals = new ArrayList<PrincipalBo>();
209        if (CollectionUtils.isNotEmpty(immutable.getPrincipals())) {
210            for (Principal principal : immutable.getPrincipals()) {
211                bo.principals.add(PrincipalBo.from(principal));
212            }
213
214            for (PrincipalBo principalBo : bo.getPrincipals()) {
215                if (StringUtils.isBlank(principalBo.getEntityId())) {
216                    principalBo.setEntityId(entityId);
217                }
218            }
219        }
220
221        bo.externalIdentifiers = new ArrayList<EntityExternalIdentifierBo>();
222        if (CollectionUtils.isNotEmpty(immutable.getExternalIdentifiers())) {
223            for (EntityExternalIdentifier externalId : immutable.getExternalIdentifiers()) {
224                bo.externalIdentifiers.add(EntityExternalIdentifierBo.from(externalId));
225            }
226
227            for (EntityExternalIdentifierBo EntityExternalIdentifierBo : bo.getExternalIdentifiers()) {
228                if (StringUtils.isBlank(EntityExternalIdentifierBo.getEntityId())) {
229                    EntityExternalIdentifierBo.setEntityId(entityId);
230                }
231            }
232        }
233
234        bo.affiliations = new ArrayList<EntityAffiliationBo>();
235        if (CollectionUtils.isNotEmpty(immutable.getAffiliations())) {
236            for (EntityAffiliation affiliation : immutable.getAffiliations()) {
237                bo.affiliations.add(EntityAffiliationBo.from(affiliation));
238            }
239
240            for (EntityAffiliationBo entityAffiliationBo : bo.getAffiliations()) {
241                if (StringUtils.isBlank(entityAffiliationBo.getEntityId())) {
242                    entityAffiliationBo.setEntityId(entityId);
243                }
244            }
245        }
246
247        bo.employmentInformation = new ArrayList<EntityEmploymentBo>();
248        if (CollectionUtils.isNotEmpty(immutable.getEmploymentInformation())) {
249            for (EntityEmployment employment : immutable.getEmploymentInformation()) {
250                bo.employmentInformation.add(EntityEmploymentBo.from(employment));
251            }
252            for (EntityEmploymentBo employmentBo : bo.getEmploymentInformation()) {
253                if (StringUtils.isBlank(employmentBo.getEntityId())) {
254                    employmentBo.setEntityId(entityId);
255                }
256
257                EntityAffiliationBo entityAffiliationBo = employmentBo.getEntityAffiliation();
258                if (entityAffiliationBo != null && StringUtils.isBlank(employmentBo.getEntityAffiliationId())) {
259                    DataFieldMaxValueIncrementer incrementer = MaxValueIncrementerFactory.getIncrementer(
260                            KimImplServiceLocator.getDataSource(), "KRIM_ENTITY_AFLTN_ID_S");
261                    String affiliationId = incrementer.nextStringValue();
262                    employmentBo.setEntityAffiliationId(affiliationId);
263                    entityAffiliationBo.setId(affiliationId);
264                    if (StringUtils.isBlank(entityAffiliationBo.getEntityId())) {
265                        entityAffiliationBo.setEntityId(entityId);
266                    }
267                }
268            }
269        }
270
271        bo.entityTypeContactInfos = new ArrayList<EntityTypeContactInfoBo>();
272        if (CollectionUtils.isNotEmpty(immutable.getEntityTypeContactInfos())) {
273            for (EntityTypeContactInfo entityType : immutable.getEntityTypeContactInfos()) {
274                bo.entityTypeContactInfos.add(EntityTypeContactInfoBo.from(entityType));
275            }
276        }
277
278        if (immutable.getPrivacyPreferences() != null) {
279            bo.privacyPreferences = EntityPrivacyPreferencesBo.from(immutable.getPrivacyPreferences());
280        }
281
282        if (immutable.getBioDemographics() != null) {
283            bo.bioDemographics = EntityBioDemographicsBo.from(immutable.getBioDemographics());
284        }
285
286        bo.citizenships = new ArrayList<EntityCitizenshipBo>();
287        if (CollectionUtils.isNotEmpty(immutable.getCitizenships())) {
288            for (EntityCitizenship citizenship : immutable.getCitizenships()) {
289                bo.citizenships.add(EntityCitizenshipBo.from(citizenship));
290            }
291
292            for (EntityCitizenshipBo citizenshipBo : bo.getCitizenships()) {
293                if (StringUtils.isBlank(citizenshipBo.getEntityId())) {
294                    citizenshipBo.setEntityId(entityId);
295                }
296            }
297        }
298
299        bo.ethnicities = new ArrayList<EntityEthnicityBo>();
300        if (CollectionUtils.isNotEmpty(immutable.getEthnicities())) {
301            for (EntityEthnicity ethnicity : immutable.getEthnicities()) {
302                bo.ethnicities.add(EntityEthnicityBo.from(ethnicity));
303            }
304        }
305
306        bo.residencies = new ArrayList<EntityResidencyBo>();
307        if (CollectionUtils.isNotEmpty(immutable.getResidencies())) {
308            for (EntityResidency residency : immutable.getResidencies()) {
309                bo.residencies.add(EntityResidencyBo.from(residency));
310            }
311
312            for (EntityResidencyBo entityResidencyBo : bo.getResidencies()) {
313                if (StringUtils.isBlank(entityResidencyBo.getEntityId())) {
314                    entityResidencyBo.setEntityId(entityId);
315                }
316            }
317        }
318
319        bo.visas = new ArrayList<EntityVisaBo>();
320        if (CollectionUtils.isNotEmpty(immutable.getVisas())) {
321            for (EntityVisa visa : immutable.getVisas()) {
322                bo.visas.add(EntityVisaBo.from(visa));
323            }
324
325            for (EntityVisaBo entityVisaBo : bo.getVisas()) {
326                if (StringUtils.isBlank(entityVisaBo.getEntityId())) {
327                    entityVisaBo.setEntityId(entityId);
328                }
329            }
330        }
331        bo.setVersionNumber(immutable.getVersionNumber());
332        bo.setObjectId(immutable.getObjectId());
333
334        return bo;
335    }
336
337    @Override
338    public EntityTypeContactInfoBo getEntityTypeContactInfoByTypeCode(String entityTypeCode) {
339        if (CollectionUtils.isEmpty(this.entityTypeContactInfos)) {
340            return null;
341        }
342        for (EntityTypeContactInfoBo entType : this.entityTypeContactInfos) {
343            if (entType.getEntityTypeCode().equals(entityTypeCode)) {
344                return entType;
345            }
346        }
347        return null;
348    }
349
350    @Override
351    public EntityEmploymentBo getPrimaryEmployment() {
352        if (CollectionUtils.isEmpty(this.employmentInformation)) {
353            return null;
354        }
355        for (EntityEmploymentBo employment : this.employmentInformation) {
356            if (employment.isPrimary() && employment.isActive()) {
357                return employment;
358            }
359        }
360        return null;
361    }
362
363    @Override
364    public EntityAffiliationBo getDefaultAffiliation() {
365        return EntityUtils.getDefaultItem(this.affiliations);
366    }
367
368    @Override
369    public EntityExternalIdentifierBo getEntityExternalIdentifier(String externalIdentifierTypeCode) {
370        if (CollectionUtils.isEmpty(this.externalIdentifiers)) {
371            return null;
372        }
373        for (EntityExternalIdentifierBo externalId : this.externalIdentifiers) {
374            if (externalId.getExternalIdentifierTypeCode().equals(externalIdentifierTypeCode)) {
375                return externalId;
376            }
377        }
378        return null;
379    }
380
381    @Override
382    public EntityNameContract getDefaultName() {
383        return EntityUtils.getDefaultItem(this.names);
384    }
385
386    @Override
387    public EntityPrivacyPreferencesBo getPrivacyPreferences() {
388        return this.privacyPreferences;
389    }
390
391    @Override
392    public EntityBioDemographicsBo getBioDemographics() {
393        return this.bioDemographics;
394    }
395
396    @Override
397    public String getId() {
398        return id;
399    }
400
401    public void setId(String id) {
402        this.id = id;
403    }
404
405    @Override
406    public List<EntityNameBo> getNames() {
407        return names;
408    }
409
410    public void setNames(List<EntityNameBo> names) {
411        this.names = names;
412    }
413
414    @Override
415    public List<PrincipalBo> getPrincipals() {
416        return principals;
417    }
418
419    public void setPrincipals(List<PrincipalBo> principals) {
420        this.principals = principals;
421    }
422
423    @Override
424    public List<EntityExternalIdentifierBo> getExternalIdentifiers() {
425        return externalIdentifiers;
426    }
427
428    public void setExternalIdentifiers(List<EntityExternalIdentifierBo> externalIdentifiers) {
429        this.externalIdentifiers = externalIdentifiers;
430    }
431
432    @Override
433    public List<EntityAffiliationBo> getAffiliations() {
434        return affiliations;
435    }
436
437    public void setAffiliations(List<EntityAffiliationBo> affiliations) {
438        this.affiliations = affiliations;
439    }
440
441    @Override
442    public List<EntityEmploymentBo> getEmploymentInformation() {
443        return employmentInformation;
444    }
445
446    public void setEmploymentInformation(List<EntityEmploymentBo> employmentInformation) {
447        this.employmentInformation = employmentInformation;
448    }
449
450    @Override
451    public List<EntityTypeContactInfoBo> getEntityTypeContactInfos() {
452        return entityTypeContactInfos;
453    }
454
455    public void setEntityTypeContactInfos(List<EntityTypeContactInfoBo> entityTypeContactInfos) {
456        this.entityTypeContactInfos = entityTypeContactInfos;
457    }
458
459    public void setPrivacyPreferences(EntityPrivacyPreferencesBo privacyPreferences) {
460        this.privacyPreferences = privacyPreferences;
461    }
462
463    public void setBioDemographics(EntityBioDemographicsBo bioDemographics) {
464        this.bioDemographics = bioDemographics;
465    }
466
467    @Override
468    public List<EntityCitizenshipBo> getCitizenships() {
469        return citizenships;
470    }
471
472    public void setCitizenships(List<EntityCitizenshipBo> citizenships) {
473        this.citizenships = citizenships;
474    }
475
476    @Override
477    public List<EntityEthnicityBo> getEthnicities() {
478        return ethnicities;
479    }
480
481    public void setEthnicities(List<EntityEthnicityBo> ethnicities) {
482        this.ethnicities = ethnicities;
483    }
484
485    @Override
486    public List<EntityResidencyBo> getResidencies() {
487        return residencies;
488    }
489
490    public void setResidencies(List<EntityResidencyBo> residencies) {
491        this.residencies = residencies;
492    }
493
494    @Override
495    public List<EntityVisaBo> getVisas() {
496        return visas;
497    }
498
499    public void setVisas(List<EntityVisaBo> visas) {
500        this.visas = visas;
501    }
502
503    public boolean getActive() {
504        return active;
505    }
506
507    @Override
508    public boolean isActive() {
509        return active;
510    }
511
512    public void setActive(boolean active) {
513        this.active = active;
514    }
515}