001    /**
002     * Copyright 2005-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kim.impl.identity;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.criteria.CriteriaLookupService;
020    import org.kuali.rice.core.api.criteria.GenericQueryResults;
021    import org.kuali.rice.core.api.criteria.QueryByCriteria;
022    import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
023    import org.kuali.rice.core.api.exception.RiceIllegalStateException;
024    import org.kuali.rice.kim.api.identity.CodedAttribute;
025    import org.kuali.rice.kim.api.identity.IdentityService;
026    import org.kuali.rice.kim.api.identity.address.EntityAddress;
027    import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
028    import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliationType;
029    import org.kuali.rice.kim.api.identity.citizenship.EntityCitizenship;
030    import org.kuali.rice.kim.api.identity.email.EntityEmail;
031    import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
032    import org.kuali.rice.kim.api.identity.entity.Entity;
033    import org.kuali.rice.kim.api.identity.entity.EntityDefault;
034    import org.kuali.rice.kim.api.identity.entity.EntityDefaultQueryResults;
035    import org.kuali.rice.kim.api.identity.entity.EntityQueryResults;
036    import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifier;
037    import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierType;
038    import org.kuali.rice.kim.api.identity.name.EntityName;
039    import org.kuali.rice.kim.api.identity.name.EntityNameQueryResults;
040    import org.kuali.rice.kim.api.identity.personal.EntityBioDemographics;
041    import org.kuali.rice.kim.api.identity.personal.EntityEthnicity;
042    import org.kuali.rice.kim.api.identity.phone.EntityPhone;
043    import org.kuali.rice.kim.api.identity.principal.Principal;
044    import org.kuali.rice.kim.api.identity.principal.PrincipalQueryResults;
045    import org.kuali.rice.kim.api.identity.privacy.EntityPrivacyPreferences;
046    import org.kuali.rice.kim.api.identity.residency.EntityResidency;
047    import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
048    import org.kuali.rice.kim.api.identity.visa.EntityVisa;
049    import org.kuali.rice.kim.impl.KIMPropertyConstants;
050    import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
051    import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
052    import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
053    import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
054    import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipBo;
055    import org.kuali.rice.kim.impl.identity.citizenship.EntityCitizenshipStatusBo;
056    import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
057    import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
058    import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
059    import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
060    import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
061    import org.kuali.rice.kim.impl.identity.entity.EntityBo;
062    import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierBo;
063    import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierTypeBo;
064    import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
065    import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
066    import org.kuali.rice.kim.impl.identity.personal.EntityBioDemographicsBo;
067    import org.kuali.rice.kim.impl.identity.personal.EntityEthnicityBo;
068    import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
069    import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
070    import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
071    import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
072    import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
073    import org.kuali.rice.kim.impl.identity.residency.EntityResidencyBo;
074    import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
075    import org.kuali.rice.kim.impl.identity.visa.EntityVisaBo;
076    import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
077    import org.kuali.rice.krad.service.BusinessObjectService;
078    
079    import javax.jws.WebParam;
080    import java.util.ArrayList;
081    import java.util.Collection;
082    import java.util.Collections;
083    import java.util.HashMap;
084    import java.util.List;
085    import java.util.Map;
086    
087    /**
088     * Base implementation of the identity (identity) service.  This version assumes the KimEntity
089     * and related data is located within the KIM database. 
090     * 
091     * @author Kuali Rice Team (rice.collab@kuali.org)
092     */
093    
094    public class IdentityServiceImpl implements IdentityService {
095    
096        private CriteriaLookupService criteriaLookupService;
097            private BusinessObjectService businessObjectService;
098    
099        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    }