View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.impl.identity;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.criteria.CriteriaLookupService;
20  import org.kuali.rice.core.api.criteria.GenericQueryResults;
21  import org.kuali.rice.core.api.criteria.QueryByCriteria;
22  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
23  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
24  import org.kuali.rice.kim.api.identity.CodedAttribute;
25  import org.kuali.rice.kim.api.identity.IdentityService;
26  import org.kuali.rice.kim.api.identity.address.EntityAddress;
27  import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
28  import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliationType;
29  import org.kuali.rice.kim.api.identity.citizenship.EntityCitizenship;
30  import org.kuali.rice.kim.api.identity.email.EntityEmail;
31  import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
32  import org.kuali.rice.kim.api.identity.entity.Entity;
33  import org.kuali.rice.kim.api.identity.entity.EntityDefault;
34  import org.kuali.rice.kim.api.identity.entity.EntityDefaultQueryResults;
35  import org.kuali.rice.kim.api.identity.entity.EntityQueryResults;
36  import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifier;
37  import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierType;
38  import org.kuali.rice.kim.api.identity.name.EntityName;
39  import org.kuali.rice.kim.api.identity.name.EntityNameQueryResults;
40  import org.kuali.rice.kim.api.identity.personal.EntityBioDemographics;
41  import org.kuali.rice.kim.api.identity.personal.EntityEthnicity;
42  import org.kuali.rice.kim.api.identity.phone.EntityPhone;
43  import org.kuali.rice.kim.api.identity.principal.Principal;
44  import org.kuali.rice.kim.api.identity.principal.PrincipalQueryResults;
45  import org.kuali.rice.kim.api.identity.privacy.EntityPrivacyPreferences;
46  import org.kuali.rice.kim.api.identity.residency.EntityResidency;
47  import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
48  import org.kuali.rice.kim.api.identity.visa.EntityVisa;
49  import org.kuali.rice.kim.impl.KIMPropertyConstants;
50  import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
51  import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
52  import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
53  import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
54  import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipBo;
55  import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipStatusBo;
56  import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
57  import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
58  import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
59  import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
60  import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
61  import org.kuali.rice.kim.impl.identity.entity.EntityBo;
62  import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierBo;
63  import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierTypeBo;
64  import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
65  import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
66  import org.kuali.rice.kim.impl.identity.personal.EntityBioDemographicsBo;
67  import org.kuali.rice.kim.impl.identity.personal.EntityEthnicityBo;
68  import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
69  import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
70  import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
71  import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
72  import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
73  import org.kuali.rice.kim.impl.identity.residency.EntityResidencyBo;
74  import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
75  import org.kuali.rice.kim.impl.identity.visa.EntityVisaBo;
76  import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
77  import org.kuali.rice.krad.service.BusinessObjectService;
78  
79  import javax.jws.WebParam;
80  import java.util.ArrayList;
81  import java.util.Collection;
82  import java.util.Collections;
83  import java.util.HashMap;
84  import java.util.List;
85  import java.util.Map;
86  
87  /**
88   * Base implementation of the identity (identity) service.  This version assumes the KimEntity
89   * and related data is located within the KIM database. 
90   * 
91   * @author Kuali Rice Team (rice.collab@kuali.org)
92   */
93  
94  public class IdentityServiceImpl implements IdentityService {
95  
96      private CriteriaLookupService criteriaLookupService;
97  	private BusinessObjectService businessObjectService;
98  
99      private static final String UNAVAILABLE = "Unavailable";
100 
101     @Override
102 	public Entity getEntity(String entityId) throws RiceIllegalArgumentException {
103         incomingParamCheck(entityId, "entityId");
104 
105 		EntityBo entity = getEntityBo( entityId );
106 		if ( entity == null ) {
107 			return null;
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 		return EntityBo.to(entity);
121 	}
122 	
123     @Override
124 	public Entity getEntityByPrincipalName(String principalName) throws RiceIllegalArgumentException{
125         incomingParamCheck(principalName, "principalName");
126 
127 		EntityBo entity = getEntityBoByPrincipalName(principalName);
128 		if ( entity == null ) {
129 			return null;
130 		}
131 		return EntityBo.to(entity);
132 	}
133     
134     @Override
135 	public Entity getEntityByEmployeeId(String employeeId) throws RiceIllegalArgumentException{
136         incomingParamCheck(employeeId, "employeeId");
137 
138 		EntityBo entity = getEntityBoByEmployeeId(employeeId);
139 		if ( entity == null ) {
140 			return null;
141 		}
142 		return EntityBo.to(entity);
143 	}
144 	
145     @Override
146 	public EntityDefault getEntityDefault(String entityId) throws RiceIllegalArgumentException {
147         incomingParamCheck(entityId, "entityId");
148 
149 		EntityBo entity = getEntityBo( entityId );
150 		if ( entity == null ) {
151 			return null;
152 		}
153 		return EntityBo.toDefault( entity );
154 	}
155 	
156     @Override
157 	public EntityDefault getEntityDefaultByPrincipalId(String principalId) throws RiceIllegalArgumentException {
158         incomingParamCheck(principalId, "principalId");
159 
160 		EntityBo entity = getEntityBoByPrincipalId(principalId);
161 		if ( entity == null ) {
162 			return null;
163 		}
164 		return EntityBo.toDefault(entity);
165 	}
166 	
167     @Override
168 	public EntityDefault getEntityDefaultByPrincipalName(String principalName) throws RiceIllegalArgumentException {
169         incomingParamCheck(principalName, "principalName");
170 
171 		EntityBo entity = getEntityBoByPrincipalName(principalName);
172 		if ( entity == null ) {
173 			return null;
174 		}
175 		return EntityBo.toDefault(entity);
176 	}
177 	
178     @Override
179     public EntityDefault getEntityDefaultByEmployeeId(String employeeId) throws RiceIllegalArgumentException {
180         incomingParamCheck(employeeId, "employeeId");
181 
182         EntityBo entity = getEntityBoByEmployeeId(employeeId);
183         if ( entity == null ) {
184             return null;
185         }
186         return EntityBo.toDefault(entity);
187     }
188     
189     @Override
190 	public Principal getPrincipalByPrincipalNameAndPassword(String principalName, String password) throws RiceIllegalArgumentException {
191         incomingParamCheck(principalName, "principalName");
192         incomingParamCheck(password, "password");
193 
194 		Map<String,Object> criteria = new HashMap<String,Object>(3);
195         criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_NAME, principalName);
196         criteria.put(KIMPropertyConstants.Principal.PASSWORD, password);
197         criteria.put(KIMPropertyConstants.Principal.ACTIVE, Boolean.TRUE);
198         Collection<PrincipalBo> principals = businessObjectService.findMatching(PrincipalBo.class, criteria);
199 
200         if (!principals.isEmpty()) {
201             return PrincipalBo.to(principals.iterator().next());
202         }
203         return null;
204 	}
205 
206     @Override
207     public Principal addPrincipalToEntity(Principal principal) throws RiceIllegalArgumentException, RiceIllegalStateException {
208         incomingParamCheck(principal, "principal");
209 
210         if (StringUtils.isEmpty(principal.getEntityId()) || StringUtils.isBlank(principal.getEntityId())
211                 || StringUtils.isEmpty(principal.getPrincipalName()) || StringUtils.isBlank(principal.getPrincipalName())) {
212             throw new RiceIllegalStateException("Principal's entityId and PrincipalName must be populated before creation");
213         }  else {
214             if (getPrincipalByPrincipalName(principal.getPrincipalName()) != null) {
215                 throw new RiceIllegalStateException("the Principal to create already exists: " + principal);
216             }
217         }
218         PrincipalBo bo = PrincipalBo.from(principal);
219         return PrincipalBo.to(businessObjectService.save(bo));
220     }
221 
222     @Override
223     public Principal updatePrincipal(Principal principal) throws RiceIllegalArgumentException, RiceIllegalStateException {
224         incomingParamCheck(principal, "principal");
225         PrincipalBo originalPrincipal = null;
226         if (StringUtils.isEmpty(principal.getEntityId()) || StringUtils.isBlank(principal.getEntityId())
227                 || StringUtils.isEmpty(principal.getPrincipalName()) || StringUtils.isBlank(principal.getPrincipalName())) {
228             throw new RiceIllegalStateException("Principal's entityId and PrincipalName must be populated before update");
229         }  else {
230              originalPrincipal = getPrincipalBoByPrincipalName(principal.getPrincipalName());
231             if (StringUtils.isEmpty(principal.getPrincipalId()) || originalPrincipal == null) {
232                 throw new RiceIllegalStateException("the Principal to update does not exist: " + principal);
233             }
234         }
235         
236         PrincipalBo bo = PrincipalBo.from(principal);
237         //Password is not set on the principal DTO, so we need to make sure the value is kept from existing principal
238         bo.setPassword(originalPrincipal.getPassword());
239         PrincipalBo updatedPrincipal = businessObjectService.save(bo);
240         if (originalPrincipal.isActive()
241                 && !updatedPrincipal.isActive()) {
242             KimImplServiceLocator.getRoleInternalService().principalInactivated(updatedPrincipal.getPrincipalId());
243         }
244         return PrincipalBo.to(updatedPrincipal);
245     }
246 
247     @Override
248     public Principal inactivatePrincipal(String principalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
249         incomingParamCheck(principalId, "principalId");
250 
251         Principal principal = getPrincipal(principalId);
252         if (principal == null) {
253             throw new RiceIllegalStateException("Principal with principalId: " + principalId + " does not exist");
254         }
255         PrincipalBo bo = PrincipalBo.from(principal);
256         bo.setActive(false);
257         return PrincipalBo.to(businessObjectService.save(bo));
258     }
259 
260     @Override
261     public Principal inactivatePrincipalByName(String principalName) throws RiceIllegalArgumentException, RiceIllegalStateException {
262         incomingParamCheck(principalName, "principalName");
263 
264         Principal principal = getPrincipalByPrincipalName(principalName);
265         if (principal == null) {
266             throw new RiceIllegalStateException("Principal with principalName: " + principalName + " does not exist");
267         }
268         PrincipalBo bo = PrincipalBo.from(principal);
269         bo.setActive(false);
270         return PrincipalBo.to(businessObjectService.save(bo));
271     }
272 
273     @Override
274     public EntityTypeContactInfo addEntityTypeContactInfoToEntity(EntityTypeContactInfo entityTypeData) throws RiceIllegalArgumentException, RiceIllegalStateException {
275         incomingParamCheck(entityTypeData, "entityTypeData");
276 
277         if (StringUtils.isEmpty(entityTypeData.getEntityId()) || StringUtils.isBlank(entityTypeData.getEntityId())
278                 || StringUtils.isEmpty(entityTypeData.getEntityTypeCode()) || StringUtils.isBlank(entityTypeData.getEntityTypeCode())) {
279             throw new RiceIllegalStateException("EntityTypeData's entityId and entityTypeCode must be populated before creation");
280         }  else {
281             if (getEntityTypeDataBo(entityTypeData.getEntityId(), entityTypeData.getEntityTypeCode()) != null) {
282                 throw new RiceIllegalStateException("the entityTypeData to create already exists: " + entityTypeData);
283             }
284         }
285         EntityTypeContactInfoBo bo = EntityTypeContactInfoBo.from(entityTypeData);
286         return EntityTypeContactInfoBo.to(businessObjectService.save(bo));
287     }
288 
289     private EntityTypeContactInfoBo getEntityTypeDataBo(String entityId, String entityTypeCode) {
290         Map<String,Object> criteria = new HashMap<String,Object>(3);
291          criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
292          criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
293          criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
294          return businessObjectService.findByPrimaryKey(EntityTypeContactInfoBo.class, criteria);
295     }
296 
297     @Override
298     public EntityTypeContactInfo updateEntityTypeContactInfo(EntityTypeContactInfo entityTypeContactInfo) throws RiceIllegalArgumentException, RiceIllegalStateException {
299         incomingParamCheck(entityTypeContactInfo, "entityTypeContactInfo");
300 
301         if (StringUtils.isBlank(entityTypeContactInfo.getEntityId()) || StringUtils.isEmpty(entityTypeContactInfo.getEntityId())
302                 || StringUtils.isBlank(entityTypeContactInfo.getEntityTypeCode()) || StringUtils.isEmpty(entityTypeContactInfo.getEntityTypeCode())) {
303             throw new RiceIllegalStateException("EntityTypeData's entityId and entityTypeCode must be populated before update");
304         }  else {
305             if (getEntityTypeDataBo(entityTypeContactInfo.getEntityId(), entityTypeContactInfo.getEntityTypeCode()) == null) {
306                 throw new RiceIllegalStateException("the entityTypeData to update does not exist: " + entityTypeContactInfo);
307             }
308         }
309         EntityTypeContactInfoBo bo = EntityTypeContactInfoBo.from(entityTypeContactInfo);
310         return EntityTypeContactInfoBo.to(businessObjectService.save(bo));
311     }
312 
313     @Override
314     public EntityTypeContactInfo inactivateEntityTypeContactInfo(String entityId, String entityTypeCode) throws RiceIllegalArgumentException, RiceIllegalStateException {
315         incomingParamCheck(entityId, "entityId");
316         incomingParamCheck(entityTypeCode, "entityTypeCode");
317 
318         EntityTypeContactInfoBo bo = getEntityTypeDataBo(entityId, entityTypeCode);
319         if (bo == null) {
320             throw new RiceIllegalStateException("EntityTypeData with entityId: " + entityId + " entityTypeCode: " + entityTypeCode + " does not exist");
321         }
322         bo.setActive(false);
323         return EntityTypeContactInfoBo.to(businessObjectService.save(bo));
324     }
325 
326     private EntityAddressBo getEntityAddressBo(String entityId, String entityTypeCode, String addressTypeCode) {
327         Map<String,Object> criteria = new HashMap<String,Object>(4);
328         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
329         criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
330         criteria.put("addressTypeCode", addressTypeCode);
331         criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
332         return businessObjectService.findByPrimaryKey(EntityAddressBo.class, criteria);
333     }
334 
335     private EntityAddressBo getEntityAddressBo(String addressId) {
336         Map<String,Object> criteria = new HashMap<String,Object>(4);
337         criteria.put(KIMPropertyConstants.Entity.ID, addressId);
338         return businessObjectService.findByPrimaryKey(EntityAddressBo.class, criteria);
339     }
340 
341     @Override
342     public EntityAddress addAddressToEntity(EntityAddress address) throws RiceIllegalArgumentException, RiceIllegalStateException {
343         incomingParamCheck(address, "address");
344 
345         if (StringUtils.isEmpty(address.getEntityId()) || StringUtils.isBlank(address.getEntityId())
346                 || StringUtils.isEmpty(address.getEntityTypeCode()) || StringUtils.isBlank(address.getEntityTypeCode())) {
347             throw new RiceIllegalStateException("Address's entityId and entityTypeCode must be populated before creation");
348         }  else {
349             if (address.getAddressType() == null) {
350                 throw new RiceIllegalStateException("Address's type must be populated before creation");
351             }
352             if (getEntityAddressBo(address.getEntityId(), address.getEntityTypeCode(), address.getAddressType().getCode()) != null) {
353                 throw new RiceIllegalStateException("the address to create already exists: " + address);
354             }
355         }
356         EntityAddressBo bo = EntityAddressBo.from(address);
357         return EntityAddressBo.to(businessObjectService.save(bo));
358     }
359 
360     @Override
361     public EntityAddress updateAddress(EntityAddress address) throws RiceIllegalArgumentException, RiceIllegalStateException {
362         incomingParamCheck(address, "address");
363 
364         if (StringUtils.isEmpty(address.getEntityId()) || StringUtils.isBlank(address.getEntityId())
365                 || StringUtils.isEmpty(address.getEntityTypeCode()) || StringUtils.isBlank(address.getEntityTypeCode())) {
366             throw new RiceIllegalStateException("Address's entityId and entityTypeCode must be populated before creation");
367         }  else {
368             if (address.getAddressType() == null) {
369                 throw new RiceIllegalStateException("Address's type must be populated before creation");
370             }
371             if (StringUtils.isEmpty(address.getId())
372                   ||  getEntityAddressBo(address.getEntityId(), address.getEntityTypeCode(), address.getAddressType().getCode()) == null) {
373                 throw new RiceIllegalStateException("the address to update does not exists: " + address);
374             }
375         }
376         EntityAddressBo bo = EntityAddressBo.from(address);
377         return EntityAddressBo.to(businessObjectService.save(bo));
378     }
379 
380     @Override
381     public EntityAddress inactivateAddress(String addressId) throws RiceIllegalArgumentException, RiceIllegalStateException {
382         incomingParamCheck(addressId, "addressId");
383 
384         EntityAddressBo bo = getEntityAddressBo(addressId);
385         if (bo == null) {
386             throw new RiceIllegalStateException("Address with addressId: " + addressId + " does not exist");
387         }
388         bo.setActive(false);
389         return EntityAddressBo.to(businessObjectService.save(bo));
390     }
391 
392     private EntityEmailBo getEntityEmailBo(String entityId, String entityTypeCode, String emailTypeCode) {
393         Map<String,Object> criteria = new HashMap<String,Object>(4);
394         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
395         criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
396         criteria.put("emailTypeCode", emailTypeCode);
397         criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
398         return businessObjectService.findByPrimaryKey(EntityEmailBo.class, criteria);
399     }
400 
401     private EntityEmailBo getEntityEmailBo(String emailId) {
402         Map<String,Object> criteria = new HashMap<String,Object>(4);
403         criteria.put(KIMPropertyConstants.Entity.ID, emailId);
404         return businessObjectService.findByPrimaryKey(EntityEmailBo.class, criteria);
405     }
406     @Override
407     public EntityEmail addEmailToEntity(EntityEmail email) throws RiceIllegalArgumentException, RiceIllegalStateException {
408         incomingParamCheck(email, "email");
409 
410         if (StringUtils.isEmpty(email.getEntityId()) || StringUtils.isBlank(email.getEntityId())
411                 || StringUtils.isEmpty(email.getEntityTypeCode()) || StringUtils.isBlank(email.getEntityTypeCode())) {
412             throw new RiceIllegalStateException("Email's entityId and entityTypeCode must be populated before creation");
413         }  else {
414             if (email.getEmailType() == null) {
415                 throw new RiceIllegalStateException("Email's type must be populated before creation");
416             }
417             if (getEntityEmailBo(email.getEntityId(), email.getEntityTypeCode(), email.getEmailType().getCode()) != null) {
418                 throw new RiceIllegalStateException("the email to create already exists: " + email);
419             }
420         }
421         EntityEmailBo bo = EntityEmailBo.from(email);
422         return EntityEmailBo.to(businessObjectService.save(bo));
423     }
424 
425     @Override
426     public EntityEmail updateEmail(EntityEmail email) throws RiceIllegalArgumentException, RiceIllegalStateException {
427         incomingParamCheck(email, "email");
428 
429         if (StringUtils.isEmpty(email.getEntityId()) || StringUtils.isBlank(email.getEntityId())
430                 || StringUtils.isEmpty(email.getEntityTypeCode()) || StringUtils.isBlank(email.getEntityTypeCode())) {
431             throw new RiceIllegalStateException("Email's entityId and entityTypeCode must be populated before creation");
432         }  else {
433             if (email.getEmailType() == null) {
434                 throw new RiceIllegalStateException("Email's type must be populated before creation");
435             }
436             if (StringUtils.isEmpty(email.getId())
437                   ||  getEntityEmailBo(email.getEntityId(), email.getEntityTypeCode(), email.getEmailType().getCode()) == null) {
438                 throw new RiceIllegalStateException("the email to update does not exists: " + email);
439             }
440         }
441         EntityEmailBo bo = EntityEmailBo.from(email);
442         return EntityEmailBo.to(businessObjectService.save(bo));
443     }
444 
445     @Override
446     public EntityEmail inactivateEmail(String emailId) throws RiceIllegalArgumentException, RiceIllegalStateException {
447         incomingParamCheck(emailId, "emailId");
448 
449         EntityEmailBo bo = getEntityEmailBo(emailId);
450         if (bo == null) {
451             throw new RiceIllegalStateException("Email with emailId: " + emailId + " does not exist");
452         }
453         bo.setActive(false);
454         return EntityEmailBo.to(businessObjectService.save(bo));
455     }
456 
457     private EntityPhoneBo getEntityPhoneBo(String entityId, String entityTypeCode, String phoneTypeCode) {
458         Map<String,Object> criteria = new HashMap<String,Object>(4);
459         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
460         criteria.put(KIMPropertyConstants.Entity.ENTITY_TYPE_CODE, entityTypeCode);
461         criteria.put("phoneTypeCode", phoneTypeCode);
462         criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
463         return businessObjectService.findByPrimaryKey(EntityPhoneBo.class, criteria);
464     }
465 
466     private EntityPhoneBo getEntityPhoneBo(String phoneId) {
467         Map<String,Object> criteria = new HashMap<String,Object>(4);
468         criteria.put(KIMPropertyConstants.Entity.ID, phoneId);
469         return businessObjectService.findByPrimaryKey(EntityPhoneBo.class, criteria);
470     }
471 
472     @Override
473     public EntityPhone addPhoneToEntity(EntityPhone phone) throws RiceIllegalArgumentException, RiceIllegalStateException {
474         incomingParamCheck(phone, "phone");
475 
476         if (StringUtils.isEmpty(phone.getEntityId()) || StringUtils.isBlank(phone.getEntityId())
477                 || StringUtils.isEmpty(phone.getEntityTypeCode()) || StringUtils.isBlank(phone.getEntityTypeCode())) {
478             throw new RiceIllegalStateException("Phone's entityId and entityTypeCode must be populated before creation");
479         }  else {
480             if (phone.getPhoneType() == null) {
481                 throw new RiceIllegalStateException("Phone's type must be populated before creation");
482             }
483             if (getEntityPhoneBo(phone.getEntityId(), phone.getEntityTypeCode(), phone.getPhoneType().getCode()) != null) {
484                 throw new RiceIllegalStateException("the phone to create already exists: " + phone);
485             }
486         }
487         EntityPhoneBo bo = EntityPhoneBo.from(phone);
488         return EntityPhoneBo.to(businessObjectService.save(bo));
489     }
490 
491     @Override
492     public EntityPhone updatePhone(EntityPhone phone) throws RiceIllegalArgumentException, RiceIllegalStateException {
493         incomingParamCheck(phone, "phone");
494 
495         if (StringUtils.isEmpty(phone.getEntityId()) || StringUtils.isBlank(phone.getEntityId())
496                 || StringUtils.isEmpty(phone.getEntityTypeCode()) || StringUtils.isBlank(phone.getEntityTypeCode())) {
497             throw new RiceIllegalStateException("Phone's entityId and entityTypeCode must be populated before creation");
498         }  else {
499             if (phone.getPhoneType() == null) {
500                 throw new RiceIllegalStateException("Phone's type must be populated before creation");
501             }
502             if (StringUtils.isEmpty(phone.getId())
503                   ||  getEntityPhoneBo(phone.getEntityId(), phone.getEntityTypeCode(), phone.getPhoneType().getCode()) == null) {
504                 throw new RiceIllegalStateException("the phone to update does not exists: " + phone);
505             }
506         }
507         EntityPhoneBo bo = EntityPhoneBo.from(phone);
508         return EntityPhoneBo.to(businessObjectService.save(bo));
509     }
510 
511     @Override
512     public EntityPhone inactivatePhone(String phoneId) throws RiceIllegalArgumentException, RiceIllegalStateException {
513         incomingParamCheck(phoneId, "phoneId");
514 
515         EntityPhoneBo bo = getEntityPhoneBo(phoneId);
516         if (bo == null) {
517             throw new RiceIllegalStateException("Phone with phoneId: " + phoneId + " does not exist");
518         }
519         bo.setActive(false);
520         return EntityPhoneBo.to(businessObjectService.save(bo));
521     }
522 
523 
524     private EntityExternalIdentifierBo getEntityExternalIdentifierBo(String entityId, String externalIdentifierTypeCode) {
525         Map<String,Object> criteria = new HashMap<String,Object>(4);
526         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
527         criteria.put("externalIdentifierTypeCode", externalIdentifierTypeCode);
528         return businessObjectService.findByPrimaryKey(EntityExternalIdentifierBo.class, criteria);
529     }
530 
531     @Override
532     public EntityExternalIdentifier addExternalIdentifierToEntity(EntityExternalIdentifier externalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
533         incomingParamCheck(externalId, "externalId");
534 
535         if (StringUtils.isEmpty(externalId.getEntityId()) || StringUtils.isBlank(externalId.getEntityId())
536                 || StringUtils.isEmpty(externalId.getExternalIdentifierTypeCode()) || StringUtils.isBlank(externalId.getExternalIdentifierTypeCode())) {
537             throw new RiceIllegalStateException("EntityExternalIdentifier's entityId and entityTypeCode must be populated before creation");
538         }  else {
539             if (getEntityExternalIdentifierBo(externalId.getEntityId(), externalId.getExternalIdentifierTypeCode()) != null) {
540                 throw new RiceIllegalStateException("the EntityExternalIdentifier to create already exists: " + externalId);
541             }
542         }
543         EntityExternalIdentifierBo bo = EntityExternalIdentifierBo.from(externalId);
544         return EntityExternalIdentifierBo.to(businessObjectService.save(bo));
545     }
546 
547     @Override
548     public EntityExternalIdentifier updateExternalIdentifier(EntityExternalIdentifier externalId) throws RiceIllegalArgumentException, RiceIllegalStateException {
549         incomingParamCheck(externalId, "externalId");
550 
551         if (StringUtils.isEmpty(externalId.getEntityId()) || StringUtils.isBlank(externalId.getEntityId())
552                 || StringUtils.isEmpty(externalId.getExternalIdentifierTypeCode()) || StringUtils.isBlank(externalId.getExternalIdentifierTypeCode())) {
553             throw new RiceIllegalStateException("EntityExternalIdentifier's entityId and externalIdentifierTypeCode must be populated before creation");
554         }  else {
555             if (StringUtils.isEmpty(externalId.getId())
556                   ||  getEntityExternalIdentifierBo(externalId.getEntityId(), externalId.getExternalIdentifierTypeCode()) == null) {
557                 throw new RiceIllegalStateException("the external identifier to update does not exist: " + externalId);
558             }
559         }
560         EntityExternalIdentifierBo bo = EntityExternalIdentifierBo.from(externalId);
561         return EntityExternalIdentifierBo.to(businessObjectService.save(bo));
562     }
563 
564 
565     private EntityAffiliationBo getEntityAffiliationBo(String id) {
566         Map<String,Object> criteria = new HashMap<String,Object>();
567         criteria.put(KIMPropertyConstants.Entity.ID, id);
568         return businessObjectService.findByPrimaryKey(EntityAffiliationBo.class, criteria);
569     }
570 
571     @Override
572     public EntityAffiliation addAffiliationToEntity(EntityAffiliation affiliation) throws RiceIllegalArgumentException, RiceIllegalStateException {
573         incomingParamCheck(affiliation, "affiliation");
574 
575         if (StringUtils.isEmpty(affiliation.getEntityId()) || StringUtils.isBlank(affiliation.getEntityId())) {
576             throw new RiceIllegalStateException("Affiliation's entityId must be populated before creation");
577         }  else {
578             if (affiliation.getAffiliationType() == null) {
579                 throw new RiceIllegalStateException("EntityAffiliation's type must be populated before creation");
580             }
581             if (getEntityAffiliationBo(affiliation.getId()) != null) {
582                 throw new RiceIllegalStateException("the EntityAffiliation to create already exists: " + affiliation);
583             }
584         }
585         EntityAffiliationBo bo = EntityAffiliationBo.from(affiliation);
586         return EntityAffiliationBo.to(businessObjectService.save(bo));
587     }
588 
589     @Override
590     public EntityAffiliation updateAffiliation(EntityAffiliation affiliation) throws RiceIllegalArgumentException, RiceIllegalStateException {
591         incomingParamCheck(affiliation, "affiliation");
592 
593         if (StringUtils.isEmpty(affiliation.getEntityId()) || StringUtils.isBlank(affiliation.getEntityId())) {
594             throw new RiceIllegalStateException("Affiliation's entityId must be populated before creation");
595         }  else {
596             if (affiliation.getAffiliationType() == null) {
597                 throw new RiceIllegalStateException("EntityAffiliation's type must be populated before creation");
598             }
599             if (StringUtils.isEmpty(affiliation.getId())
600                   ||  getEntityAffiliationBo(affiliation.getId()) == null) {
601                 throw new RiceIllegalStateException("the EntityAffiliation to update already exists: " + affiliation);
602             }
603         }
604         EntityAffiliationBo bo = EntityAffiliationBo.from(affiliation);
605         return EntityAffiliationBo.to(businessObjectService.save(bo));
606     }
607 
608     @Override
609     public EntityAffiliation inactivateAffiliation(String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
610         incomingParamCheck(id, "id");
611 
612         EntityAffiliationBo bo = getEntityAffiliationBo(id);
613         if (bo == null) {
614             throw new RiceIllegalStateException("EntityAffiliation with id: " + id + " does not exist");
615         }
616         bo.setActive(false);
617         return EntityAffiliationBo.to(businessObjectService.save(bo));
618     }
619 
620     @Override
621 	public EntityQueryResults findEntities(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
622 		incomingParamCheck(queryByCriteria, "queryByCriteria");
623 
624         GenericQueryResults<EntityBo> results = criteriaLookupService.lookup(EntityBo.class, queryByCriteria);
625 
626         EntityQueryResults.Builder builder = EntityQueryResults.Builder.create();
627         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
628         builder.setTotalRowCount(results.getTotalRowCount());
629 
630         final List<Entity.Builder> ims = new ArrayList<Entity.Builder>();
631         for (EntityBo bo : results.getResults()) {
632             ims.add(Entity.Builder.create(bo));
633         }
634 
635         builder.setResults(ims);
636         return builder.build();
637 	}
638 
639     @Override
640 	public EntityDefaultQueryResults findEntityDefaults(QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
641 		incomingParamCheck(queryByCriteria, "queryByCriteria");
642 
643         GenericQueryResults<EntityBo> results = criteriaLookupService.lookup(EntityBo.class, queryByCriteria);
644 
645         EntityDefaultQueryResults.Builder builder = EntityDefaultQueryResults.Builder.create();
646         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
647         builder.setTotalRowCount(results.getTotalRowCount());
648 
649         final List<EntityDefault.Builder> ims = new ArrayList<EntityDefault.Builder>();
650         for (EntityBo bo : results.getResults()) {
651             ims.add(EntityDefault.Builder.create(bo));
652         }
653 
654         builder.setResults(ims);
655         return builder.build();
656 	}
657 
658 	protected EntityNameQueryResults findNames(QueryByCriteria queryByCriteria) {
659 		incomingParamCheck(queryByCriteria, "queryByCriteria");
660 
661         GenericQueryResults<EntityNameBo> results = criteriaLookupService.lookup(EntityNameBo.class, queryByCriteria);
662 
663         EntityNameQueryResults.Builder builder = EntityNameQueryResults.Builder.create();
664         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
665         builder.setTotalRowCount(results.getTotalRowCount());
666 
667         final List<EntityName.Builder> ims = new ArrayList<EntityName.Builder>();
668         for (EntityNameBo bo : results.getResults()) {
669             ims.add(EntityName.Builder.create(bo));
670         }
671 
672         builder.setResults(ims);
673         return builder.build();
674 	}
675 
676     @Override
677 	public EntityPrivacyPreferences getEntityPrivacyPreferences(String entityId) throws RiceIllegalArgumentException {
678         incomingParamCheck(entityId, "entityId");
679 		Map<String,String> criteria = new HashMap<String,String>(1);
680         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
681 		return EntityPrivacyPreferencesBo.to(businessObjectService.findByPrimaryKey(EntityPrivacyPreferencesBo.class, criteria));
682 	}
683 
684     @Override
685 	public Principal getPrincipal(String principalId) throws RiceIllegalArgumentException {
686 		incomingParamCheck(principalId, "principalId");
687 
688         PrincipalBo principal = getPrincipalBo(principalId);
689 		if ( principal == null ) {
690 			return null;
691 		}
692         if (StringUtils.isBlank(principal.getPrincipalName())) {
693             principal.setPrincipalName(UNAVAILABLE);
694         }
695 		return PrincipalBo.to(principal);
696 	}
697 
698     @Override
699     public List<Principal> getPrincipals (List<String> principalIds) {
700         List<Principal>  ret = new ArrayList<Principal>();
701         for(String p: principalIds) {
702             Principal principalInfo = getPrincipal(p);
703 
704             if (principalInfo != null) {
705                 ret.add(principalInfo) ;
706             }
707         }
708         return ret;
709     }
710 	
711 	private PrincipalBo getPrincipalBo(String principalId) {
712 		Map<String,String> criteria = new HashMap<String,String>(1);
713         criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
714 		return businessObjectService.findByPrimaryKey(PrincipalBo.class, criteria);
715 	}
716 
717 	private EntityBo getEntityBo(String entityId) {
718 		return businessObjectService.findByPrimaryKey(EntityBo.class, Collections.singletonMap("id", entityId));
719 	}
720 
721 	@Override
722 	public Principal getPrincipalByPrincipalName(String principalName) throws RiceIllegalArgumentException {
723 		incomingParamCheck(principalName, "principalName");
724 
725 		return PrincipalBo.to(getPrincipalBoByPrincipalName(principalName));
726     }
727 
728     private PrincipalBo getPrincipalBoByPrincipalName(String principalName) throws RiceIllegalArgumentException {
729 
730         Map<String,Object> criteria = new HashMap<String,Object>(1);
731         criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_NAME, principalName.toLowerCase());
732         Collection<PrincipalBo> principals = businessObjectService.findMatching(PrincipalBo.class, criteria);
733         if (!principals.isEmpty() && principals.size() == 1) {
734             return principals.iterator().next();
735         }
736         return null;
737     }
738 
739     @Override
740     public List<Principal> getPrincipalsByEntityId(String entityId) throws RiceIllegalArgumentException {
741         incomingParamCheck(entityId, "entityId");
742 
743         List<Principal>  principals = new ArrayList<Principal>();
744         Map<String,Object> criteria = new HashMap<String,Object>(2);
745         criteria.put(KIMPropertyConstants.Person.ENTITY_ID, entityId);
746         Collection<PrincipalBo> principalBos = businessObjectService.findMatching(PrincipalBo.class, criteria);
747 
748         if (principalBos != null && !principalBos.isEmpty()) {
749 
750             for(PrincipalBo principalBo: principalBos) {
751                 Principal principal = PrincipalBo.to(principalBo);
752                 principals.add(principal);
753             }
754             return principals;
755         }
756         return null;
757     }
758 
759     @Override
760     public List<Principal> getPrincipalsByEmployeeId(String employeeId) throws RiceIllegalArgumentException {
761         incomingParamCheck(employeeId, "employeeId");
762 
763         List<Principal>  principals = new ArrayList<Principal>();
764         Map<String,Object> criteria = new HashMap<String,Object>(2);
765         criteria.put(KIMPropertyConstants.Person.EMPLOYEE_ID, employeeId);
766         Collection<EntityEmploymentBo> entityEmploymentBos = businessObjectService.findMatching(EntityEmploymentBo.class, criteria);
767 
768         if (entityEmploymentBos != null && !entityEmploymentBos.isEmpty()) {
769             List<String>  entityIds = new ArrayList<String>();
770             for(EntityEmploymentBo entityEmploymentBo: entityEmploymentBos) {
771                 String entityId =  entityEmploymentBo.getEntityId();
772                 if (StringUtils.isNotBlank(entityId) && !entityIds.contains(entityId)) {
773                     entityIds.add(entityId);
774                 }
775             }
776 
777             for(String entityId: entityIds) {
778                 List<Principal> principalsForEntity = getPrincipalsByEntityId(entityId);
779                 if (principalsForEntity != null && !principalsForEntity.isEmpty()) {
780                     principals.addAll(principalsForEntity);
781                 }
782             }
783             if (!principals.isEmpty()) {
784                 return principals;
785             }
786         }
787         return null;
788     }
789 
790 	/**
791 	 * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByPrincipalName(java.lang.String)
792 	 */
793 	protected EntityBo getEntityBoByPrincipalName(String principalName) {
794 		if ( StringUtils.isBlank( principalName ) ) {
795 			return null;
796 		}
797         return getEntityByKeyValue("principals." + KIMPropertyConstants.Principal.PRINCIPAL_NAME, principalName.toLowerCase());
798 	}
799 
800 	/**
801 	 * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByPrincipalId(java.lang.String)
802 	 */
803 	protected EntityBo getEntityBoByPrincipalId(String principalId) {
804 		if ( StringUtils.isBlank( principalId ) ) {
805 			return null;
806 		}
807         return getEntityByKeyValue("principals." + KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
808 	}
809 
810 	/**
811      * @see org.kuali.rice.kim.api.identity.IdentityService#getEntityByEmployeeId(java.lang.String)
812      */
813     protected EntityBo getEntityBoByEmployeeId(String employeeId) {
814         if ( StringUtils.isBlank( employeeId ) ) {
815             return null;
816         }
817         return getEntityByKeyValue("employmentInformation." + KIMPropertyConstants.Person.EMPLOYEE_ID, employeeId);
818     }
819     
820 	/**
821 	 * Generic helper method for performing a lookup through the business object service.
822 	 */
823 	protected EntityBo getEntityByKeyValue(String key, String value) {
824 		Map<String,String> criteria = new HashMap<String,String>(1);
825         criteria.put(key, value);
826         Collection<EntityBo> entities = businessObjectService.findMatching(EntityBo.class, criteria);
827         if (entities != null && entities.size() >= 1) {
828         	return entities.iterator().next();
829         }
830 		return null;
831 	}
832 
833     @Override
834 	public CodedAttribute getAddressType( String code ) throws RiceIllegalArgumentException {
835         incomingParamCheck(code, "code");
836 		EntityAddressTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityAddressTypeBo.class, code);
837 		if ( impl == null ) {
838 			return null;
839 		}
840 		return EntityAddressTypeBo.to(impl);
841 	}
842 
843     @Override
844     public List<CodedAttribute> findAllAddressTypes() {
845         List<EntityAddressTypeBo> bos = (List<EntityAddressTypeBo>)businessObjectService
846                 .findMatching(EntityAddressTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
847 
848         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
849         for (EntityAddressTypeBo bo : bos) {
850             codedAttributes.add(EntityAddressTypeBo.to(bo));
851         }
852         return Collections.unmodifiableList(codedAttributes);
853     }
854 
855     @Override
856     public EntityAffiliationType getAffiliationType( String code ) throws RiceIllegalArgumentException {
857         incomingParamCheck(code, "code");
858 
859         EntityAffiliationTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityAffiliationTypeBo.class, code);
860 		if ( impl == null ) {
861 			return null;
862 		}
863 		return EntityAffiliationTypeBo.to(impl);
864 	}
865 
866     @Override
867     public List<EntityAffiliationType> findAllAffiliationTypes() {
868         List<EntityAffiliationTypeBo> bos = (List<EntityAffiliationTypeBo>)businessObjectService
869                 .findMatching(EntityAffiliationTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
870 
871         List<EntityAffiliationType> codedAttributes = new ArrayList<EntityAffiliationType>();
872         for (EntityAffiliationTypeBo bo : bos) {
873             codedAttributes.add(EntityAffiliationTypeBo.to(bo));
874         }
875         return Collections.unmodifiableList(codedAttributes);
876     }
877 
878     @Override
879     public CodedAttribute getCitizenshipStatus( String code ) throws RiceIllegalArgumentException {
880 		incomingParamCheck(code, "code");
881         EntityCitizenshipStatusBo impl = businessObjectService.findBySinglePrimaryKey(EntityCitizenshipStatusBo.class, code);
882 		if ( impl == null ) {
883 			return null;
884 		}
885 		return EntityCitizenshipStatusBo.to(impl);
886 	}
887 
888     @Override
889     public List<CodedAttribute> findAllCitizenshipStatuses() {
890         List<EntityCitizenshipStatusBo> bos = (List<EntityCitizenshipStatusBo>)businessObjectService
891                 .findMatching(EntityCitizenshipStatusBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
892 
893         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
894         for (EntityCitizenshipStatusBo bo : bos) {
895             codedAttributes.add(EntityCitizenshipStatusBo.to(bo));
896         }
897         return Collections.unmodifiableList(codedAttributes);
898     }
899 
900     @Override
901     public CodedAttribute getEmailType( String code ) throws RiceIllegalArgumentException {
902 		incomingParamCheck(code, "code");
903         EntityEmailTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityEmailTypeBo.class, code);
904 		if ( impl == null ) {
905 			return null;
906 		}
907 		return EntityEmailTypeBo.to(impl);
908 	}
909 
910     @Override
911     public List<CodedAttribute> findAllEmailTypes() {
912         List<EntityEmailTypeBo> bos = (List<EntityEmailTypeBo>)businessObjectService
913                 .findMatching(EntityEmailTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
914 
915         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
916         for (EntityEmailTypeBo bo : bos) {
917             codedAttributes.add(EntityEmailTypeBo.to(bo));
918         }
919         return Collections.unmodifiableList(codedAttributes);
920     }
921 
922     @Override
923     public PrincipalQueryResults findPrincipals(
924             @WebParam(name = "query") QueryByCriteria query) throws RiceIllegalArgumentException {
925         incomingParamCheck(query, "query");
926 
927         GenericQueryResults<PrincipalBo> results = criteriaLookupService.lookup(PrincipalBo.class, query);
928 
929         PrincipalQueryResults.Builder builder = PrincipalQueryResults.Builder.create();
930         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
931         builder.setTotalRowCount(results.getTotalRowCount());
932 
933         final List<Principal.Builder> ims = new ArrayList<Principal.Builder>();
934         for (PrincipalBo bo : results.getResults()) {
935             ims.add(Principal.Builder.create(bo));
936         }
937 
938         builder.setResults(ims);
939         return builder.build();
940     }
941 
942     @Override
943     public CodedAttribute getEmploymentStatus( String code ) throws RiceIllegalArgumentException {
944 		incomingParamCheck(code, "code");
945         EntityEmploymentStatusBo impl = businessObjectService.findBySinglePrimaryKey(EntityEmploymentStatusBo.class, code);
946 		if ( impl == null ) {
947 			return null;
948 		}
949 		return EntityEmploymentStatusBo.to(impl);
950 	}
951 
952     @Override
953     public List<CodedAttribute> findAllEmploymentStatuses() {
954         List<EntityEmploymentStatusBo> bos = (List<EntityEmploymentStatusBo>)businessObjectService
955                 .findMatching(EntityEmploymentStatusBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
956 
957         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
958         for (EntityEmploymentStatusBo bo : bos) {
959             codedAttributes.add(EntityEmploymentStatusBo.to(bo));
960         }
961         return Collections.unmodifiableList(codedAttributes);
962     }
963 
964     @Override
965     public CodedAttribute getEmploymentType( String code ) throws RiceIllegalArgumentException {
966 		incomingParamCheck(code, "code");
967         EntityEmploymentTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityEmploymentTypeBo.class, code);
968 		if ( impl == null ) {
969 			return null;
970 		}
971 		return EntityEmploymentTypeBo.to(impl);
972 	}
973 
974     @Override
975     public List<CodedAttribute> findAllEmploymentTypes() {
976         List<EntityEmploymentTypeBo> bos = (List<EntityEmploymentTypeBo>)businessObjectService
977                 .findMatching(EntityEmploymentTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
978 
979         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
980         for (EntityEmploymentTypeBo bo : bos) {
981             codedAttributes.add(EntityEmploymentTypeBo.to(bo));
982         }
983         return Collections.unmodifiableList(codedAttributes);
984     }
985 
986     @Override
987     public CodedAttribute getNameType(String code) throws RiceIllegalArgumentException {
988 		incomingParamCheck(code, "code");
989         EntityNameTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityNameTypeBo.class, code);
990 		if ( impl == null ) {
991 			return null;
992 		}
993 		return EntityNameTypeBo.to(impl);
994 	}
995 
996     @Override
997     public List<CodedAttribute> findAllNameTypes() {
998         List<EntityNameTypeBo> bos = (List<EntityNameTypeBo>)businessObjectService
999                 .findMatching(EntityNameTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
1000 
1001         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1002         for (EntityNameTypeBo bo : bos) {
1003             codedAttributes.add(EntityNameTypeBo.to(bo));
1004         }
1005         return Collections.unmodifiableList(codedAttributes);
1006     }
1007 
1008     @Override
1009     public CodedAttribute getEntityType( String code ) throws RiceIllegalArgumentException {
1010 		incomingParamCheck(code, "code");
1011         EntityTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityTypeBo.class, code);
1012 		if ( impl == null ) {
1013 			return null;
1014 		}
1015 		return EntityTypeBo.to(impl);
1016 	}
1017 
1018     @Override
1019     public List<CodedAttribute> findAllEntityTypes() {
1020         List<EntityTypeBo> bos = (List<EntityTypeBo>)businessObjectService
1021                 .findMatching(EntityTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
1022         
1023         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1024         for (EntityTypeBo bo : bos) {
1025             codedAttributes.add(EntityTypeBo.to(bo));    
1026         }
1027         return Collections.unmodifiableList(codedAttributes);
1028     }
1029 
1030     @Override
1031     public EntityExternalIdentifierType getExternalIdentifierType( String code ) throws RiceIllegalArgumentException {
1032 		incomingParamCheck(code, "code");
1033 
1034         EntityExternalIdentifierTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityExternalIdentifierTypeBo.class, code);
1035 		if ( impl == null ) {
1036 			return null;
1037 		}
1038 		return EntityExternalIdentifierTypeBo.to(impl);
1039 	}
1040 
1041     @Override
1042     public List<EntityExternalIdentifierType> findAllExternalIdendtifierTypes() {
1043         List<EntityExternalIdentifierTypeBo> bos = (List<EntityExternalIdentifierTypeBo>)businessObjectService
1044                 .findMatching(EntityExternalIdentifierTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
1045 
1046         List<EntityExternalIdentifierType> codedAttributes = new ArrayList<EntityExternalIdentifierType>();
1047         for (EntityExternalIdentifierTypeBo bo : bos) {
1048             codedAttributes.add(EntityExternalIdentifierTypeBo.to(bo));
1049         }
1050         return Collections.unmodifiableList(codedAttributes);
1051     }
1052 
1053     @Override
1054     public CodedAttribute getPhoneType( String code ) throws RiceIllegalArgumentException {
1055 		incomingParamCheck(code, "code");
1056         EntityPhoneTypeBo impl = businessObjectService.findBySinglePrimaryKey(EntityPhoneTypeBo.class, code);
1057 		if ( impl == null ) {
1058 			return null;
1059 		}
1060 		return EntityPhoneTypeBo.to(impl);
1061 	}
1062 
1063     @Override
1064     public List<CodedAttribute> findAllPhoneTypes() {
1065         List<EntityPhoneTypeBo> bos = (List<EntityPhoneTypeBo>)businessObjectService
1066                 .findMatching(EntityPhoneTypeBo.class, Collections.singletonMap(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE));
1067 
1068         List<CodedAttribute> codedAttributes = new ArrayList<CodedAttribute>();
1069         for (EntityPhoneTypeBo bo : bos) {
1070             codedAttributes.add(EntityPhoneTypeBo.to(bo));
1071         }
1072         return Collections.unmodifiableList(codedAttributes);
1073     }
1074 
1075     @Override
1076     public Entity createEntity(Entity entity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1077         incomingParamCheck(entity, "entity");
1078 
1079         if (StringUtils.isNotBlank(entity.getId()) && getEntity(entity.getId()) != null) {
1080             throw new RiceIllegalStateException("the Entity to create already exists: " + entity);
1081         }
1082 
1083         EntityBo bo = EntityBo.from(entity);
1084         return EntityBo.to(businessObjectService.save(bo));
1085     }
1086 
1087     @Override
1088     public Entity updateEntity(Entity entity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1089         incomingParamCheck(entity, "entity");
1090         EntityBo oldBo = null;
1091         Map<String, String> passwdMap = new HashMap<String, String>();
1092         if (StringUtils.isBlank(entity.getId())) {
1093             throw new RiceIllegalStateException("the Entity does not exist: " + entity);
1094         } else {
1095             oldBo = getEntityBo(entity.getId());
1096             if (oldBo == null) {
1097                 throw new RiceIllegalStateException("the Entity does not exist: " + entity);    
1098             }
1099         }
1100 
1101         for (PrincipalBo principalBo : oldBo.getPrincipals()) {
1102             passwdMap.put(principalBo.getPrincipalId(), principalBo.getPassword());
1103         }
1104         EntityBo bo = EntityBo.from(entity);
1105         for (PrincipalBo principal : bo.getPrincipals()) {
1106             principal.setPassword(passwdMap.get(principal.getPrincipalId()));
1107         }
1108         return EntityBo.to(businessObjectService.save(bo));
1109     }
1110 
1111 
1112 
1113     @Override
1114     public Entity inactivateEntity(String entityId) throws RiceIllegalArgumentException, RiceIllegalStateException {
1115         incomingParamCheck(entityId, "entityId");
1116 
1117         EntityBo entity = getEntityBo(entityId);
1118         if (entity == null) {
1119             throw new RiceIllegalStateException("an Entity does not exist for entityId: " + entityId);
1120         }
1121 
1122         entity.setActive(false);
1123         return EntityBo.to(businessObjectService.save(entity));
1124     }
1125 
1126     @Override
1127     public EntityPrivacyPreferences addPrivacyPreferencesToEntity(EntityPrivacyPreferences privacyPreferences) throws RiceIllegalArgumentException, RiceIllegalStateException {
1128         incomingParamCheck(privacyPreferences, "privacyPreferences");
1129 
1130         if (StringUtils.isEmpty(privacyPreferences.getEntityId()) || StringUtils.isBlank(privacyPreferences.getEntityId())) {
1131             throw new RiceIllegalStateException("PrivacyPreferences' entityId must be populated before creation");
1132         }  else {
1133             if (getEntityPrivacyPreferences(privacyPreferences.getEntityId()) != null) {
1134                 throw new RiceIllegalStateException("the PrivacyPreferences to create already exists: " + privacyPreferences);
1135             }
1136         }
1137         EntityPrivacyPreferencesBo bo = EntityPrivacyPreferencesBo.from(privacyPreferences);
1138         return EntityPrivacyPreferencesBo.to(businessObjectService.save(bo));
1139     }
1140 
1141     @Override
1142     public EntityPrivacyPreferences updatePrivacyPreferences(EntityPrivacyPreferences privacyPreferences) throws RiceIllegalArgumentException, RiceIllegalStateException {
1143         incomingParamCheck(privacyPreferences, "privacyPreferences");
1144 
1145         if (StringUtils.isEmpty(privacyPreferences.getEntityId()) || StringUtils.isBlank(privacyPreferences.getEntityId())) {
1146             throw new RiceIllegalStateException("PrivacyPreferences' entityId must be populated before update");
1147         }  else {
1148             if (getEntityPrivacyPreferences(privacyPreferences.getEntityId()) == null) {
1149                 throw new RiceIllegalStateException("the PrivacyPreferences to update does not exist: " + privacyPreferences);
1150             }
1151         }
1152         EntityPrivacyPreferencesBo bo = EntityPrivacyPreferencesBo.from(privacyPreferences);
1153         return EntityPrivacyPreferencesBo.to(businessObjectService.save(bo));
1154     }
1155 
1156     private EntityCitizenshipBo getEntityCitizenshipBo(String entityId, String citizenshipStatusCode) {
1157         if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(citizenshipStatusCode)) {
1158             return null;
1159         }
1160         Map<String,Object> criteria = new HashMap<String,Object>(4);
1161         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1162         criteria.put("statusCode", citizenshipStatusCode);
1163         criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1164         return businessObjectService.findByPrimaryKey(EntityCitizenshipBo.class, criteria);
1165     }
1166 
1167     private EntityCitizenshipBo getEntityCitizenshipBo(String id) {
1168         if (StringUtils.isEmpty(id)) {
1169             return null;
1170         }
1171         Map<String,Object> criteria = new HashMap<String,Object>();
1172         criteria.put(KIMPropertyConstants.Entity.ID, id);
1173         criteria.put(KIMPropertyConstants.Entity.ACTIVE, Boolean.TRUE);
1174         return businessObjectService.findByPrimaryKey(EntityCitizenshipBo.class, criteria);
1175     }
1176 
1177     @Override
1178     public EntityCitizenship addCitizenshipToEntity(EntityCitizenship citizenship) throws RiceIllegalArgumentException, RiceIllegalStateException {
1179         incomingParamCheck(citizenship, "citizenship");
1180 
1181         if (StringUtils.isEmpty(citizenship.getEntityId()) || StringUtils.isBlank(citizenship.getEntityId())) {
1182             throw new RiceIllegalStateException("Citizenship's entityId must be populated before creation");
1183         }  else {
1184             if (citizenship.getStatus() == null) {
1185                 throw new RiceIllegalStateException("Citizenship's status must be populated before creation");
1186             }
1187             if (getEntityCitizenshipBo(citizenship.getEntityId(), citizenship.getStatus().getCode()) != null) {
1188                 throw new RiceIllegalStateException("the EntityCitizenship to create already exists: " + citizenship);
1189             }
1190         }
1191         EntityCitizenshipBo bo = EntityCitizenshipBo.from(citizenship);
1192         return EntityCitizenshipBo.to(businessObjectService.save(bo));
1193     }
1194 
1195     @Override
1196     public EntityCitizenship updateCitizenship(EntityCitizenship citizenship) throws RiceIllegalArgumentException, RiceIllegalStateException {
1197         incomingParamCheck(citizenship, "citizenship");
1198 
1199         if (StringUtils.isEmpty(citizenship.getEntityId()) || StringUtils.isBlank(citizenship.getEntityId())) {
1200             throw new RiceIllegalStateException("Email's entityId must be populated before creation");
1201         }  else {
1202             if (citizenship.getStatus() == null) {
1203                 throw new RiceIllegalStateException("Citizenship's status must be populated before creation");
1204             }
1205             if (getEntityCitizenshipBo(citizenship.getEntityId(), citizenship.getStatus().getCode()) == null) {
1206                 throw new RiceIllegalStateException("the EntityCitizenship to update does not exist: " + citizenship);
1207             }
1208         }
1209         EntityCitizenshipBo bo = EntityCitizenshipBo.from(citizenship);
1210         return EntityCitizenshipBo.to(businessObjectService.save(bo));
1211     }
1212 
1213     @Override
1214     public EntityCitizenship inactivateCitizenship(String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1215         incomingParamCheck(id, "id");
1216 
1217         EntityCitizenshipBo bo = getEntityCitizenshipBo(id);
1218         if (bo == null) {
1219             throw new RiceIllegalStateException("the EntityCitizenship with id: " + id + " does not exist");
1220         }
1221         bo.setActive(false);
1222         return EntityCitizenshipBo.to(businessObjectService.save(bo));
1223     }
1224 
1225     private EntityEthnicityBo getEntityEthnicityBo(String ethnicityId) {
1226         if (StringUtils.isEmpty(ethnicityId)) {
1227             return null;
1228         }
1229         Map<String,Object> criteria = new HashMap<String,Object>();
1230         criteria.put(KIMPropertyConstants.Entity.ID, ethnicityId);
1231         return businessObjectService.findByPrimaryKey(EntityEthnicityBo.class, criteria);
1232     }
1233     @Override
1234     public EntityEthnicity addEthnicityToEntity(EntityEthnicity ethnicity) throws RiceIllegalArgumentException {
1235         incomingParamCheck(ethnicity, "ethnicity");
1236 
1237         if (StringUtils.isEmpty(ethnicity.getEntityId()) || StringUtils.isBlank(ethnicity.getEntityId())) {
1238             throw new RiceIllegalStateException("Ethnicity's entityId must be populated before creation");
1239         }  else {
1240             if (StringUtils.isNotEmpty(ethnicity.getId()) && getEntityEthnicityBo(ethnicity.getId()) != null) {
1241                 throw new RiceIllegalStateException("the EntityEthnicity to create already exists: " + ethnicity);
1242             }
1243         }
1244         EntityEthnicityBo bo = EntityEthnicityBo.from(ethnicity);
1245         return EntityEthnicityBo.to(businessObjectService.save(bo));
1246     }
1247 
1248     @Override
1249     public EntityEthnicity updateEthnicity(EntityEthnicity ethnicity) throws RiceIllegalArgumentException, RiceIllegalStateException {
1250         incomingParamCheck(ethnicity, "ethnicity");
1251 
1252         if (StringUtils.isEmpty(ethnicity.getEntityId()) || StringUtils.isBlank(ethnicity.getEntityId())) {
1253             throw new RiceIllegalStateException("Ethnicity's entityId must be populated before creation");
1254         }  else {
1255             if (StringUtils.isEmpty(ethnicity.getId()) || getEntityEthnicityBo(ethnicity.getId()) == null) {
1256                 throw new RiceIllegalStateException("the EntityEthnicity to update does not exist: " + ethnicity);
1257             }
1258         }
1259         EntityEthnicityBo bo = EntityEthnicityBo.from(ethnicity);
1260         return EntityEthnicityBo.to(businessObjectService.save(bo));
1261     }
1262 
1263     private EntityResidencyBo getEntityResidencyBo(String residencyId) {
1264         if (StringUtils.isEmpty(residencyId)) {
1265             return null;
1266         }
1267         Map<String,Object> criteria = new HashMap<String,Object>();
1268         criteria.put(KIMPropertyConstants.Entity.ID, residencyId);
1269         return businessObjectService.findByPrimaryKey(EntityResidencyBo.class, criteria);
1270     }
1271 
1272     @Override
1273     public EntityResidency addResidencyToEntity(EntityResidency residency) throws RiceIllegalArgumentException, RiceIllegalStateException {
1274         incomingParamCheck(residency, "residency");
1275 
1276         if (StringUtils.isEmpty(residency.getEntityId()) || StringUtils.isBlank(residency.getEntityId())) {
1277             throw new RiceIllegalStateException("Residency's entityId must be populated before creation");
1278         }  else {
1279             if (StringUtils.isNotEmpty(residency.getId()) && getEntityResidencyBo(residency.getId()) != null) {
1280                 throw new RiceIllegalStateException("the EntityResidency to create already exists: " + residency);
1281             }
1282         }
1283         EntityResidencyBo bo = EntityResidencyBo.from(residency);
1284         return EntityResidencyBo.to(businessObjectService.save(bo));
1285     }
1286 
1287     @Override
1288     public EntityResidency updateResidency(EntityResidency residency) throws RiceIllegalArgumentException, RiceIllegalStateException {
1289         incomingParamCheck(residency, "residency");
1290 
1291         if (StringUtils.isEmpty(residency.getEntityId()) || StringUtils.isBlank(residency.getEntityId())) {
1292             throw new RiceIllegalStateException("Residency's entityId must be populated before creation");
1293         }  else {
1294             if (StringUtils.isEmpty(residency.getId()) || getEntityResidencyBo(residency.getId()) == null) {
1295                 throw new RiceIllegalStateException("the EntityResidency to update does not exist: " + residency);
1296             }
1297         }
1298         EntityResidencyBo bo = EntityResidencyBo.from(residency);
1299         return EntityResidencyBo.to(businessObjectService.save(bo));
1300     }
1301 
1302     private EntityVisaBo getEntityVisaBo(String visaId) {
1303         if (StringUtils.isEmpty(visaId)) {
1304             return null;
1305         }
1306         Map<String,Object> criteria = new HashMap<String,Object>();
1307         criteria.put(KIMPropertyConstants.Entity.ID, visaId);
1308         return businessObjectService.findByPrimaryKey(EntityVisaBo.class, criteria);
1309     }
1310 
1311     @Override
1312     public EntityVisa addVisaToEntity(EntityVisa visa) throws RiceIllegalArgumentException, RiceIllegalStateException {
1313         incomingParamCheck(visa, "visa");
1314 
1315         if (StringUtils.isEmpty(visa.getEntityId()) || StringUtils.isBlank(visa.getEntityId())) {
1316             throw new RiceIllegalStateException("Visa's entityId must be populated before creation");
1317         }  else {
1318             if (StringUtils.isNotEmpty(visa.getId()) && getEntityVisaBo(visa.getId()) != null) {
1319                 throw new RiceIllegalStateException("the EntityVisa to create already exists: " + visa);
1320             }
1321         }
1322         EntityVisaBo bo = EntityVisaBo.from(visa);
1323         return EntityVisaBo.to(businessObjectService.save(bo));
1324     }
1325 
1326     @Override
1327     public EntityVisa updateVisa(EntityVisa visa) throws RiceIllegalArgumentException, RiceIllegalStateException {
1328         incomingParamCheck(visa, "visa");
1329 
1330         if (StringUtils.isEmpty(visa.getEntityId()) || StringUtils.isBlank(visa.getEntityId())) {
1331             throw new RiceIllegalStateException("Visa's entityId must be populated before creation");
1332         }  else {
1333             if (StringUtils.isEmpty(visa.getId()) || getEntityVisaBo(visa.getId()) == null) {
1334                 throw new RiceIllegalStateException("the EntityVisa to update does not exist: " + visa);
1335             }
1336         }
1337         EntityVisaBo bo = EntityVisaBo.from(visa);
1338         return EntityVisaBo.to(businessObjectService.save(bo));
1339     }
1340 
1341     private EntityNameBo getEntityNameBo(String entityId, String nameTypeCode) {
1342         if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(nameTypeCode)) {
1343             return null;
1344         }
1345         Map<String,Object> criteria = new HashMap<String,Object>();
1346         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1347         criteria.put("nameCode", nameTypeCode);
1348         criteria.put(KIMPropertyConstants.Entity.ACTIVE, "Y");
1349         return businessObjectService.findByPrimaryKey(EntityNameBo.class, criteria);
1350     }
1351 
1352     private EntityNameBo getEntityNameBo(String id) {
1353         if (StringUtils.isEmpty(id)) {
1354             return null;
1355         }
1356         Map<String,Object> criteria = new HashMap<String,Object>();
1357         criteria.put(KIMPropertyConstants.Entity.ID, id);
1358         criteria.put(KIMPropertyConstants.Entity.ACTIVE, "Y");
1359         return businessObjectService.findByPrimaryKey(EntityNameBo.class, criteria);
1360     }
1361     
1362     @Override
1363     public EntityNamePrincipalName getDefaultNamesForPrincipalId(String principalId) {
1364     	EntityNamePrincipalName.Builder nameBuilder = EntityNamePrincipalName.Builder.create();
1365     	Map<String,String> criteria = new HashMap<String,String>();
1366     	criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
1367     	PrincipalBo principal = (PrincipalBo) businessObjectService.findByPrimaryKey(PrincipalBo.class, criteria);
1368 
1369     	if (null != principal) {
1370     		nameBuilder.setPrincipalName(principal.getPrincipalName());
1371 
1372     		criteria.clear();
1373     		criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, principal.getEntityId());
1374     		criteria.put("DFLT_IND", "Y");
1375     		criteria.put("ACTV_IND", "Y");
1376     		EntityNameBo name = (EntityNameBo) businessObjectService.findByPrimaryKey(EntityNameBo.class, criteria);
1377 
1378     		if (name == null) {
1379     			// to make this simple for now, assume if there is no default name that this is a system entity we are dealing with here
1380     			EntityName.Builder defaultNameBuilder = EntityName.Builder.create();
1381     			defaultNameBuilder.setLastName(principal.getPrincipalName().toUpperCase());
1382     			nameBuilder.setDefaultName(defaultNameBuilder);
1383     		} else {
1384     			nameBuilder.setDefaultName( EntityName.Builder.create(name) );
1385     		}
1386     		EntityNamePrincipalName entityNamePrincipalName = nameBuilder.build(); 
1387     		return entityNamePrincipalName;
1388     	}
1389     	return null;
1390     }
1391 
1392     @Override
1393     public EntityName addNameToEntity(EntityName name) throws RiceIllegalArgumentException, RiceIllegalStateException {
1394         incomingParamCheck(name, "name");
1395 
1396         if (StringUtils.isEmpty(name.getEntityId()) || StringUtils.isBlank(name.getEntityId())) {
1397             throw new RiceIllegalStateException("Name's entityId must be populated before creation");
1398         }  else {
1399             if (name.getNameType() == null) {
1400                 throw new RiceIllegalStateException("EntityName's type must be populated before creation");
1401             }
1402             if (getEntityNameBo(name.getEntityId(), name.getNameType().getCode()) != null) {
1403                 throw new RiceIllegalStateException("the EntityName to create already exists: " + name);
1404             }
1405         }
1406         EntityNameBo bo = EntityNameBo.from(name);
1407         return EntityNameBo.to(businessObjectService.save(bo));
1408     }
1409 
1410     @Override
1411     public EntityName updateName(EntityName name) throws RiceIllegalArgumentException, RiceIllegalStateException {
1412         incomingParamCheck(name, "name");
1413 
1414         if (StringUtils.isEmpty(name.getEntityId()) || StringUtils.isBlank(name.getEntityId())) {
1415             throw new RiceIllegalStateException("Name's entityId must be populated before update");
1416         }  else {
1417             if (name.getNameType() == null) {
1418                 throw new RiceIllegalStateException("EntityName's type must be populated before update");
1419             }
1420             if (StringUtils.isEmpty(name.getId()) || getEntityNameBo(name.getId()) == null) {
1421                 throw new RiceIllegalStateException("the EntityName to update does not exist: " + name);
1422             }
1423         }
1424         EntityNameBo bo = EntityNameBo.from(name);
1425         return EntityNameBo.to(businessObjectService.save(bo));
1426     }
1427 
1428     @Override
1429     public EntityName inactivateName(String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1430         incomingParamCheck(id, "id");
1431 
1432         EntityNameBo bo = getEntityNameBo(id);
1433         if (bo == null) {
1434             throw new RiceIllegalStateException("the EntityName to inactivate does not exist");
1435         }
1436 
1437         bo.setActive(false);
1438         return EntityNameBo.to(businessObjectService.save(bo));
1439     }
1440 
1441     private EntityEmploymentBo getEntityEmploymentBo(String entityId, String employmentTypeCode,
1442                         String employmentStatusCode, String employmentAffiliationId) {
1443         if (StringUtils.isEmpty(entityId) || StringUtils.isEmpty(employmentTypeCode)
1444                 || StringUtils.isEmpty(employmentStatusCode) || StringUtils.isEmpty(employmentAffiliationId)) {
1445             return null;
1446         }
1447         Map<String,Object> criteria = new HashMap<String,Object>();
1448         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1449         criteria.put("employeeTypeCode", employmentTypeCode);
1450         criteria.put("employeeStatusCode", employmentStatusCode);
1451         criteria.put("entityAffiliationId", employmentAffiliationId);
1452         criteria.put(KIMPropertyConstants.Entity.ACTIVE, "Y");
1453         return businessObjectService.findByPrimaryKey(EntityEmploymentBo.class, criteria);
1454     }
1455 
1456     private EntityEmploymentBo getEntityEmploymentBo(String id) {
1457         if (StringUtils.isEmpty(id)) {
1458             return null;
1459         }
1460         Map<String,Object> criteria = new HashMap<String,Object>();
1461         criteria.put(KIMPropertyConstants.Entity.ID, id);
1462         criteria.put(KIMPropertyConstants.Entity.ACTIVE, "Y");
1463         return businessObjectService.findByPrimaryKey(EntityEmploymentBo.class, criteria);
1464     }
1465     @Override
1466     public EntityEmployment addEmploymentToEntity(EntityEmployment employment) throws RiceIllegalArgumentException, RiceIllegalStateException {
1467         incomingParamCheck(employment, "employment");
1468 
1469         if (StringUtils.isEmpty(employment.getEntityId()) || StringUtils.isBlank(employment.getEntityId())) {
1470             throw new RiceIllegalStateException("EntityEmployment's entityId must be populated before creation");
1471         }  else {
1472             if (employment.getEmployeeType() == null
1473                     || employment.getEmployeeStatus() == null
1474                     || employment.getEntityAffiliation() == null) {
1475                 throw new RiceIllegalStateException("EntityEmployment's status, type, and entity affiliation must be populated before creation");
1476             }
1477             if (getEntityEmploymentBo(employment.getEntityId(), employment.getEmployeeType().getCode(), employment.getEmployeeStatus().getCode(), employment.getEntityAffiliation().getId()) != null) {
1478                 throw new RiceIllegalStateException("the EntityEmployment to create already exists: " + employment);
1479             }
1480         }
1481         EntityEmploymentBo bo = EntityEmploymentBo.from(employment);
1482         return EntityEmploymentBo.to(businessObjectService.save(bo));
1483     }
1484 
1485     @Override
1486     public EntityEmployment updateEmployment(EntityEmployment employment) throws RiceIllegalArgumentException, RiceIllegalStateException {
1487         incomingParamCheck(employment, "employment");
1488 
1489         if (StringUtils.isEmpty(employment.getEntityId()) || StringUtils.isBlank(employment.getEntityId())) {
1490             throw new RiceIllegalStateException("EntityEmployment's entityId must be populated before update");
1491         }  else {
1492             if (employment.getEmployeeType() == null
1493                     || employment.getEmployeeStatus() == null
1494                     || employment.getEntityAffiliation() == null) {
1495                 throw new RiceIllegalStateException("EntityEmployment's status, type, and entity affiliation must be populated before update");
1496             }
1497             if (getEntityEmploymentBo(employment.getEntityId(), employment.getEmployeeType().getCode(), employment.getEmployeeStatus().getCode(), employment.getEntityAffiliation().getId()) == null) {
1498                 throw new RiceIllegalStateException("the EntityEmployment to udpate does not exist: " + employment);
1499             }
1500         }
1501         EntityEmploymentBo bo = EntityEmploymentBo.from(employment);
1502         return EntityEmploymentBo.to(businessObjectService.save(bo));
1503     }
1504 
1505     @Override
1506     public EntityEmployment inactivateEmployment(String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
1507         incomingParamCheck(id, "id");
1508 
1509         EntityEmploymentBo bo = getEntityEmploymentBo(id);
1510         if (bo == null) {
1511             throw new RiceIllegalStateException("the EntityEmployment to inactivate does not exist");
1512         }
1513         bo.setActive(false);
1514         return EntityEmploymentBo.to(businessObjectService.save(bo));
1515     }
1516 
1517 	private EntityBioDemographicsBo getEntityBioDemographicsBo(String entityId) {
1518         if (StringUtils.isEmpty(entityId)) {
1519             return null;
1520         }
1521 		Map<String,String> criteria = new HashMap<String,String>(1);
1522         criteria.put(KIMPropertyConstants.Entity.ENTITY_ID, entityId);
1523 		return businessObjectService.findByPrimaryKey(EntityBioDemographicsBo.class, criteria);
1524 	}
1525 
1526     @Override
1527     public EntityBioDemographics addBioDemographicsToEntity(EntityBioDemographics bioDemographics) throws RiceIllegalArgumentException, RiceIllegalStateException {
1528         incomingParamCheck(bioDemographics, "bioDemographics");
1529 
1530         if (StringUtils.isEmpty(bioDemographics.getEntityId()) || StringUtils.isBlank(bioDemographics.getEntityId())) {
1531             throw new RiceIllegalStateException("BioDemographics' entityId must be populated before creation");
1532         }  else {
1533             if (getEntityBioDemographicsBo(bioDemographics.getEntityId()) != null) {
1534                 throw new RiceIllegalStateException("the EntityBioDemographics to create already exists: " + bioDemographics);
1535             }
1536         }
1537         EntityBioDemographicsBo bo = EntityBioDemographicsBo.from(bioDemographics);
1538         return EntityBioDemographicsBo.to(businessObjectService.save(bo));
1539     }
1540 
1541     @Override
1542     public EntityBioDemographics updateBioDemographics(EntityBioDemographics bioDemographics) throws RiceIllegalArgumentException, RiceIllegalStateException {
1543         incomingParamCheck(bioDemographics, "bioDemographics");
1544 
1545         if (getEntityBioDemographicsBo(bioDemographics.getEntityId()) == null) {
1546             throw new RiceIllegalStateException("the EntityBioDemographics to update does not exist: " + bioDemographics);
1547         }
1548         EntityBioDemographicsBo bo = EntityBioDemographicsBo.from(bioDemographics);
1549         return EntityBioDemographicsBo.to(businessObjectService.save(bo));
1550     }
1551 
1552 
1553     public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
1554         this.criteriaLookupService = criteriaLookupService;
1555     }
1556 
1557     public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
1558         this.businessObjectService = businessObjectService;
1559     }
1560 
1561     private void incomingParamCheck(Object object, String name) {
1562         if (object == null) {
1563             throw new RiceIllegalArgumentException(name + " was null");
1564         } else if (object instanceof String
1565                 && StringUtils.isBlank((String) object)) {
1566             throw new RiceIllegalArgumentException(name + " was blank");
1567         }
1568     }
1569 }