001/**
002 * Copyright 2005-2016 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;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.criteria.QueryByCriteria;
020import org.kuali.rice.core.api.criteria.QueryResults;
021import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
022import org.kuali.rice.core.api.exception.RiceIllegalStateException;
023import org.kuali.rice.kim.api.identity.CodedAttribute;
024import org.kuali.rice.kim.api.identity.IdentityService;
025import org.kuali.rice.kim.api.identity.address.EntityAddress;
026import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
027import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliationType;
028import org.kuali.rice.kim.api.identity.citizenship.EntityCitizenship;
029import org.kuali.rice.kim.api.identity.email.EntityEmail;
030import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
031import org.kuali.rice.kim.api.identity.entity.Entity;
032import org.kuali.rice.kim.api.identity.entity.EntityDefault;
033import org.kuali.rice.kim.api.identity.entity.EntityDefaultQueryResults;
034import org.kuali.rice.kim.api.identity.entity.EntityQueryResults;
035import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifier;
036import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierType;
037import org.kuali.rice.kim.api.identity.name.EntityName;
038import org.kuali.rice.kim.api.identity.name.EntityNameQueryResults;
039import org.kuali.rice.kim.api.identity.personal.EntityBioDemographics;
040import org.kuali.rice.kim.api.identity.personal.EntityEthnicity;
041import org.kuali.rice.kim.api.identity.phone.EntityPhone;
042import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
043import org.kuali.rice.kim.api.identity.principal.Principal;
044import org.kuali.rice.kim.api.identity.principal.PrincipalQueryResults;
045import org.kuali.rice.kim.api.identity.privacy.EntityPrivacyPreferences;
046import org.kuali.rice.kim.api.identity.residency.EntityResidency;
047import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
048import org.kuali.rice.kim.api.identity.visa.EntityVisa;
049import org.kuali.rice.kim.impl.KIMPropertyConstants;
050import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
051import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
052import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
053import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
054import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipBo;
055import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipStatusBo;
056import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
057import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
058import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
059import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
060import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
061import org.kuali.rice.kim.impl.identity.entity.EntityBo;
062import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierBo;
063import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierTypeBo;
064import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
065import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
066import org.kuali.rice.kim.impl.identity.personal.EntityBioDemographicsBo;
067import org.kuali.rice.kim.impl.identity.personal.EntityEthnicityBo;
068import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
069import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
070import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
071import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
072import org.kuali.rice.kim.impl.identity.residency.EntityResidencyBo;
073import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
074import org.kuali.rice.kim.impl.identity.visa.EntityVisaBo;
075import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
076import org.kuali.rice.krad.data.DataObjectService;
077
078import javax.jws.WebParam;
079import java.util.ArrayList;
080import java.util.Collections;
081import java.util.HashMap;
082import java.util.List;
083import java.util.Map;
084
085/**
086 * Base implementation of the identity (identity) service.  This version assumes the KimEntity
087 * and related data is located within the KIM database.
088 *
089 * @author Kuali Rice Team (rice.collab@kuali.org)
090 */
091
092public class IdentityServiceImpl implements IdentityService {
093
094    protected static final String UNAVAILABLE = "Unavailable";
095
096    protected DataObjectService dataObjectService;
097
098    protected IdentityServiceDao identityServiceDao;
099
100    @Override
101    public Entity getEntity(String entityId) throws RiceIllegalArgumentException {
102        incomingParamCheck(entityId, "entityId");
103
104        EntityBo entity = getEntityBo(entityId);
105        if (entity == null) {
106            return null;
107        }
108
109        return EntityBo.to(entity);
110    }
111
112    @Override
113    public Entity getEntityByPrincipalId(String principalId) throws RiceIllegalArgumentException {
114        incomingParamCheck(principalId, "principalId");
115
116        EntityBo entity = getEntityBoByPrincipalId(principalId);
117        if (entity == null) {
118            return null;
119        }
120
121        return EntityBo.to(entity);
122    }
123
124    @Override
125    public Entity getEntityByPrincipalName(String principalName) throws RiceIllegalArgumentException {
126        incomingParamCheck(principalName, "principalName");
127
128        EntityBo entity = getEntityBoByPrincipalName(principalName);
129        if (entity == null) {
130            return null;
131        }
132
133        return EntityBo.to(entity);
134    }
135
136    @Override
137    public Entity getEntityByEmployeeId(String employeeId) throws RiceIllegalArgumentException {
138        incomingParamCheck(employeeId, "employeeId");
139
140        EntityBo entity = getEntityBoByEmployeeId(employeeId);
141        if (entity == null) {
142            return null;
143        }
144
145        return EntityBo.to(entity);
146    }
147
148    @Override
149    public EntityDefault getEntityDefault(String entityId) throws RiceIllegalArgumentException {
150        incomingParamCheck(entityId, "entityId");
151
152        EntityBo entity = getEntityBo(entityId);
153        if (entity == null) {
154            return null;
155        }
156
157        return EntityBo.toDefault(entity);
158    }
159
160    @Override
161    public EntityDefault getEntityDefaultByPrincipalId(String principalId) throws RiceIllegalArgumentException {
162        incomingParamCheck(principalId, "principalId");
163
164        EntityBo entity = getEntityBoByPrincipalId(principalId);
165        if (entity == null) {
166            return null;
167        }
168
169        return EntityBo.toDefault(entity);
170    }
171
172    @Override
173    public EntityDefault getEntityDefaultByPrincipalName(String principalName) throws RiceIllegalArgumentException {
174        incomingParamCheck(principalName, "principalName");
175
176        EntityBo entity = getEntityBoByPrincipalName(principalName);
177        if (entity == null) {
178            return null;
179        }
180
181        return EntityBo.toDefault(entity);
182    }
183
184    @Override
185    public EntityDefault getEntityDefaultByEmployeeId(String employeeId) throws RiceIllegalArgumentException {
186        incomingParamCheck(employeeId, "employeeId");
187
188        EntityBo entity = getEntityBoByEmployeeId(employeeId);
189        if (entity == null) {
190            return null;
191        }
192
193        return EntityBo.toDefault(entity);
194    }
195
196    @Override
197    public Principal getPrincipalByPrincipalNameAndPassword(String principalName,
198            String password) throws RiceIllegalArgumentException {
199        incomingParamCheck(principalName, "principalName");
200        incomingParamCheck(password, "password");
201
202        Map<String, Object> criteria = new HashMap<String, Object>(3);
203        criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_NAME, principalName);
204        criteria.put(KIMPropertyConstants.Principal.PASSWORD, password);
205        criteria.put(KIMPropertyConstants.Principal.ACTIVE, Boolean.TRUE);
206        QueryResults<PrincipalBo> principals = dataObjectService.findMatching(PrincipalBo.class,
207                QueryByCriteria.Builder.andAttributes(criteria).build());
208
209        if (!principals.getResults().isEmpty()) {
210            return PrincipalBo.to(principals.getResults().get(0));
211        }
212
213        return null;
214    }
215
216    @Override
217    public Principal addPrincipalToEntity(
218            Principal principal) throws RiceIllegalArgumentException, RiceIllegalStateException {
219        incomingParamCheck(principal, "principal");
220
221        if (StringUtils.isBlank(principal.getEntityId()) || StringUtils.isBlank(principal.getPrincipalName())) {
222            throw new RiceIllegalStateException(
223                    "Principal's entityId and PrincipalName must be populated before creation");
224        } else {
225            if (getPrincipalByPrincipalName(principal.getPrincipalName()) != null) {
226                throw new RiceIllegalStateException("the Principal to create already exists: " + principal);
227            }
228        }
229        PrincipalBo bo = PrincipalBo.from(principal);
230
231        return PrincipalBo.to(dataObjectService.save(bo));
232    }
233
234    @Override
235    public Principal updatePrincipal(
236            Principal principal) throws RiceIllegalArgumentException, RiceIllegalStateException {
237        incomingParamCheck(principal, "principal");
238
239        PrincipalBo originalPrincipal = null;
240        if (StringUtils.isBlank(principal.getEntityId()) || StringUtils.isBlank(principal.getPrincipalName())) {
241            throw new RiceIllegalStateException(
242                    "Principal's entityId and PrincipalName must be populated before update");
243        } else {
244            originalPrincipal = getPrincipalBo(principal.getPrincipalId());
245            if (StringUtils.isBlank(principal.getPrincipalId()) || originalPrincipal == null) {
246                throw new RiceIllegalStateException("the Principal to update does not exist: " + principal);
247            }
248        }
249
250        PrincipalBo bo = PrincipalBo.from(principal);
251        //Password is not set on the principal DTO, so we need to make sure the value is kept from existing principal
252        bo.setPassword(originalPrincipal.getPassword());
253        PrincipalBo updatedPrincipal = dataObjectService.save(bo);
254        if (originalPrincipal.isActive() && !updatedPrincipal.isActive()) {
255            KimImplServiceLocator.getRoleInternalService().principalInactivated(updatedPrincipal.getPrincipalId());
256        }
257
258        return PrincipalBo.to(updatedPrincipal);
259    }
260
261    @Override
262    public Principal inactivatePrincipal(
263            String principalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
264        incomingParamCheck(principalId, "principalId");
265
266        Principal principal = getPrincipal(principalId);
267        if (principal == null) {
268            throw new RiceIllegalStateException("Principal with principalId: " + principalId + " does not exist");
269        }
270        PrincipalBo bo = PrincipalBo.from(principal);
271        bo.setActive(false);
272
273        return PrincipalBo.to(dataObjectService.save(bo));
274    }
275
276    @Override
277    public Principal inactivatePrincipalByName(
278            String principalName) throws RiceIllegalArgumentException, RiceIllegalStateException {
279        incomingParamCheck(principalName, "principalName");
280
281        Principal principal = getPrincipalByPrincipalName(principalName);
282        if (principal == null) {
283            throw new RiceIllegalStateException("Principal with principalName: " + principalName + " does not exist");
284        }
285        PrincipalBo bo = PrincipalBo.from(principal);
286        bo.setActive(false);
287
288        return PrincipalBo.to(dataObjectService.save(bo));
289    }
290
291    @Override
292    public EntityTypeContactInfo addEntityTypeContactInfoToEntity(
293            EntityTypeContactInfo entityTypeData) throws RiceIllegalArgumentException, RiceIllegalStateException {
294        incomingParamCheck(entityTypeData, "entityTypeData");
295
296        if (StringUtils.isBlank(entityTypeData.getEntityId())
297                || StringUtils.isBlank(entityTypeData.getEntityTypeCode())) {
298            throw new RiceIllegalStateException(
299                    "EntityTypeData's entityId and entityTypeCode must be populated before creation");
300        } else {
301            if (getEntityTypeDataBo(entityTypeData.getEntityId(), entityTypeData.getEntityTypeCode()) != null) {
302                throw new RiceIllegalStateException("the entityTypeData to create already exists: " + entityTypeData);
303            }
304        }
305        EntityTypeContactInfoBo bo = EntityTypeContactInfoBo.from(entityTypeData);
306
307        return EntityTypeContactInfoBo.to(dataObjectService.save(bo));
308    }
309
310    protected EntityTypeContactInfoBo getEntityTypeDataBo(String entityId, String entityTypeCode) {
311        Map<String, Object> criteria = new HashMap<String, Object>(3);
312        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
313        criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
314        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
315        List<EntityTypeContactInfoBo> results = dataObjectService.findMatching(EntityTypeContactInfoBo.class,
316                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
317        if (results.isEmpty()) {
318            return null;
319        }
320
321        return results.get(0);
322    }
323
324    @Override
325    public EntityTypeContactInfo updateEntityTypeContactInfo(
326            EntityTypeContactInfo entityTypeContactInfo) throws RiceIllegalArgumentException, RiceIllegalStateException {
327        incomingParamCheck(entityTypeContactInfo, "entityTypeContactInfo");
328
329        if (StringUtils.isBlank(entityTypeContactInfo.getEntityId())
330                || StringUtils.isBlank(entityTypeContactInfo.getEntityTypeCode())) {
331            throw new RiceIllegalStateException(
332                    "EntityTypeData's entityId and entityTypeCode must be populated before update");
333        } else {
334            if (getEntityTypeDataBo(entityTypeContactInfo.getEntityId(), entityTypeContactInfo.getEntityTypeCode())
335                    == null) {
336                throw new RiceIllegalStateException(
337                        "the entityTypeData to update does not exist: " + entityTypeContactInfo);
338            }
339        }
340        EntityTypeContactInfoBo bo = EntityTypeContactInfoBo.from(entityTypeContactInfo);
341
342        return EntityTypeContactInfoBo.to(dataObjectService.save(bo));
343    }
344
345    @Override
346    public EntityTypeContactInfo inactivateEntityTypeContactInfo(String entityId,
347            String entityTypeCode) throws RiceIllegalArgumentException, RiceIllegalStateException {
348        incomingParamCheck(entityId, "entityId");
349        incomingParamCheck(entityTypeCode, "entityTypeCode");
350
351        EntityTypeContactInfoBo bo = getEntityTypeDataBo(entityId, entityTypeCode);
352        if (bo == null) {
353            throw new RiceIllegalStateException("EntityTypeData with entityId: "
354                    + entityId + " entityTypeCode: " + entityTypeCode + " does not exist");
355        }
356        bo.setActive(false);
357
358        return EntityTypeContactInfoBo.to(dataObjectService.save(bo));
359    }
360
361    protected EntityAddressBo getEntityAddressBo(String entityId, String entityTypeCode, String addressTypeCode) {
362        Map<String, Object> criteria = new HashMap<String, Object>(4);
363        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
364        criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
365        criteria.put("addressTypeCode", addressTypeCode);
366        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
367        List<EntityAddressBo> results = dataObjectService.findMatching(EntityAddressBo.class,
368                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
369        if (results.isEmpty()) {
370            return null;
371        }
372
373        return results.get(0);
374    }
375
376    protected EntityAddressBo getEntityAddressBo(String addressId) {
377        return dataObjectService.find(EntityAddressBo.class, addressId);
378    }
379
380    @Override
381    public EntityAddress addAddressToEntity(
382            EntityAddress address) throws RiceIllegalArgumentException, RiceIllegalStateException {
383        incomingParamCheck(address, "address");
384
385        if (StringUtils.isBlank(address.getEntityId()) || StringUtils.isBlank(address.getEntityTypeCode())) {
386            throw new RiceIllegalStateException(
387                    "Address's entityId and entityTypeCode must be populated before creation");
388        } else {
389            if (address.getAddressType() == null) {
390                throw new RiceIllegalStateException("Address's type must be populated before creation");
391            }
392            if (getEntityAddressBo(address.getEntityId(), address.getEntityTypeCode(),
393                    address.getAddressType().getCode()) != null) {
394                throw new RiceIllegalStateException("the address to create already exists: " + address);
395            }
396        }
397        EntityAddressBo bo = EntityAddressBo.from(address);
398
399        return EntityAddressBo.to(dataObjectService.save(bo));
400    }
401
402    @Override
403    public EntityAddress updateAddress(
404            EntityAddress address) throws RiceIllegalArgumentException, RiceIllegalStateException {
405        incomingParamCheck(address, "address");
406
407        if (StringUtils.isBlank(address.getEntityId()) || StringUtils.isBlank(address.getEntityTypeCode())) {
408            throw new RiceIllegalStateException(
409                    "Address's entityId and entityTypeCode must be populated before creation");
410        } else {
411            if (address.getAddressType() == null) {
412                throw new RiceIllegalStateException("Address's type must be populated before creation");
413            }
414            if (StringUtils.isEmpty(address.getId()) || getEntityAddressBo(address.getEntityId(),
415                    address.getEntityTypeCode(), address.getAddressType().getCode()) == null) {
416                throw new RiceIllegalStateException("the address to update does not exists: " + address);
417            }
418        }
419        EntityAddressBo bo = EntityAddressBo.from(address);
420
421        return EntityAddressBo.to(dataObjectService.save(bo));
422    }
423
424    @Override
425    public EntityAddress inactivateAddress(
426            String addressId) throws RiceIllegalArgumentException, RiceIllegalStateException {
427        incomingParamCheck(addressId, "addressId");
428
429        EntityAddressBo bo = getEntityAddressBo(addressId);
430        if (bo == null) {
431            throw new RiceIllegalStateException("Address with addressId: " + addressId + " does not exist");
432        }
433        bo.setActive(false);
434
435        return EntityAddressBo.to(dataObjectService.save(bo));
436    }
437
438    protected EntityEmailBo getEntityEmailBo(String entityId, String entityTypeCode, String emailTypeCode) {
439        Map<String, Object> criteria = new HashMap<String, Object>(4);
440        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
441        criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
442        criteria.put("emailTypeCode", emailTypeCode);
443        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
444        List<EntityEmailBo> results = dataObjectService.findMatching(EntityEmailBo.class,
445                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
446        if (results.isEmpty()) {
447            return null;
448        }
449
450        return results.get(0);
451    }
452
453    protected EntityEmailBo getEntityEmailBo(String emailId) {
454        return dataObjectService.find(EntityEmailBo.class, emailId);
455    }
456
457    @Override
458    public EntityEmail addEmailToEntity(
459            EntityEmail email) throws RiceIllegalArgumentException, RiceIllegalStateException {
460        incomingParamCheck(email, "email");
461
462        if (StringUtils.isBlank(email.getEntityId()) || StringUtils.isBlank(email.getEntityTypeCode())) {
463            throw new RiceIllegalStateException(
464                    "Email's entityId and entityTypeCode must be populated before creation");
465        } else {
466            if (email.getEmailType() == null) {
467                throw new RiceIllegalStateException("Email's type must be populated before creation");
468            }
469            if (getEntityEmailBo(email.getEntityId(), email.getEntityTypeCode(), email.getEmailType().getCode())
470                    != null) {
471                throw new RiceIllegalStateException("the email to create already exists: " + email);
472            }
473        }
474        EntityEmailBo bo = EntityEmailBo.from(email);
475
476        return EntityEmailBo.to(dataObjectService.save(bo));
477    }
478
479    @Override
480    public EntityEmail updateEmail(EntityEmail email) throws RiceIllegalArgumentException, RiceIllegalStateException {
481        incomingParamCheck(email, "email");
482
483        if (StringUtils.isBlank(email.getEntityId()) || StringUtils.isBlank(email.getEntityTypeCode())) {
484            throw new RiceIllegalStateException(
485                    "Email's entityId and entityTypeCode must be populated before creation");
486        } else {
487            if (email.getEmailType() == null) {
488                throw new RiceIllegalStateException("Email's type must be populated before creation");
489            }
490            if (StringUtils.isEmpty(email.getId()) || getEntityEmailBo(email.getEntityId(), email.getEntityTypeCode(),
491                    email.getEmailType().getCode()) == null) {
492                throw new RiceIllegalStateException("the email to update does not exists: " + email);
493            }
494        }
495        EntityEmailBo bo = EntityEmailBo.from(email);
496
497        return EntityEmailBo.to(dataObjectService.save(bo));
498    }
499
500    @Override
501    public EntityEmail inactivateEmail(String emailId) throws RiceIllegalArgumentException, RiceIllegalStateException {
502        incomingParamCheck(emailId, "emailId");
503
504        EntityEmailBo bo = getEntityEmailBo(emailId);
505        if (bo == null) {
506            throw new RiceIllegalStateException("Email with emailId: " + emailId + " does not exist");
507        }
508        bo.setActive(false);
509
510        return EntityEmailBo.to(dataObjectService.save(bo));
511    }
512
513    protected EntityPhoneBo getEntityPhoneBo(String entityId, String entityTypeCode, String phoneTypeCode) {
514        Map<String, Object> criteria = new HashMap<String, Object>(4);
515        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
516        criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
517        criteria.put("phoneTypeCode", phoneTypeCode);
518        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
519        List<EntityPhoneBo> results = dataObjectService.findMatching(EntityPhoneBo.class,
520                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
521        if (results.isEmpty()) {
522            return null;
523        }
524
525        return results.get(0);
526    }
527
528    protected EntityPhoneBo getEntityPhoneBo(String phoneId) {
529        return dataObjectService.find(EntityPhoneBo.class, phoneId);
530    }
531
532    @Override
533    public EntityPhone addPhoneToEntity(
534            EntityPhone phone) throws RiceIllegalArgumentException, RiceIllegalStateException {
535        incomingParamCheck(phone, "phone");
536
537        if (StringUtils.isBlank(phone.getEntityId()) || StringUtils.isBlank(phone.getEntityTypeCode())) {
538            throw new RiceIllegalStateException(
539                    "Phone's entityId and entityTypeCode must be populated before creation");
540        } else {
541            if (phone.getPhoneType() == null) {
542                throw new RiceIllegalStateException("Phone's type must be populated before creation");
543            }
544            if (getEntityPhoneBo(phone.getEntityId(), phone.getEntityTypeCode(), phone.getPhoneType().getCode())
545                    != null) {
546                throw new RiceIllegalStateException("the phone to create already exists: " + phone);
547            }
548        }
549        EntityPhoneBo bo = EntityPhoneBo.from(phone);
550
551        return EntityPhoneBo.to(dataObjectService.save(bo));
552    }
553
554    @Override
555    public EntityPhone updatePhone(EntityPhone phone) throws RiceIllegalArgumentException, RiceIllegalStateException {
556        incomingParamCheck(phone, "phone");
557
558        if (StringUtils.isBlank(phone.getEntityId()) || StringUtils.isBlank(phone.getEntityTypeCode())) {
559            throw new RiceIllegalStateException(
560                    "Phone's entityId and entityTypeCode must be populated before creation");
561        } else {
562            if (phone.getPhoneType() == null) {
563                throw new RiceIllegalStateException("Phone's type must be populated before creation");
564            }
565            if (StringUtils.isEmpty(phone.getId()) || getEntityPhoneBo(phone.getEntityId(), phone.getEntityTypeCode(),
566                    phone.getPhoneType().getCode()) == null) {
567                throw new RiceIllegalStateException("the phone to update does not exists: " + phone);
568            }
569        }
570        EntityPhoneBo bo = EntityPhoneBo.from(phone);
571
572        return EntityPhoneBo.to(dataObjectService.save(bo));
573    }
574
575    @Override
576    public EntityPhone inactivatePhone(String phoneId) throws RiceIllegalArgumentException, RiceIllegalStateException {
577        incomingParamCheck(phoneId, "phoneId");
578
579        EntityPhoneBo bo = getEntityPhoneBo(phoneId);
580        if (bo == null) {
581            throw new RiceIllegalStateException("Phone with phoneId: " + phoneId + " does not exist");
582        }
583        bo.setActive(false);
584
585        return EntityPhoneBo.to(dataObjectService.save(bo));
586    }
587
588    protected EntityExternalIdentifierBo getEntityExternalIdentifierBo(String entityId,
589            String externalIdentifierTypeCode) {
590        Map<String, Object> criteria = new HashMap<String, Object>(4);
591        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
592        criteria.put("externalIdentifierTypeCode", externalIdentifierTypeCode);
593        List<EntityExternalIdentifierBo> results = dataObjectService.findMatching(EntityExternalIdentifierBo.class,
594                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
595        if (results.isEmpty()) {
596            return null;
597        }
598
599        return results.get(0);
600    }
601
602    @Override
603    public EntityExternalIdentifier addExternalIdentifierToEntity(
604            EntityExternalIdentifier externalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
605        incomingParamCheck(externalId, "externalId");
606
607        if (StringUtils.isBlank(externalId.getEntityId())
608                || StringUtils.isBlank(externalId.getExternalIdentifierTypeCode())) {
609            throw new RiceIllegalStateException(
610                    "EntityExternalIdentifier's entityId and entityTypeCode must be populated before creation");
611        } else {
612            if (getEntityExternalIdentifierBo(externalId.getEntityId(), externalId.getExternalIdentifierTypeCode())
613                    != null) {
614                throw new RiceIllegalStateException(
615                        "the EntityExternalIdentifier to create already exists: " + externalId);
616            }
617        }
618        EntityExternalIdentifierBo bo = EntityExternalIdentifierBo.from(externalId);
619
620        return EntityExternalIdentifierBo.to(dataObjectService.save(bo));
621    }
622
623    @Override
624    public EntityExternalIdentifier updateExternalIdentifier(
625            EntityExternalIdentifier externalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
626        incomingParamCheck(externalId, "externalId");
627
628        if (StringUtils.isBlank(externalId.getEntityId())
629                || StringUtils.isBlank(externalId.getExternalIdentifierTypeCode())) {
630            throw new RiceIllegalStateException(
631                    "EntityExternalIdentifier's entityId and externalIdentifierTypeCode must be populated before creation");
632        } else {
633            if (StringUtils.isEmpty(externalId.getId()) || getEntityExternalIdentifierBo(externalId.getEntityId(),
634                    externalId.getExternalIdentifierTypeCode()) == null) {
635                throw new RiceIllegalStateException("the external identifier to update does not exist: " + externalId);
636            }
637        }
638        EntityExternalIdentifierBo bo = EntityExternalIdentifierBo.from(externalId);
639
640        return EntityExternalIdentifierBo.to(dataObjectService.save(bo));
641    }
642
643    protected EntityAffiliationBo getEntityAffiliationBo(String id) {
644        return dataObjectService.find(EntityAffiliationBo.class, id);
645    }
646
647    @Override
648    public EntityAffiliation addAffiliationToEntity(
649            EntityAffiliation affiliation) throws RiceIllegalArgumentException, RiceIllegalStateException {
650        incomingParamCheck(affiliation, "affiliation");
651
652        if (StringUtils.isBlank(affiliation.getEntityId())) {
653            throw new RiceIllegalStateException("Affiliation's entityId must be populated before creation");
654        } else {
655            if (affiliation.getAffiliationType() == null) {
656                throw new RiceIllegalStateException("EntityAffiliation's type must be populated before creation");
657            }
658            if (getEntityAffiliationBo(affiliation.getId()) != null) {
659                throw new RiceIllegalStateException("the EntityAffiliation to create already exists: " + affiliation);
660            }
661        }
662        EntityAffiliationBo bo = EntityAffiliationBo.from(affiliation);
663
664        return EntityAffiliationBo.to(dataObjectService.save(bo));
665    }
666
667    @Override
668    public EntityAffiliation updateAffiliation(
669            EntityAffiliation affiliation) throws RiceIllegalArgumentException, RiceIllegalStateException {
670        incomingParamCheck(affiliation, "affiliation");
671
672        if (StringUtils.isBlank(affiliation.getEntityId())) {
673            throw new RiceIllegalStateException("Affiliation's entityId must be populated before creation");
674        } else {
675            if (affiliation.getAffiliationType() == null) {
676                throw new RiceIllegalStateException("EntityAffiliation's type must be populated before creation");
677            }
678            if (StringUtils.isEmpty(affiliation.getId()) || getEntityAffiliationBo(affiliation.getId()) == null) {
679                throw new RiceIllegalStateException("the EntityAffiliation to update already exists: " + affiliation);
680            }
681        }
682        EntityAffiliationBo bo = EntityAffiliationBo.from(affiliation);
683
684        return EntityAffiliationBo.to(dataObjectService.save(bo));
685    }
686
687    @Override
688    public EntityAffiliation inactivateAffiliation(
689            String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
690        incomingParamCheck(id, "id");
691
692        EntityAffiliationBo bo = getEntityAffiliationBo(id);
693        if (bo == null) {
694            throw new RiceIllegalStateException("EntityAffiliation with id: " + id + " does not exist");
695        }
696        bo.setActive(false);
697
698        return EntityAffiliationBo.to(dataObjectService.save(bo));
699    }
700
701    @Override
702    public EntityQueryResults findEntities(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
703        incomingParamCheck(queryByCriteria, "queryByCriteria");
704
705        QueryResults<EntityBo> results = dataObjectService.findMatching(EntityBo.class, queryByCriteria);
706
707        EntityQueryResults.Builder builder = EntityQueryResults.Builder.create();
708        builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
709        builder.setTotalRowCount(results.getTotalRowCount());
710
711        final List<Entity.Builder> ims = new ArrayList<Entity.Builder>();
712        for (EntityBo bo : results.getResults()) {
713            ims.add(Entity.Builder.create(bo));
714        }
715
716        builder.setResults(ims);
717
718        return builder.build();
719    }
720
721    @Override
722    public EntityDefaultQueryResults findEntityDefaults(
723            QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
724        incomingParamCheck(queryByCriteria, "queryByCriteria");
725
726        QueryResults<EntityBo> results = dataObjectService.findMatching(EntityBo.class, queryByCriteria);
727
728        EntityDefaultQueryResults.Builder builder = EntityDefaultQueryResults.Builder.create();
729        builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
730        builder.setTotalRowCount(results.getTotalRowCount());
731
732        final List<EntityDefault.Builder> ims = new ArrayList<EntityDefault.Builder>();
733        for (EntityBo bo : results.getResults()) {
734            ims.add(EntityDefault.Builder.create(bo));
735        }
736
737        builder.setResults(ims);
738
739        return builder.build();
740    }
741
742    protected EntityNameQueryResults findNames(QueryByCriteria queryByCriteria) {
743        incomingParamCheck(queryByCriteria, "queryByCriteria");
744
745        QueryResults<EntityNameBo> results = dataObjectService.findMatching(EntityNameBo.class, queryByCriteria);
746
747        EntityNameQueryResults.Builder builder = EntityNameQueryResults.Builder.create();
748        builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
749        builder.setTotalRowCount(results.getTotalRowCount());
750
751        final List<EntityName.Builder> ims = new ArrayList<EntityName.Builder>();
752        for (EntityNameBo bo : results.getResults()) {
753            ims.add(EntityName.Builder.create(bo));
754        }
755
756        builder.setResults(ims);
757
758        return builder.build();
759    }
760
761    @Override
762    public EntityPrivacyPreferences getEntityPrivacyPreferences(String entityId) throws RiceIllegalArgumentException {
763        incomingParamCheck(entityId, "entityId");
764
765        return EntityPrivacyPreferencesBo.to(dataObjectService.find(EntityPrivacyPreferencesBo.class, entityId));
766    }
767
768    @Override
769    public Principal getPrincipal(String principalId) throws RiceIllegalArgumentException {
770        incomingParamCheck(principalId, "principalId");
771
772        PrincipalBo principal = getPrincipalBo(principalId);
773        if (principal == null) {
774            return null;
775        }
776        if (StringUtils.isBlank(principal.getPrincipalName())) {
777            principal.setPrincipalName(UNAVAILABLE);
778        }
779
780        return PrincipalBo.to(principal);
781    }
782
783    @Override
784    public List<Principal> getPrincipals(List<String> principalIds) {
785        List<Principal> ret = new ArrayList<Principal>();
786        for (String p : principalIds) {
787            Principal principalInfo = getPrincipal(p);
788
789            if (principalInfo != null) {
790                ret.add(principalInfo);
791            }
792        }
793
794        return ret;
795    }
796
797    protected PrincipalBo getPrincipalBo(String principalId) {
798        return dataObjectService.find(PrincipalBo.class, principalId);
799    }
800
801    protected EntityBo getEntityBo(String entityId) {
802        return dataObjectService.find(EntityBo.class, entityId);
803    }
804
805    @Override
806    public Principal getPrincipalByPrincipalName(String principalName) throws RiceIllegalArgumentException {
807        incomingParamCheck(principalName, "principalName");
808
809        return PrincipalBo.to(getPrincipalBoByPrincipalName(principalName));
810    }
811
812    protected PrincipalBo getPrincipalBoByPrincipalName(String principalName) throws RiceIllegalArgumentException {
813        QueryResults<PrincipalBo> principals = dataObjectService.findMatching(PrincipalBo.class,
814                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Principal.PRINCIPAL_NAME,
815                        principalName.toLowerCase()).build());
816        if (!principals.getResults().isEmpty() && principals.getResults().size() == 1) {
817            return principals.getResults().get(0);
818        }
819
820        return null;
821    }
822
823    @Override
824    public List<Principal> getPrincipalsByEntityId(String entityId) throws RiceIllegalArgumentException {
825        incomingParamCheck(entityId, "entityId");
826
827        List<Principal> principals = new ArrayList<Principal>();
828        Map<String, Object> criteria = new HashMap<String, Object>(1);
829        criteria.put(KIMPropertyConstants.Person.ENTITY_ID, entityId);
830        QueryResults<PrincipalBo> principalBos = dataObjectService.findMatching(PrincipalBo.class,
831                QueryByCriteria.Builder.andAttributes(criteria).build());
832
833        if (!principalBos.getResults().isEmpty()) {
834
835            for (PrincipalBo principalBo : principalBos.getResults()) {
836                Principal principal = PrincipalBo.to(principalBo);
837                principals.add(principal);
838            }
839            return principals;
840        }
841
842        return null;
843    }
844
845    @Override
846    public List<Principal> getPrincipalsByEmployeeId(String employeeId) throws RiceIllegalArgumentException {
847        incomingParamCheck(employeeId, "employeeId");
848
849        List<Principal> principals = new ArrayList<Principal>();
850        Map<String, Object> criteria = new HashMap<String, Object>(1);
851        criteria.put(KIMPropertyConstants.Person.EMPLOYEE_ID, employeeId);
852        QueryResults<EntityEmploymentBo> entityEmploymentBos = dataObjectService.findMatching(EntityEmploymentBo.class,
853                QueryByCriteria.Builder.andAttributes(criteria).build());
854
855        if (!entityEmploymentBos.getResults().isEmpty()) {
856            List<String> entityIds = new ArrayList<String>();
857            for (EntityEmploymentBo entityEmploymentBo : entityEmploymentBos.getResults()) {
858                String entityId = entityEmploymentBo.getEntityId();
859                if (StringUtils.isNotBlank(entityId) && !entityIds.contains(entityId)) {
860                    entityIds.add(entityId);
861                }
862            }
863
864            for (String entityId : entityIds) {
865                List<Principal> principalsForEntity = getPrincipalsByEntityId(entityId);
866                if (principalsForEntity != null && !principalsForEntity.isEmpty()) {
867                    principals.addAll(principalsForEntity);
868                }
869            }
870
871            if (!principals.isEmpty()) {
872                return principals;
873            }
874        }
875
876        return null;
877    }
878
879    /**
880     * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByPrincipalName(java.lang.String)
881     */
882    protected EntityBo getEntityBoByPrincipalName(String principalName) {
883        if (StringUtils.isBlank(principalName)) {
884            return null;
885        }
886
887        return getEntityByKeyValue("principals." + KIMPropertyConstants.Principal.PRINCIPAL_NAME,
888                principalName.toLowerCase());
889    }
890
891    /**
892     * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByPrincipalId(java.lang.String)
893     */
894    protected EntityBo getEntityBoByPrincipalId(String principalId) {
895        if (StringUtils.isBlank(principalId)) {
896            return null;
897        }
898
899        return getEntityByKeyValue("principals." + KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
900    }
901
902    /**
903     * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByEmployeeId(java.lang.String)
904     */
905    protected EntityBo getEntityBoByEmployeeId(String employeeId) {
906        if (StringUtils.isBlank(employeeId)) {
907            return null;
908        }
909
910        return getEntityByKeyValue("employmentInformation." + KIMPropertyConstants.Person.EMPLOYEE_ID, employeeId);
911    }
912
913    /**
914     * Generic helper method for performing a lookup through the business object service.
915     */
916    protected EntityBo getEntityByKeyValue(String key, String value) {
917        List<EntityBo> entities = dataObjectService.findMatching(EntityBo.class, QueryByCriteria.Builder.forAttribute(
918                key, value).build()).getResults();
919        if (entities.size() >= 1) {
920            return entities.get(0);
921        }
922
923        return null;
924    }
925
926    @Override
927    public CodedAttribute getAddressType(String code) throws RiceIllegalArgumentException {
928        incomingParamCheck(code, "code");
929
930        EntityAddressTypeBo impl = dataObjectService.find(EntityAddressTypeBo.class, code);
931        if (impl == null) {
932            return null;
933        }
934
935        return EntityAddressTypeBo.to(impl);
936    }
937
938    @Override
939    public List<CodedAttribute> findAllAddressTypes() {
940        List<EntityAddressTypeBo> bos = dataObjectService.findMatching(EntityAddressTypeBo.class,
941                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
942                .getResults();
943        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
944        for (EntityAddressTypeBo bo : bos) {
945            codedAttributes.add(EntityAddressTypeBo.to(bo));
946        }
947
948        return Collections.unmodifiableList(codedAttributes);
949    }
950
951    @Override
952    public EntityAffiliationType getAffiliationType(String code) throws RiceIllegalArgumentException {
953        incomingParamCheck(code, "code");
954
955        EntityAffiliationTypeBo impl = dataObjectService.find(EntityAffiliationTypeBo.class, code);
956        if (impl == null) {
957            return null;
958        }
959
960        return EntityAffiliationTypeBo.to(impl);
961    }
962
963    @Override
964    public List<EntityAffiliationType> findAllAffiliationTypes() {
965        List<EntityAffiliationTypeBo> bos = dataObjectService.findMatching(EntityAffiliationTypeBo.class,
966                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
967                .getResults();
968        List<EntityAffiliationType> codedAttributes = new ArrayList<EntityAffiliationType>();
969        for (EntityAffiliationTypeBo bo : bos) {
970            codedAttributes.add(EntityAffiliationTypeBo.to(bo));
971        }
972
973        return Collections.unmodifiableList(codedAttributes);
974    }
975
976    @Override
977    public CodedAttribute getCitizenshipStatus(String code) throws RiceIllegalArgumentException {
978        incomingParamCheck(code, "code");
979
980        EntityCitizenshipStatusBo impl = dataObjectService.find(EntityCitizenshipStatusBo.class, code);
981        if (impl == null) {
982            return null;
983        }
984
985        return EntityCitizenshipStatusBo.to(impl);
986    }
987
988    @Override
989    public List<CodedAttribute> findAllCitizenshipStatuses() {
990        List<EntityCitizenshipStatusBo> bos = dataObjectService.findMatching(EntityCitizenshipStatusBo.class,
991                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
992                .getResults();
993
994        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
995        for (EntityCitizenshipStatusBo bo : bos) {
996            codedAttributes.add(EntityCitizenshipStatusBo.to(bo));
997        }
998
999        return Collections.unmodifiableList(codedAttributes);
1000    }
1001
1002    @Override
1003    public CodedAttribute getEmailType(String code) throws RiceIllegalArgumentException {
1004        incomingParamCheck(code, "code");
1005
1006        EntityEmailTypeBo impl = dataObjectService.find(EntityEmailTypeBo.class, code);
1007        if (impl == null) {
1008            return null;
1009        }
1010
1011        return EntityEmailTypeBo.to(impl);
1012    }
1013
1014    @Override
1015    public List<CodedAttribute> findAllEmailTypes() {
1016        List<EntityEmailTypeBo> bos = dataObjectService.findMatching(EntityEmailTypeBo.class,
1017                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1018                .getResults();
1019
1020        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1021        for (EntityEmailTypeBo bo : bos) {
1022            codedAttributes.add(EntityEmailTypeBo.to(bo));
1023        }
1024
1025        return Collections.unmodifiableList(codedAttributes);
1026    }
1027
1028    @Override
1029    public PrincipalQueryResults findPrincipals(
1030            @WebParam(name = "query") QueryByCriteria query) throws RiceIllegalArgumentException {
1031        incomingParamCheck(query, "query");
1032
1033        QueryResults<PrincipalBo> results = dataObjectService.findMatching(PrincipalBo.class, query);
1034
1035        PrincipalQueryResults.Builder builder = PrincipalQueryResults.Builder.create();
1036        builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
1037        builder.setTotalRowCount(results.getTotalRowCount());
1038
1039        final List<Principal.Builder> ims = new ArrayList<Principal.Builder>();
1040        for (PrincipalBo bo : results.getResults()) {
1041            ims.add(Principal.Builder.create(bo));
1042        }
1043
1044        builder.setResults(ims);
1045
1046        return builder.build();
1047    }
1048
1049    @Override
1050    public CodedAttribute getEmploymentStatus(String code) throws RiceIllegalArgumentException {
1051        incomingParamCheck(code, "code");
1052        EntityEmploymentStatusBo impl = dataObjectService.find(EntityEmploymentStatusBo.class, code);
1053        if (impl == null) {
1054            return null;
1055        }
1056
1057        return EntityEmploymentStatusBo.to(impl);
1058    }
1059
1060    @Override
1061    public List<CodedAttribute> findAllEmploymentStatuses() {
1062        List<EntityEmploymentStatusBo> bos = dataObjectService.findMatching(EntityEmploymentStatusBo.class,
1063                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1064                .getResults();
1065
1066        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1067        for (EntityEmploymentStatusBo bo : bos) {
1068            codedAttributes.add(EntityEmploymentStatusBo.to(bo));
1069        }
1070
1071        return Collections.unmodifiableList(codedAttributes);
1072    }
1073
1074    @Override
1075    public CodedAttribute getEmploymentType(String code) throws RiceIllegalArgumentException {
1076        incomingParamCheck(code, "code");
1077        EntityEmploymentTypeBo impl = dataObjectService.find(EntityEmploymentTypeBo.class, code);
1078        if (impl == null) {
1079            return null;
1080        }
1081
1082        return EntityEmploymentTypeBo.to(impl);
1083    }
1084
1085    @Override
1086    public List<CodedAttribute> findAllEmploymentTypes() {
1087        List<EntityEmploymentTypeBo> bos = dataObjectService.findMatching(EntityEmploymentTypeBo.class,
1088                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1089                .getResults();
1090
1091        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1092        for (EntityEmploymentTypeBo bo : bos) {
1093            codedAttributes.add(EntityEmploymentTypeBo.to(bo));
1094        }
1095
1096        return Collections.unmodifiableList(codedAttributes);
1097    }
1098
1099    @Override
1100    public CodedAttribute getNameType(String code) throws RiceIllegalArgumentException {
1101        incomingParamCheck(code, "code");
1102
1103        EntityNameTypeBo impl = dataObjectService.find(EntityNameTypeBo.class, code);
1104        if (impl == null) {
1105            return null;
1106        }
1107
1108        return EntityNameTypeBo.to(impl);
1109    }
1110
1111    @Override
1112    public List<CodedAttribute> findAllNameTypes() {
1113        List<EntityNameTypeBo> bos = dataObjectService.findMatching(EntityNameTypeBo.class,
1114                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1115                .getResults();
1116
1117        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1118        for (EntityNameTypeBo bo : bos) {
1119            codedAttributes.add(EntityNameTypeBo.to(bo));
1120        }
1121
1122        return Collections.unmodifiableList(codedAttributes);
1123    }
1124
1125    @Override
1126    public CodedAttribute getEntityType(String code) throws RiceIllegalArgumentException {
1127        incomingParamCheck(code, "code");
1128
1129        EntityTypeBo impl = dataObjectService.find(EntityTypeBo.class, code);
1130        if (impl == null) {
1131            return null;
1132        }
1133
1134        return EntityTypeBo.to(impl);
1135    }
1136
1137    @Override
1138    public List<CodedAttribute> findAllEntityTypes() {
1139        List<EntityTypeBo> bos = dataObjectService.findMatching(EntityTypeBo.class,
1140                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1141                .getResults();
1142
1143        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1144        for (EntityTypeBo bo : bos) {
1145            codedAttributes.add(EntityTypeBo.to(bo));
1146        }
1147
1148        return Collections.unmodifiableList(codedAttributes);
1149    }
1150
1151    @Override
1152    public EntityExternalIdentifierType getExternalIdentifierType(String code) throws RiceIllegalArgumentException {
1153        incomingParamCheck(code, "code");
1154
1155        EntityExternalIdentifierTypeBo impl = dataObjectService.find(EntityExternalIdentifierTypeBo.class, code);
1156        if (impl == null) {
1157            return null;
1158        }
1159
1160        return EntityExternalIdentifierTypeBo.to(impl);
1161    }
1162
1163    @Override
1164    public List<EntityExternalIdentifierType> findAllExternalIdendtifierTypes() {
1165        List<EntityExternalIdentifierTypeBo> bos = dataObjectService.findMatching(EntityExternalIdentifierTypeBo.class,
1166                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1167                .getResults();
1168
1169        List<EntityExternalIdentifierType> codedAttributes = new ArrayList<EntityExternalIdentifierType>();
1170        for (EntityExternalIdentifierTypeBo bo : bos) {
1171            codedAttributes.add(EntityExternalIdentifierTypeBo.to(bo));
1172        }
1173
1174        return Collections.unmodifiableList(codedAttributes);
1175    }
1176
1177    @Override
1178    public CodedAttribute getPhoneType(String code) throws RiceIllegalArgumentException {
1179        incomingParamCheck(code, "code");
1180
1181        EntityPhoneTypeBo impl = dataObjectService.find(EntityPhoneTypeBo.class, code);
1182        if (impl == null) {
1183            return null;
1184        }
1185
1186        return EntityPhoneTypeBo.to(impl);
1187    }
1188
1189    @Override
1190    public List<CodedAttribute> findAllPhoneTypes() {
1191        List<EntityPhoneTypeBo> bos = dataObjectService.findMatching(EntityPhoneTypeBo.class,
1192                QueryByCriteria.Builder.forAttribute(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE).build())
1193                .getResults();
1194
1195        List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1196        for (EntityPhoneTypeBo bo : bos) {
1197            codedAttributes.add(EntityPhoneTypeBo.to(bo));
1198        }
1199
1200        return Collections.unmodifiableList(codedAttributes);
1201    }
1202
1203    @Override
1204    public Entity createEntity(Entity entity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1205        incomingParamCheck(entity, "entity");
1206
1207        if (StringUtils.isNotBlank(entity.getId()) && getEntity(entity.getId()) != null) {
1208            throw new RiceIllegalStateException("the Entity to create already exists: " + entity);
1209        }
1210
1211        EntityBo bo = EntityBo.from(entity);
1212
1213        return EntityBo.to(dataObjectService.save(bo));
1214    }
1215
1216    @Override
1217    public Entity updateEntity(Entity entity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1218        incomingParamCheck(entity, "entity");
1219        EntityBo oldBo = null;
1220        Map<String, String> passwdMap = new HashMap<String, String>();
1221
1222        if (StringUtils.isBlank(entity.getId())) {
1223            throw new RiceIllegalStateException("the Entity does not exist: " + entity);
1224        } else {
1225            oldBo = getEntityBo(entity.getId());
1226            if (oldBo == null) {
1227                throw new RiceIllegalStateException("the Entity does not exist: " + entity);
1228            }
1229        }
1230
1231        for (PrincipalBo principalBo : oldBo.getPrincipals()) {
1232            passwdMap.put(principalBo.getPrincipalId(), principalBo.getPassword());
1233        }
1234
1235        EntityBo bo = EntityBo.from(entity);
1236        for (PrincipalBo principal : bo.getPrincipals()) {
1237            principal.setPassword(passwdMap.get(principal.getPrincipalId()));
1238        }
1239
1240        return EntityBo.to(dataObjectService.save(bo));
1241    }
1242
1243    @Override
1244    public Entity inactivateEntity(String entityId) throws RiceIllegalArgumentException, RiceIllegalStateException {
1245        incomingParamCheck(entityId, "entityId");
1246
1247        EntityBo entity = getEntityBo(entityId);
1248        if (entity == null) {
1249            throw new RiceIllegalStateException("an Entity does not exist for entityId: " + entityId);
1250        }
1251
1252        entity.setActive(false);
1253
1254        return EntityBo.to(dataObjectService.save(entity));
1255    }
1256
1257    @Override
1258    public EntityPrivacyPreferences addPrivacyPreferencesToEntity(
1259            EntityPrivacyPreferences privacyPreferences) throws RiceIllegalArgumentException, RiceIllegalStateException {
1260        incomingParamCheck(privacyPreferences, "privacyPreferences");
1261
1262        if (StringUtils.isBlank(privacyPreferences.getEntityId())) {
1263            throw new RiceIllegalStateException("PrivacyPreferences' entityId must be populated before creation");
1264        } else {
1265            if (getEntityPrivacyPreferences(privacyPreferences.getEntityId()) != null) {
1266                throw new RiceIllegalStateException(
1267                        "the PrivacyPreferences to create already exists: " + privacyPreferences);
1268            }
1269        }
1270        EntityPrivacyPreferencesBo bo = EntityPrivacyPreferencesBo.from(privacyPreferences);
1271
1272        return EntityPrivacyPreferencesBo.to(dataObjectService.save(bo));
1273    }
1274
1275    @Override
1276    public EntityPrivacyPreferences updatePrivacyPreferences(
1277            EntityPrivacyPreferences privacyPreferences) throws RiceIllegalArgumentException, RiceIllegalStateException {
1278        incomingParamCheck(privacyPreferences, "privacyPreferences");
1279
1280        if (StringUtils.isBlank(privacyPreferences.getEntityId())) {
1281            throw new RiceIllegalStateException("PrivacyPreferences' entityId must be populated before update");
1282        } else {
1283            if (getEntityPrivacyPreferences(privacyPreferences.getEntityId()) == null) {
1284                throw new RiceIllegalStateException(
1285                        "the PrivacyPreferences to update does not exist: " + privacyPreferences);
1286            }
1287        }
1288        EntityPrivacyPreferencesBo bo = EntityPrivacyPreferencesBo.from(privacyPreferences);
1289
1290        return EntityPrivacyPreferencesBo.to(dataObjectService.save(bo));
1291    }
1292
1293    protected EntityCitizenshipBo getEntityCitizenshipBo(String entityId, String citizenshipStatusCode) {
1294        if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(citizenshipStatusCode)) {
1295            return null;
1296        }
1297        Map<String, Object> criteria = new HashMap<String, Object>(4);
1298        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1299        criteria.put("statusCode", citizenshipStatusCode);
1300        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1301        List<EntityCitizenshipBo> results = dataObjectService.findMatching(EntityCitizenshipBo.class,
1302                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1303        if (results.isEmpty()) {
1304            return null;
1305        }
1306
1307        return results.get(0);
1308
1309    }
1310
1311    protected EntityCitizenshipBo getEntityCitizenshipBo(String id) {
1312        if (StringUtils.isEmpty(id)) {
1313            return null;
1314        }
1315        Map<String, Object> criteria = new HashMap<String, Object>();
1316        criteria.put(KIMPropertyConstants.Entity.ID, id);
1317        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1318        List<EntityCitizenshipBo> results = dataObjectService.findMatching(EntityCitizenshipBo.class,
1319                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1320        if (results.isEmpty()) {
1321            return null;
1322        }
1323
1324        return results.get(0);
1325    }
1326
1327    @Override
1328    public EntityCitizenship addCitizenshipToEntity(
1329            EntityCitizenship citizenship) throws RiceIllegalArgumentException, RiceIllegalStateException {
1330        incomingParamCheck(citizenship, "citizenship");
1331
1332        if (StringUtils.isBlank(citizenship.getEntityId())) {
1333            throw new RiceIllegalStateException("Citizenship's entityId must be populated before creation");
1334        } else {
1335            if (citizenship.getStatus() == null) {
1336                throw new RiceIllegalStateException("Citizenship's status must be populated before creation");
1337            }
1338            if (getEntityCitizenshipBo(citizenship.getEntityId(), citizenship.getStatus().getCode()) != null) {
1339                throw new RiceIllegalStateException("the EntityCitizenship to create already exists: " + citizenship);
1340            }
1341        }
1342        EntityCitizenshipBo bo = EntityCitizenshipBo.from(citizenship);
1343
1344        return EntityCitizenshipBo.to(dataObjectService.save(bo));
1345    }
1346
1347    @Override
1348    public EntityCitizenship updateCitizenship(
1349            EntityCitizenship citizenship) throws RiceIllegalArgumentException, RiceIllegalStateException {
1350        incomingParamCheck(citizenship, "citizenship");
1351
1352        if (StringUtils.isBlank(citizenship.getEntityId())) {
1353            throw new RiceIllegalStateException("Email's entityId must be populated before creation");
1354        } else {
1355            if (citizenship.getStatus() == null) {
1356                throw new RiceIllegalStateException("Citizenship's status must be populated before creation");
1357            }
1358            if (getEntityCitizenshipBo(citizenship.getEntityId(), citizenship.getStatus().getCode()) == null) {
1359                throw new RiceIllegalStateException("the EntityCitizenship to update does not exist: " + citizenship);
1360            }
1361        }
1362        EntityCitizenshipBo bo = EntityCitizenshipBo.from(citizenship);
1363
1364        return EntityCitizenshipBo.to(dataObjectService.save(bo));
1365    }
1366
1367    @Override
1368    public EntityCitizenship inactivateCitizenship(
1369            String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1370        incomingParamCheck(id, "id");
1371
1372        EntityCitizenshipBo bo = getEntityCitizenshipBo(id);
1373        if (bo == null) {
1374            throw new RiceIllegalStateException("the EntityCitizenship with id: " + id + " does not exist");
1375        }
1376        bo.setActive(false);
1377
1378        return EntityCitizenshipBo.to(dataObjectService.save(bo));
1379    }
1380
1381    protected EntityEthnicityBo getEntityEthnicityBo(String ethnicityId) {
1382        if (StringUtils.isEmpty(ethnicityId)) {
1383            return null;
1384        }
1385
1386        return dataObjectService.find(EntityEthnicityBo.class, ethnicityId);
1387    }
1388
1389    @Override
1390    public EntityEthnicity addEthnicityToEntity(EntityEthnicity ethnicity) throws RiceIllegalArgumentException {
1391        incomingParamCheck(ethnicity, "ethnicity");
1392
1393        if (StringUtils.isBlank(ethnicity.getEntityId())) {
1394            throw new RiceIllegalStateException("Ethnicity's entityId must be populated before creation");
1395        } else {
1396            if (StringUtils.isNotEmpty(ethnicity.getId()) && getEntityEthnicityBo(ethnicity.getId()) != null) {
1397                throw new RiceIllegalStateException("the EntityEthnicity to create already exists: " + ethnicity);
1398            }
1399        }
1400        EntityEthnicityBo bo = EntityEthnicityBo.from(ethnicity);
1401
1402        return EntityEthnicityBo.to(dataObjectService.save(bo));
1403    }
1404
1405    @Override
1406    public EntityEthnicity updateEthnicity(
1407            EntityEthnicity ethnicity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1408        incomingParamCheck(ethnicity, "ethnicity");
1409
1410        if (StringUtils.isBlank(ethnicity.getEntityId())) {
1411            throw new RiceIllegalStateException("Ethnicity's entityId must be populated before creation");
1412        } else {
1413            if (StringUtils.isEmpty(ethnicity.getId()) || getEntityEthnicityBo(ethnicity.getId()) == null) {
1414                throw new RiceIllegalStateException("the EntityEthnicity to update does not exist: " + ethnicity);
1415            }
1416        }
1417        EntityEthnicityBo bo = EntityEthnicityBo.from(ethnicity);
1418
1419        return EntityEthnicityBo.to(dataObjectService.save(bo));
1420    }
1421
1422    protected EntityResidencyBo getEntityResidencyBo(String residencyId) {
1423        if (StringUtils.isEmpty(residencyId)) {
1424            return null;
1425        }
1426
1427        return dataObjectService.find(EntityResidencyBo.class, residencyId);
1428    }
1429
1430    @Override
1431    public EntityResidency addResidencyToEntity(
1432            EntityResidency residency) throws RiceIllegalArgumentException, RiceIllegalStateException {
1433        incomingParamCheck(residency, "residency");
1434
1435        if (StringUtils.isBlank(residency.getEntityId())) {
1436            throw new RiceIllegalStateException("Residency's entityId must be populated before creation");
1437        } else {
1438            if (StringUtils.isNotEmpty(residency.getId()) && getEntityResidencyBo(residency.getId()) != null) {
1439                throw new RiceIllegalStateException("the EntityResidency to create already exists: " + residency);
1440            }
1441        }
1442        EntityResidencyBo bo = EntityResidencyBo.from(residency);
1443
1444        return EntityResidencyBo.to(dataObjectService.save(bo));
1445    }
1446
1447    @Override
1448    public EntityResidency updateResidency(
1449            EntityResidency residency) throws RiceIllegalArgumentException, RiceIllegalStateException {
1450        incomingParamCheck(residency, "residency");
1451
1452        if (StringUtils.isBlank(residency.getEntityId())) {
1453            throw new RiceIllegalStateException("Residency's entityId must be populated before creation");
1454        } else {
1455            if (StringUtils.isEmpty(residency.getId()) || getEntityResidencyBo(residency.getId()) == null) {
1456                throw new RiceIllegalStateException("the EntityResidency to update does not exist: " + residency);
1457            }
1458        }
1459        EntityResidencyBo bo = EntityResidencyBo.from(residency);
1460
1461        return EntityResidencyBo.to(dataObjectService.save(bo));
1462    }
1463
1464    protected EntityVisaBo getEntityVisaBo(String visaId) {
1465        if (StringUtils.isEmpty(visaId)) {
1466            return null;
1467        }
1468
1469        return dataObjectService.find(EntityVisaBo.class, visaId);
1470    }
1471
1472    @Override
1473    public EntityVisa addVisaToEntity(EntityVisa visa) throws RiceIllegalArgumentException, RiceIllegalStateException {
1474        incomingParamCheck(visa, "visa");
1475
1476        if (StringUtils.isBlank(visa.getEntityId())) {
1477            throw new RiceIllegalStateException("Visa's entityId must be populated before creation");
1478        } else {
1479            if (StringUtils.isNotEmpty(visa.getId()) && getEntityVisaBo(visa.getId()) != null) {
1480                throw new RiceIllegalStateException("the EntityVisa to create already exists: " + visa);
1481            }
1482        }
1483        EntityVisaBo bo = EntityVisaBo.from(visa);
1484
1485        return EntityVisaBo.to(dataObjectService.save(bo));
1486    }
1487
1488    @Override
1489    public EntityVisa updateVisa(EntityVisa visa) throws RiceIllegalArgumentException, RiceIllegalStateException {
1490        incomingParamCheck(visa, "visa");
1491
1492        if (StringUtils.isBlank(visa.getEntityId())) {
1493            throw new RiceIllegalStateException("Visa's entityId must be populated before creation");
1494        } else {
1495            if (StringUtils.isEmpty(visa.getId()) || getEntityVisaBo(visa.getId()) == null) {
1496                throw new RiceIllegalStateException("the EntityVisa to update does not exist: " + visa);
1497            }
1498        }
1499        EntityVisaBo bo = EntityVisaBo.from(visa);
1500
1501        return EntityVisaBo.to(dataObjectService.save(bo));
1502    }
1503
1504    protected EntityNameBo getEntityNameBo(String entityId, String nameTypeCode) {
1505        if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(nameTypeCode)) {
1506            return null;
1507        }
1508        Map<String, Object> criteria = new HashMap<String, Object>();
1509        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1510        criteria.put("nameCode", nameTypeCode);
1511        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1512        List<EntityNameBo> results = dataObjectService.findMatching(EntityNameBo.class,
1513                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1514        if (results.isEmpty()) {
1515            return null;
1516        }
1517
1518        return results.get(0);
1519    }
1520
1521    protected EntityNameBo getEntityNameBo(String id) {
1522        if (StringUtils.isEmpty(id)) {
1523            return null;
1524        }
1525        Map<String, Object> criteria = new HashMap<String, Object>();
1526        criteria.put(KIMPropertyConstants.Entity.ID, id);
1527        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1528        List<EntityNameBo> results = dataObjectService.findMatching(EntityNameBo.class,
1529                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1530        if (results.isEmpty()) {
1531            return null;
1532        }
1533
1534        return results.get(0);
1535    }
1536
1537    @Override
1538    public EntityNamePrincipalName getDefaultNamesForPrincipalId(String principalId) {
1539        PrincipalBo principal = dataObjectService.find(PrincipalBo.class, principalId);
1540
1541        if (null != principal) {
1542            EntityNamePrincipalName.Builder nameBuilder = EntityNamePrincipalName.Builder.create();
1543            nameBuilder.setPrincipalName(principal.getPrincipalName());
1544
1545            Map<String, Object> criteria = new HashMap<String, Object>();
1546            criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, principal.getEntityId());
1547            criteria.put("defaultValue", Boolean.TRUE);
1548            criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1549            List<EntityNameBo> results = dataObjectService.findMatching(EntityNameBo.class,
1550                    QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1551            if (results.isEmpty()) {
1552                // to make this simple for now, assume if there is no default name that this is a system entity we are dealing with here
1553                EntityName.Builder defaultNameBuilder = EntityName.Builder.create();
1554                defaultNameBuilder.setLastName(principal.getPrincipalName().toUpperCase());
1555                nameBuilder.setDefaultName(defaultNameBuilder);
1556            } else {
1557                nameBuilder.setDefaultName(EntityName.Builder.create(results.get(0)));
1558            }
1559            EntityNamePrincipalName entityNamePrincipalName = nameBuilder.build();
1560
1561            return entityNamePrincipalName;
1562        }
1563
1564        return null;
1565    }
1566
1567    @Override
1568    public Map<String, EntityNamePrincipalName> getDefaultNamesForPrincipalIds(List<String> principalIds) {
1569        return getIdentityServiceDao().getDefaultNamesByPrincipalIds(principalIds);
1570    }
1571
1572    /**
1573     * {@inheritDoc}
1574     */
1575    @Override
1576    public EntityPrivacyPreferences getPrivacyPreferencesForPrincipalId(String principalId) {
1577        PrincipalBo principal = dataObjectService.find(PrincipalBo.class, principalId);
1578
1579        if (principal != null) {
1580            EntityPrivacyPreferencesBo privacyPrefs =
1581                    dataObjectService.find(EntityPrivacyPreferencesBo.class, principal.getEntityId());
1582
1583            if (privacyPrefs != null) {
1584                return EntityPrivacyPreferencesBo.to(privacyPrefs);
1585            }
1586
1587            return EntityPrivacyPreferences.Builder.create(principal.getEntityId()).build();
1588        }
1589
1590        return null;
1591    }
1592
1593    @Override
1594    public EntityName addNameToEntity(EntityName name) throws RiceIllegalArgumentException, RiceIllegalStateException {
1595        incomingParamCheck(name, "name");
1596
1597        if (StringUtils.isBlank(name.getEntityId())) {
1598            throw new RiceIllegalStateException("Name's entityId must be populated before creation");
1599        } else {
1600            if (name.getNameType() == null) {
1601                throw new RiceIllegalStateException("EntityName's type must be populated before creation");
1602            }
1603            if (getEntityNameBo(name.getEntityId(), name.getNameType().getCode()) != null) {
1604                throw new RiceIllegalStateException("the EntityName to create already exists: " + name);
1605            }
1606        }
1607        EntityNameBo bo = EntityNameBo.from(name);
1608
1609        return EntityNameBo.to(dataObjectService.save(bo));
1610    }
1611
1612    @Override
1613    public EntityName updateName(EntityName name) throws RiceIllegalArgumentException, RiceIllegalStateException {
1614        incomingParamCheck(name, "name");
1615
1616        if (StringUtils.isBlank(name.getEntityId())) {
1617            throw new RiceIllegalStateException("Name's entityId must be populated before update");
1618        } else {
1619            if (name.getNameType() == null) {
1620                throw new RiceIllegalStateException("EntityName's type must be populated before update");
1621            }
1622            if (StringUtils.isEmpty(name.getId()) || getEntityNameBo(name.getId()) == null) {
1623                throw new RiceIllegalStateException("the EntityName to update does not exist: " + name);
1624            }
1625        }
1626        EntityNameBo bo = EntityNameBo.from(name);
1627
1628        return EntityNameBo.to(dataObjectService.save(bo));
1629    }
1630
1631    @Override
1632    public EntityName inactivateName(String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1633        incomingParamCheck(id, "id");
1634
1635        EntityNameBo bo = getEntityNameBo(id);
1636        if (bo == null) {
1637            throw new RiceIllegalStateException("the EntityName to inactivate does not exist");
1638        }
1639
1640        bo.setActive(false);
1641
1642        return EntityNameBo.to(dataObjectService.save(bo));
1643    }
1644
1645    protected EntityEmploymentBo getEntityEmploymentBo(String entityId, String employmentTypeCode,
1646            String employmentStatusCode, String employmentAffiliationId) {
1647        if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(employmentTypeCode) || StringUtils.isEmpty(
1648                employmentStatusCode) || StringUtils.isEmpty(employmentAffiliationId)) {
1649            return null;
1650        }
1651        Map<String, Object> criteria = new HashMap<String, Object>();
1652        criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1653        criteria.put("employeeTypeCode", employmentTypeCode);
1654        criteria.put("employeeStatusCode", employmentStatusCode);
1655        criteria.put("entityAffiliationId", employmentAffiliationId);
1656        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1657        List<EntityEmploymentBo> results = dataObjectService.findMatching(EntityEmploymentBo.class,
1658                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1659
1660        if (results.isEmpty()) {
1661            return null;
1662        }
1663
1664        return results.get(0);
1665    }
1666
1667    protected EntityEmploymentBo getEntityEmploymentBo(String id) {
1668        if (StringUtils.isEmpty(id)) {
1669            return null;
1670        }
1671        Map<String, Object> criteria = new HashMap<String, Object>();
1672        criteria.put(KIMPropertyConstants.Entity.ID, id);
1673        criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1674        List<EntityEmploymentBo> results = dataObjectService.findMatching(EntityEmploymentBo.class,
1675                QueryByCriteria.Builder.andAttributes(criteria).build()).getResults();
1676        if (results.isEmpty()) {
1677            return null;
1678        }
1679
1680        return results.get(0);
1681    }
1682
1683    @Override
1684    public EntityEmployment addEmploymentToEntity(
1685            EntityEmployment employment) throws RiceIllegalArgumentException, RiceIllegalStateException {
1686        incomingParamCheck(employment, "employment");
1687
1688        if (StringUtils.isBlank(employment.getEntityId())) {
1689            throw new RiceIllegalStateException("EntityEmployment's entityId must be populated before creation");
1690        } else {
1691            if (employment.getEmployeeType() == null
1692                    || employment.getEmployeeStatus() == null
1693                    || employment.getEntityAffiliation() == null) {
1694                throw new RiceIllegalStateException(
1695                        "EntityEmployment's status, type, and entity affiliation must be populated before creation");
1696            }
1697            if (getEntityEmploymentBo(employment.getEntityId(), employment.getEmployeeType().getCode(),
1698                    employment.getEmployeeStatus().getCode(), employment.getEntityAffiliation().getId()) != null) {
1699                throw new RiceIllegalStateException("the EntityEmployment to create already exists: " + employment);
1700            }
1701        }
1702        EntityEmploymentBo bo = EntityEmploymentBo.from(employment);
1703
1704        return EntityEmploymentBo.to(dataObjectService.save(bo));
1705    }
1706
1707    @Override
1708    public EntityEmployment updateEmployment(
1709            EntityEmployment employment) throws RiceIllegalArgumentException, RiceIllegalStateException {
1710        incomingParamCheck(employment, "employment");
1711
1712        if (StringUtils.isBlank(employment.getEntityId())) {
1713            throw new RiceIllegalStateException("EntityEmployment's entityId must be populated before update");
1714        } else {
1715            if (employment.getEmployeeType() == null
1716                    || employment.getEmployeeStatus() == null
1717                    || employment.getEntityAffiliation() == null) {
1718                throw new RiceIllegalStateException(
1719                        "EntityEmployment's status, type, and entity affiliation must be populated before update");
1720            }
1721            if (getEntityEmploymentBo(employment.getEntityId(), employment.getEmployeeType().getCode(),
1722                    employment.getEmployeeStatus().getCode(), employment.getEntityAffiliation().getId()) == null) {
1723                throw new RiceIllegalStateException("the EntityEmployment to udpate does not exist: " + employment);
1724            }
1725        }
1726        EntityEmploymentBo bo = EntityEmploymentBo.from(employment);
1727
1728        return EntityEmploymentBo.to(dataObjectService.save(bo));
1729    }
1730
1731    @Override
1732    public EntityEmployment inactivateEmployment(
1733            String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1734        incomingParamCheck(id, "id");
1735
1736        EntityEmploymentBo bo = getEntityEmploymentBo(id);
1737        if (bo == null) {
1738            throw new RiceIllegalStateException("the EntityEmployment to inactivate does not exist");
1739        }
1740        bo.setActive(false);
1741
1742        return EntityEmploymentBo.to(dataObjectService.save(bo));
1743    }
1744
1745    protected EntityBioDemographicsBo getEntityBioDemographicsBo(String entityId) {
1746        if (StringUtils.isEmpty(entityId)) {
1747            return null;
1748        }
1749
1750        return dataObjectService.find(EntityBioDemographicsBo.class, entityId);
1751    }
1752
1753    @Override
1754    public EntityBioDemographics addBioDemographicsToEntity(
1755            EntityBioDemographics bioDemographics) throws RiceIllegalArgumentException, RiceIllegalStateException {
1756        incomingParamCheck(bioDemographics, "bioDemographics");
1757
1758        if (StringUtils.isBlank(bioDemographics.getEntityId())) {
1759            throw new RiceIllegalStateException("BioDemographics' entityId must be populated before creation");
1760        } else {
1761            if (getEntityBioDemographicsBo(bioDemographics.getEntityId()) != null) {
1762                throw new RiceIllegalStateException(
1763                        "the EntityBioDemographics to create already exists: " + bioDemographics);
1764            }
1765        }
1766        EntityBioDemographicsBo bo = EntityBioDemographicsBo.from(bioDemographics);
1767
1768        return EntityBioDemographicsBo.to(dataObjectService.save(bo));
1769    }
1770
1771    @Override
1772    public EntityBioDemographics updateBioDemographics(
1773            EntityBioDemographics bioDemographics) throws RiceIllegalArgumentException, RiceIllegalStateException {
1774        incomingParamCheck(bioDemographics, "bioDemographics");
1775
1776        if (getEntityBioDemographicsBo(bioDemographics.getEntityId()) == null) {
1777            throw new RiceIllegalStateException(
1778                    "the EntityBioDemographics to update does not exist: " + bioDemographics);
1779        }
1780        EntityBioDemographicsBo bo = EntityBioDemographicsBo.from(bioDemographics);
1781
1782        return EntityBioDemographicsBo.to(dataObjectService.save(bo));
1783    }
1784
1785    protected void incomingParamCheck(Object object, String name) {
1786        if (object == null) {
1787            throw new RiceIllegalArgumentException(name + " was null");
1788        } else if (object instanceof String && StringUtils.isBlank((String) object)) {
1789            throw new RiceIllegalArgumentException(name + " was blank");
1790        }
1791    }
1792
1793    public void setDataObjectService(DataObjectService dataObjectService) {
1794        this.dataObjectService = dataObjectService;
1795    }
1796
1797    public IdentityServiceDao getIdentityServiceDao() {
1798        return identityServiceDao;
1799    }
1800
1801    public void setIdentityServiceDao(IdentityServiceDao identityServiceDao) {
1802        this.identityServiceDao = identityServiceDao;
1803    }
1804}