View Javadoc

1   /**
2    * Copyright 2005-2014 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.service.impl;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.log4j.Logger;
21  import org.joda.time.DateTime;
22  import org.kuali.rice.core.api.config.property.ConfigContext;
23  import org.kuali.rice.core.api.criteria.Predicate;
24  import org.kuali.rice.core.api.criteria.PredicateUtils;
25  import org.kuali.rice.core.api.criteria.QueryByCriteria;
26  import org.kuali.rice.core.api.membership.MemberType;
27  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
28  import org.kuali.rice.coreservice.api.parameter.Parameter;
29  import org.kuali.rice.core.api.uif.RemotableCheckbox;
30  import org.kuali.rice.core.api.uif.RemotableCheckboxGroup;
31  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
32  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
33  import org.kuali.rice.kim.api.KimConstants;
34  import org.kuali.rice.kim.api.KimConstants.KimGroupMemberTypes;
35  import org.kuali.rice.kim.api.group.Group;
36  import org.kuali.rice.kim.api.group.GroupMember;
37  import org.kuali.rice.kim.api.group.GroupService;
38  import org.kuali.rice.kim.api.identity.IdentityService;
39  import org.kuali.rice.kim.api.identity.Person;
40  import org.kuali.rice.kim.api.identity.address.EntityAddress;
41  import org.kuali.rice.kim.api.identity.address.EntityAddressContract;
42  import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation;
43  import org.kuali.rice.kim.api.identity.email.EntityEmail;
44  import org.kuali.rice.kim.api.identity.email.EntityEmailContract;
45  import org.kuali.rice.kim.api.identity.employment.EntityEmployment;
46  import org.kuali.rice.kim.api.identity.entity.Entity;
47  import org.kuali.rice.kim.api.identity.entity.EntityDefault;
48  import org.kuali.rice.kim.api.identity.name.EntityName;
49  import org.kuali.rice.kim.api.identity.phone.EntityPhone;
50  import org.kuali.rice.kim.api.identity.phone.EntityPhoneContract;
51  import org.kuali.rice.kim.api.identity.principal.Principal;
52  import org.kuali.rice.kim.api.identity.privacy.EntityPrivacyPreferences;
53  import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo;
54  import org.kuali.rice.kim.api.permission.PermissionService;
55  import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
56  import org.kuali.rice.kim.api.role.Role;
57  import org.kuali.rice.kim.api.role.RoleMember;
58  import org.kuali.rice.kim.api.role.RoleService;
59  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
60  import org.kuali.rice.kim.api.type.KimAttributeField;
61  import org.kuali.rice.kim.api.type.KimType;
62  import org.kuali.rice.kim.api.type.KimTypeAttribute;
63  import org.kuali.rice.kim.api.type.KimTypeInfoService;
64  import org.kuali.rice.kim.bo.ui.GroupDocumentMember;
65  import org.kuali.rice.kim.bo.ui.GroupDocumentQualifier;
66  import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
67  import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission;
68  import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
69  import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility;
70  import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibilityAction;
71  import org.kuali.rice.kim.bo.ui.PersonDocumentAddress;
72  import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
73  import org.kuali.rice.kim.bo.ui.PersonDocumentEmail;
74  import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
75  import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
76  import org.kuali.rice.kim.bo.ui.PersonDocumentName;
77  import org.kuali.rice.kim.bo.ui.PersonDocumentPhone;
78  import org.kuali.rice.kim.bo.ui.PersonDocumentPrivacy;
79  import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
80  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegation;
81  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
82  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
83  import org.kuali.rice.kim.document.IdentityManagementGroupDocument;
84  import org.kuali.rice.kim.document.IdentityManagementPersonDocument;
85  import org.kuali.rice.kim.document.IdentityManagementRoleDocument;
86  import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator;
87  import org.kuali.rice.kim.framework.type.KimTypeService;
88  import org.kuali.rice.kim.impl.KIMPropertyConstants;
89  import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
90  import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo;
91  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberAttributeDataBo;
92  import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
93  import org.kuali.rice.kim.impl.group.GroupAttributeBo;
94  import org.kuali.rice.kim.impl.group.GroupBo;
95  import org.kuali.rice.kim.impl.group.GroupMemberBo;
96  import org.kuali.rice.kim.impl.identity.IdentityArchiveService;
97  import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
98  import org.kuali.rice.kim.impl.identity.address.EntityAddressTypeBo;
99  import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
100 import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationTypeBo;
101 import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
102 import org.kuali.rice.kim.impl.identity.email.EntityEmailTypeBo;
103 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
104 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentStatusBo;
105 import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentTypeBo;
106 import org.kuali.rice.kim.impl.identity.entity.EntityBo;
107 import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
108 import org.kuali.rice.kim.impl.identity.name.EntityNameTypeBo;
109 import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
110 import org.kuali.rice.kim.impl.identity.phone.EntityPhoneTypeBo;
111 import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
112 import org.kuali.rice.kim.impl.identity.privacy.EntityPrivacyPreferencesBo;
113 import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
114 import org.kuali.rice.kim.impl.permission.PermissionBo;
115 import org.kuali.rice.kim.impl.responsibility.ResponsibilityInternalService;
116 import org.kuali.rice.kim.impl.role.RoleBo;
117 import org.kuali.rice.kim.impl.role.RoleBoLite;
118 import org.kuali.rice.kim.impl.role.RoleMemberAttributeDataBo;
119 import org.kuali.rice.kim.impl.role.RoleMemberBo;
120 import org.kuali.rice.kim.impl.role.RolePermissionBo;
121 import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo;
122 import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
123 import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
124 import org.kuali.rice.kim.impl.type.KimTypeBo;
125 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
126 import org.kuali.rice.kim.service.UiDocumentService;
127 import org.kuali.rice.kim.service.dao.UiDocumentServiceDAO;
128 import org.kuali.rice.kim.util.KimCommonUtilsInternal;
129 import org.kuali.rice.kns.datadictionary.exporter.AttributesMapBuilder;
130 import org.kuali.rice.kns.kim.type.DataDictionaryTypeServiceHelper;
131 import org.kuali.rice.kns.service.DocumentHelperService;
132 import org.kuali.rice.kns.service.KNSServiceLocator;
133 import org.kuali.rice.krad.bo.BusinessObject;
134 import org.kuali.rice.krad.bo.PersistableBusinessObject;
135 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
136 import org.kuali.rice.krad.datadictionary.exporter.ExportMap;
137 import org.kuali.rice.krad.document.Document;
138 import org.kuali.rice.krad.service.BusinessObjectService;
139 import org.kuali.rice.krad.service.KRADServiceLocator;
140 import org.kuali.rice.krad.util.KRADConstants;
141 import org.kuali.rice.krad.util.ObjectUtils;
142 
143 import java.sql.Timestamp;
144 import java.util.ArrayList;
145 import java.util.Collection;
146 import java.util.Collections;
147 import java.util.Comparator;
148 import java.util.HashMap;
149 import java.util.HashSet;
150 import java.util.List;
151 import java.util.Map;
152 import java.util.Set;
153 
154 import javax.xml.namespace.QName;
155 
156 /**
157  * This is a description of what this class does - shyu don't forget to fill this in.
158  *
159  * @author Kuali Rice Team (rice.collab@kuali.org)
160  *
161  */
162 public class UiDocumentServiceImpl implements UiDocumentService {
163 	private static final Logger LOG = Logger.getLogger(UiDocumentServiceImpl.class);
164 	private static final String SHOW_BLANK_QUALIFIERS = "kim.show.blank.qualifiers";
165     private static final String KIM_IDENTITY_ARCHIVE_SERVICE = "kimIdentityArchiveService";
166 
167     private IdentityArchiveService identityArchiveService;
168     private RoleService roleService;
169 	private BusinessObjectService businessObjectService;
170 	private IdentityService identityService;
171     private PermissionService permissionService;
172 	private GroupService groupService;
173 	private ResponsibilityService responsibilityService;
174     private ResponsibilityInternalService responsibilityInternalService;
175 	private KimTypeInfoService kimTypeInfoService;
176     private DocumentHelperService documentHelperService;
177     private ParameterService parameterService;
178     private UiDocumentServiceDAO uiDocumentServiceDAO;
179 
180     /**
181 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
182 	 */
183 	public void saveEntityPerson(
184 	    IdentityManagementPersonDocument identityManagementPersonDocument) {
185 		EntityBo kimEntity = new EntityBo();
186 		EntityBo origEntity = getEntityBo(identityManagementPersonDocument.getEntityId());
187 		boolean creatingNew = true;
188 		if (origEntity == null) {
189 			origEntity = new EntityBo();
190 			kimEntity.setActive(true);
191 		} else {
192 			// TODO : in order to resolve optimistic locking issue. has to get identity and set the version number if identity records matched
193 			// Need to look into this.
194 			//kimEntity = origEntity;
195 			kimEntity.setActive(origEntity.isActive());
196 			kimEntity.setVersionNumber(origEntity.getVersionNumber());
197 			creatingNew = false;
198 		}
199 
200 		kimEntity.setId(identityManagementPersonDocument.getEntityId());
201 		String initiatorPrincipalId = getInitiatorPrincipalId(identityManagementPersonDocument);
202 		boolean inactivatingPrincipal = false;
203 		if(canModifyEntity(initiatorPrincipalId, identityManagementPersonDocument.getPrincipalId())){
204 			inactivatingPrincipal = setupPrincipal(identityManagementPersonDocument, kimEntity, origEntity.getPrincipals());
205 			setupAffiliation(identityManagementPersonDocument, kimEntity, origEntity.getAffiliations(), origEntity.getEmploymentInformation());
206 			setupName(identityManagementPersonDocument, kimEntity, origEntity.getNames());
207 		// entitytype
208 			List<EntityTypeContactInfoBo> entityTypes = new ArrayList<EntityTypeContactInfoBo>();
209 			EntityTypeContactInfoBo entityType = new EntityTypeContactInfoBo();
210 			entityType.setEntityId(identityManagementPersonDocument.getEntityId());
211 			entityType.setEntityTypeCode(KimConstants.EntityTypes.PERSON);
212 			entityType.setActive(true);
213 			entityTypes.add(entityType);
214 			EntityTypeContactInfoBo origEntityType = new EntityTypeContactInfoBo();
215 			for (EntityTypeContactInfoBo type : origEntity.getEntityTypeContactInfos()) {
216 				// should check identity.entitytypeid, but it's not persist in persondoc yet
217 				if (type.getEntityTypeCode()!=null && StringUtils.equals(type.getEntityTypeCode(), entityType.getEntityTypeCode())) {
218 					origEntityType = type;
219 					entityType.setVersionNumber(type.getVersionNumber());
220 					entityType.setActive(type.isActive());
221 				}
222 			}
223 			setupPhone(identityManagementPersonDocument, entityType, origEntityType.getPhoneNumbers());
224 			setupEmail(identityManagementPersonDocument, entityType, origEntityType.getEmailAddresses());
225 			setupAddress(identityManagementPersonDocument, entityType, origEntityType.getAddresses());
226             kimEntity.setEntityTypeContactInfos(entityTypes);
227 		} else{
228 			if(ObjectUtils.isNotNull(origEntity.getExternalIdentifiers())) {
229                 kimEntity.setExternalIdentifiers(origEntity.getExternalIdentifiers());
230             }
231 			if(ObjectUtils.isNotNull(origEntity.getEmploymentInformation())) {
232                 kimEntity.setEmploymentInformation(origEntity.getEmploymentInformation());
233             }
234 			if(ObjectUtils.isNotNull(origEntity.getAffiliations())) {
235                 kimEntity.setAffiliations(origEntity.getAffiliations());
236             }
237 			if(ObjectUtils.isNotNull(origEntity.getNames())) {
238                 kimEntity.setNames(origEntity.getNames());
239             }
240 			if(ObjectUtils.isNotNull(origEntity.getEntityTypeContactInfos())) {
241                 kimEntity.setEntityTypeContactInfos(origEntity.getEntityTypeContactInfos());
242             }
243 		}
244 		if(creatingNew || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId())) {
245 			setupPrivacy(identityManagementPersonDocument, kimEntity, origEntity.getPrivacyPreferences());
246 		} else {
247 			if(ObjectUtils.isNotNull(origEntity.getPrivacyPreferences())) {
248 				kimEntity.setPrivacyPreferences(origEntity.getPrivacyPreferences());
249 			}
250 		}
251 		List <GroupMemberBo>  groupPrincipals = populateGroupMembers(identityManagementPersonDocument);
252 		List <RoleMemberBo>  rolePrincipals = populateRoleMembers(identityManagementPersonDocument);
253 		List <DelegateTypeBo> personDelegations = populateDelegations(identityManagementPersonDocument);
254 		List <PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
255 		List <RoleResponsibilityActionBo> roleRspActions = populateRoleRspActions(identityManagementPersonDocument);
256 		List <RoleMemberAttributeDataBo> blankRoleMemberAttrs = getBlankRoleMemberAttrs(rolePrincipals);
257 		bos.add(kimEntity);
258 		//if(ObjectUtils.isNotNull(kimEntity.getPrivacyPreferences()))
259 		//	bos.add(kimEntity.getPrivacyPreferences());
260 		bos.addAll(groupPrincipals);
261 		bos.addAll(rolePrincipals);
262 		bos.addAll(roleRspActions);
263 		bos.addAll(personDelegations);
264 		// boservice.save(bos) does not handle deleteawarelist
265 		getBusinessObjectService().save(bos);
266 
267 		if (!blankRoleMemberAttrs.isEmpty()) {
268 			getBusinessObjectService().delete(blankRoleMemberAttrs);
269 		}
270 		if ( inactivatingPrincipal ) {
271 			//when a person is inactivated, inactivate their group, role, and delegation memberships
272 			KimImplServiceLocator.getRoleInternalService().principalInactivated(
273                     identityManagementPersonDocument.getPrincipalId());
274 		}
275 	}
276 
277 	private String getInitiatorPrincipalId(Document document){
278 		try{
279 			return document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
280 		} catch(Exception ex){
281 			return null;
282 		}
283 	}
284 
285 	public Map<String,Object> getAttributeEntries( List<KimAttributeField> definitions ) {
286 		final Map<String,Object> attributeEntries = new HashMap<String,Object>();
287 		if (definitions != null) {
288 	        for (AttributeDefinition definition : DataDictionaryTypeServiceHelper.toKimAttributeDefinitions(definitions)) {
289 				final AttributesMapBuilder builder = new AttributesMapBuilder();
290                 final ExportMap map = builder.buildAttributeMap(definition, "");
291                 attributeEntries.put(definition.getName(),map.getExportData());
292 			}
293 		}
294         return attributeEntries;
295 	}
296 
297 
298 	/**
299 	 *
300 	 * @see org.kuali.rice.kim.service.UiDocumentService#loadEntityToPersonDoc(IdentityManagementPersonDocument, String)
301 	 */
302 	public void loadEntityToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId) {
303 		Principal principal = this.getIdentityService().getPrincipal(principalId);
304         Entity kimEntity = null;
305 
306         if(ObjectUtils.isNotNull(principal)) {
307             // If the principal is not null it was found in the identity management service
308             kimEntity = this.getIdentityService().getEntity(principal.getEntityId());
309         }
310 
311         if(ObjectUtils.isNull(principal) || ObjectUtils.isNull(kimEntity)) {
312             // If the principal or entity is null look up the entity in the
313             // archive service, and then get the principal from it
314             IdentityArchiveService identityArchive = getIdentityArchiveService();
315             EntityDefault entityInfo = identityArchive.getEntityDefaultFromArchiveByPrincipalId(principalId);
316             principal = entityInfo.getPrincipals().get(0);
317             Entity.Builder eb  = Entity.Builder.create();
318             eb.setId(entityInfo.getEntityId());
319             kimEntity = eb.build();
320 
321         }
322         if(kimEntity == null) {
323             throw new RuntimeException("Entity does not exist for principal id: " + principalId);
324         }
325         if(principal==null) {
326         	throw new RuntimeException("Principal does not exist for principal id:"+principalId);
327         }
328 
329         identityManagementPersonDocument.setPrincipalId(principal.getPrincipalId());
330         identityManagementPersonDocument.setPrincipalName(principal.getPrincipalName());
331         //identityManagementPersonDocument.setPassword(principal.getPassword());
332         identityManagementPersonDocument.setActive(principal.isActive());
333 		identityManagementPersonDocument.setEntityId(kimEntity.getId());
334 		if ( ObjectUtils.isNotNull( kimEntity.getPrivacyPreferences() ) ) {
335 			identityManagementPersonDocument.setPrivacy(loadPrivacyReferences(kimEntity.getPrivacyPreferences()));
336 		}
337 		//identityManagementPersonDocument.setActive(kimEntity.isActive());
338 		identityManagementPersonDocument.setAffiliations(loadAffiliations(kimEntity.getAffiliations(),kimEntity.getEmploymentInformation()));
339 		identityManagementPersonDocument.setNames(loadNames( identityManagementPersonDocument, principalId, kimEntity.getNames(), identityManagementPersonDocument.getPrivacy().isSuppressName() ));
340 		EntityTypeContactInfo entityType = null;
341 		for (EntityTypeContactInfo type : kimEntity.getEntityTypeContactInfos()) {
342 			if (KimConstants.EntityTypes.PERSON.equals(type.getEntityTypeCode())) {
343 				entityType = EntityTypeContactInfo.Builder.create(type).build();
344 			}
345 		}
346 
347 		if(entityType!=null){
348 			identityManagementPersonDocument.setEmails(loadEmails(identityManagementPersonDocument, principalId, entityType.getEmailAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressEmail()));
349 			identityManagementPersonDocument.setPhones(loadPhones(identityManagementPersonDocument, principalId, entityType.getPhoneNumbers(), identityManagementPersonDocument.getPrivacy().isSuppressPhone()));
350 			identityManagementPersonDocument.setAddrs(loadAddresses(identityManagementPersonDocument, principalId, entityType.getAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressAddress()));
351 		}
352 
353 		List<Group> groups = getGroupService().getGroups(getGroupService().getDirectGroupIdsByPrincipalId(
354                 identityManagementPersonDocument.getPrincipalId()));
355 		loadGroupToPersonDoc(identityManagementPersonDocument, groups);
356 		loadRoleToPersonDoc(identityManagementPersonDocument);
357 		loadDelegationsToPersonDoc(identityManagementPersonDocument);
358 	}
359 
360     @SuppressWarnings("unchecked")
361 	public List<DelegateTypeBo> getPersonDelegations(String principalId){
362 		if(principalId==null) {
363 			return new ArrayList<DelegateTypeBo>();
364         }
365 		Map<String,String> criteria = new HashMap<String,String>(1);
366 		criteria.put(KimConstants.PrimaryKeyConstants.MEMBER_ID, principalId);
367 		criteria.put( KIMPropertyConstants.DelegationMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode() );
368 		List<DelegateMemberBo> delegationMembers = (List<DelegateMemberBo>)getBusinessObjectService().findMatching(DelegateMemberBo.class, criteria);
369 		List<DelegateTypeBo> delegations = new ArrayList<DelegateTypeBo>();
370 		List<String> delegationIds = new ArrayList<String>();
371 		if(ObjectUtils.isNotNull(delegationMembers)){
372 			for(DelegateMemberBo delegationMember: delegationMembers){
373 				if(!delegationIds.contains(delegationMember.getDelegationId())){
374 					delegationIds.add(delegationMember.getDelegationId());
375 					criteria = new HashMap<String,String>(1);
376 					criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationMember.getDelegationId());
377 					delegations.add(getBusinessObjectService().findByPrimaryKey(DelegateTypeBo.class, criteria));
378 				}
379 			}
380 		}
381 		return delegations;
382 	}
383 
384 
385     protected void loadDelegationsToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument){
386 		List<RoleDocumentDelegation> delList = new ArrayList<RoleDocumentDelegation>();
387 		RoleDocumentDelegation documentDelegation;
388 		List<DelegateTypeBo> origDelegations = getPersonDelegations(identityManagementPersonDocument.getPrincipalId());
389 		if(ObjectUtils.isNotNull(origDelegations)){
390 			for(DelegateTypeBo del: origDelegations){
391 				if(del.isActive()){
392 					documentDelegation = new RoleDocumentDelegation();
393 					documentDelegation.setActive(del.isActive());
394 					documentDelegation.setDelegationId(del.getDelegationId());
395 					documentDelegation.setDelegationTypeCode(del.getDelegationTypeCode());
396 					documentDelegation.setKimTypeId(del.getKimTypeId());
397 					documentDelegation.setMembers(
398 							loadDelegationMembers(identityManagementPersonDocument,
399 									del.getMembers(), (RoleBo)getMember(MemberType.ROLE, del.getRoleId())));
400 					documentDelegation.setRoleId(del.getRoleId());
401 					documentDelegation.setEdit(true);
402 					delList.add(documentDelegation);
403 				}
404 			}
405 		}
406 		identityManagementPersonDocument.setDelegations(delList);
407 		setDelegationMembersInDocument(identityManagementPersonDocument);
408 	}
409 
410 	public void setDelegationMembersInDocument(IdentityManagementPersonDocument identityManagementPersonDocument){
411 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getDelegations())){
412 			for(RoleDocumentDelegation delegation: identityManagementPersonDocument.getDelegations()){
413 				if(CollectionUtils.isNotEmpty(delegation.getMembers())){
414 					for(RoleDocumentDelegationMember member: delegation.getMembers()){
415 						if (StringUtils.equals(member.getMemberId(), identityManagementPersonDocument.getPrincipalId()))
416 						{
417 						    member.setDelegationTypeCode(delegation.getDelegationTypeCode());
418 						    identityManagementPersonDocument.getDelegationMembers().add(member);
419 						}
420 					}
421 				}
422 			}
423 		}
424 	}
425 
426     protected List<RoleDocumentDelegationMember> loadDelegationMembers(
427     		IdentityManagementPersonDocument identityManagementPersonDocument, List<DelegateMemberBo> members, RoleBo roleImpl){
428 		List<RoleDocumentDelegationMember> pndMembers = new ArrayList<RoleDocumentDelegationMember>();
429 		RoleDocumentDelegationMember pndMember;
430 		RoleMemberBo roleMember;
431 		if(ObjectUtils.isNotNull(members)){
432 			for(DelegateMemberBo member: members){
433 				pndMember = new RoleDocumentDelegationMember();
434 				pndMember.setActiveFromDate(member.getActiveFromDateValue());
435 				pndMember.setActiveToDate(member.getActiveToDateValue());
436 				pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
437 				pndMember.setRoleBo(roleImpl);
438 				if(pndMember.isActive()){
439                     pndMember.setMemberId(member.getMemberId());
440                     pndMember.setDelegationMemberId(member.getDelegationMemberId());
441                     pndMember.setMemberTypeCode(member.getType().getCode());
442                     pndMember.setDelegationId(member.getDelegationId());
443                     pndMember.setVersionNumber(member.getVersionNumber());
444                     pndMember.setObjectId(member.getObjectId());
445 
446 					pndMember.setRoleMemberId(member.getRoleMemberId());
447 					roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
448 					if(roleMember!=null){
449 						pndMember.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
450 						pndMember.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
451 					}
452 					pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
453 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
454 					pndMember.setEdit(true);
455 					pndMember.setQualifiers(loadDelegationMemberQualifiers(identityManagementPersonDocument, pndMember.getAttributesHelper().getDefinitions(), member.getAttributeDetails()));
456 					pndMembers.add(pndMember);
457 				}
458 			}
459 		}
460 		return pndMembers;
461 	}
462 
463     protected List<RoleDocumentDelegationMemberQualifier> loadDelegationMemberQualifiers(IdentityManagementPersonDocument identityManagementPersonDocument,
464     		List<KimAttributeField> origAttributeDefinitions, List<DelegateMemberAttributeDataBo> attributeDataList){
465 		List<RoleDocumentDelegationMemberQualifier> pndMemberRoleQualifiers = new ArrayList<RoleDocumentDelegationMemberQualifier>();
466 		RoleDocumentDelegationMemberQualifier pndMemberRoleQualifier;
467 		boolean attributePresent = false;
468 		String origAttributeId;
469 		if(origAttributeDefinitions!=null){
470 			for(KimAttributeField key: origAttributeDefinitions) {
471 				origAttributeId = identityManagementPersonDocument.getKimAttributeDefnId(key);
472 				if(ObjectUtils.isNotNull(attributeDataList)){
473 					for(DelegateMemberAttributeDataBo memberRoleQualifier: attributeDataList){
474 						if(StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
475 							pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
476 							pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
477 							pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
478 							pndMemberRoleQualifier.setDelegationMemberId(memberRoleQualifier.getAssignedToId());
479 							pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
480 							pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
481 							pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
482 							pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
483 							attributePresent = true;
484 						}
485 					}
486 				}
487 				if(!attributePresent){
488 					pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
489 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
490 					pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
491 				}
492 				attributePresent = false;
493 			}
494 		}
495 		return pndMemberRoleQualifiers;
496 	}
497 
498 	/**
499 	 *
500      * This method loads related group data to pending person document when user initiates the 'edit' or 'inquiry'.
501      *
502 	 * @param identityManagementPersonDocument
503 	 * @param groups
504 	 */
505     protected void loadGroupToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument, List<? extends Group> groups) {
506         List <PersonDocumentGroup> docGroups = new ArrayList <PersonDocumentGroup>();
507         if(ObjectUtils.isNotNull(groups)){
508             for (Group group: groups) {
509                 if (getGroupService().isDirectMemberOfGroup(identityManagementPersonDocument.getPrincipalId(), group.getId())) {
510                     PersonDocumentGroup docGroup = new PersonDocumentGroup();
511                     docGroup.setGroupId(group.getId());
512                     docGroup.setGroupName(group.getName());
513                     docGroup.setNamespaceCode(group.getNamespaceCode());
514                     docGroup.setPrincipalId(identityManagementPersonDocument.getPrincipalId());
515                     Collection<GroupMember> groupMemberships = null;
516                     groupMemberships = getGroupService().getMembersOfGroup(group.getId());
517 
518                     if(ObjectUtils.isNotNull(groupMemberships)){
519                         for (GroupMember groupMember: groupMemberships) {
520                             if (StringUtils.equals(groupMember.getMemberId(), identityManagementPersonDocument.getPrincipalId()) &&
521                                     KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.equals(groupMember.getType())) {
522                                 docGroup.setGroupMemberId(groupMember.getId());
523                                 if (groupMember.getActiveFromDate() != null) {
524                                     docGroup.setActiveFromDate(groupMember.getActiveFromDate() == null ? null : new Timestamp(groupMember.getActiveFromDate().getMillis()));
525                                 }
526                                 if (groupMember.getActiveToDate() != null) {
527                                     docGroup.setActiveToDate(groupMember.getActiveToDate() == null ? null : new Timestamp(groupMember.getActiveToDate().getMillis()));
528                                 }
529                                 continue;
530                             }
531                         }
532                     }
533                     docGroup.setKimTypeId(group.getKimTypeId());
534                     docGroup.setEdit(true);
535                     docGroups.add(docGroup);
536                 }
537             }
538         }
539         identityManagementPersonDocument.setGroups(docGroups);
540     }
541 
542 	/**
543 	 * Used to populate the {@link PersonDocumentRole} objects for a {@link IdentityManagementPersonDocument}
544 	 *
545 	 * @param identityManagementPersonDocument {@link IdentityManagementPersonDocument}
546 	 */
547     protected void loadRoleToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument) {
548         List <PersonDocumentRole> docRoles = new ArrayList <PersonDocumentRole>();
549         // a list for Id's of the roles added to docRoles
550         List<String> roleIds = new ArrayList<String>();
551 
552         // get the membership objects for the PrincipalId
553         List<RoleMemberBo> roleMembers = getRoleMembersForPrincipal(identityManagementPersonDocument.getPrincipalId());
554 
555         // if the PrincipalId is a member of any roles, add those roles to docRoles
556         if(ObjectUtils.isNotNull(roleMembers)){
557             // for each membership get the role and add it, if not already added
558             for (RoleMemberBo member : roleMembers) {
559 				if(member.isActive() && !roleIds.contains(member.getRoleId())) {
560 					loadDocRoles(docRoles, roleIds, member, roleMembers);
561 				}
562             }
563         }
564 
565         // complete the attributes for each role being being returned
566         for (PersonDocumentRole role : docRoles) {
567             role.setDefinitions(getAttributeDefinitionsForRole(role));
568 
569             KimDocumentRoleMember newRolePrncpl = new KimDocumentRoleMember();
570             newRolePrncpl.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
571             newRolePrncpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
572             role.setNewRolePrncpl(newRolePrncpl);
573 
574             if(role.getDefinitions()!=null){
575                 for (KimAttributeField key : role.getDefinitions()) {
576                     KimDocumentRoleQualifier qualifier = new KimDocumentRoleQualifier();
577                     setAttrDefnIdForQualifier(qualifier,key);
578                     role.getNewRolePrncpl().getQualifiers().add(qualifier);
579                 }
580             }
581 
582             // load the role's ResponsibilityActions
583             loadRoleRstAction(role);
584 
585             role.setAttributeEntry( getAttributeEntries( role.getDefinitions() ) );
586         }
587 
588         // add the PersonDocumentRoles to the IdentityManagementPersonDocument
589         identityManagementPersonDocument.setRoles(docRoles);
590     }
591 
592     /**
593      * Selects a {@link RoleBoLite} for passed {@link RoleMemberBo} and adds to List of {@link PersonDocumentRole} objects
594      *
595      * @param docRoles a list of {@link PersonDocumentRole} roles
596      * @param roleIds a list of the Ids of the Roles already added
597      * @param member a {@link RoleMemberBo} of a {@link RoleBoLite}
598 	 * @param roleMembers a list of {@link RoleMemberBo} membership objects for the PrincipalId
599      */
600     private void loadDocRoles(List <PersonDocumentRole> docRoles, List<String> roleIds,  RoleMemberBo member, List<RoleMemberBo> roleMembers) {
601 
602         // get the RoleBoLite object by it's Id from a role membership object
603         RoleBoLite role =  getBusinessObjectService().findBySinglePrimaryKey(RoleBoLite.class, member.getRoleId());
604 
605 		// create list of RoleMemberBo's for the same role
606 		List<RoleMemberBo> matchingMembers = new ArrayList<RoleMemberBo>();
607 		for (RoleMemberBo tempMember : roleMembers) {
608 			if (tempMember.getRoleId().equals(member.getRoleId())){
609 				matchingMembers.add(tempMember);
610 			}
611 		}
612 
613         // if not already found add role to docRoles
614         if (ObjectUtils.isNotNull(role) && !roleIds.contains(role.getId())) {
615             PersonDocumentRole docRole = new PersonDocumentRole();
616             docRole.setKimTypeId(role.getKimTypeId());
617             docRole.setActive(role.isActive());
618             docRole.setNamespaceCode(role.getNamespaceCode());
619             docRole.setEdit(true);
620             docRole.setRoleId(role.getId());
621             docRole.setRoleName(role.getName());
622             docRole.refreshReferenceObject("assignedResponsibilities");
623 			docRole.setRolePrncpls(populateDocRolePrncpl(role.getNamespaceCode(), matchingMembers, member.getMemberId(), getAttributeDefinitionsForRole(docRole)));
624             docRoles.add(docRole);
625             roleIds.add(role.getId());
626         }
627     }
628 
629 	protected List<KimAttributeField> getAttributeDefinitionsForRole(PersonDocumentRole role) {
630     	KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(KimTypeBo.to(
631                 role.getKimRoleType()));
632     	//it is possible that the the kimTypeService is coming from a remote application
633         // and therefore it can't be guarenteed that it is up and working, so using a try/catch to catch this possibility.
634         try {
635         	if ( kimTypeService != null ) {
636         		return kimTypeService.getAttributeDefinitions(role.getKimTypeId());
637         	}
638         } catch (Exception ex) {
639             LOG.warn("Not able to retrieve KimTypeService from remote system for KIM Role Type: " + role.getKimRoleType(), ex);
640         }
641     	return Collections.emptyList();
642 	}
643 
644 	protected void loadRoleRstAction(PersonDocumentRole role) {
645 		if(role!=null && CollectionUtils.isNotEmpty(role.getRolePrncpls())){
646 			for (KimDocumentRoleMember roleMbr : role.getRolePrncpls()) {
647 				List<RoleResponsibilityActionBo> actions = getRoleRspActions( roleMbr.getRoleMemberId());
648 				if(ObjectUtils.isNotNull(actions)){
649 					for (RoleResponsibilityActionBo entRoleRspAction :actions) {
650 						KimDocumentRoleResponsibilityAction roleRspAction = new KimDocumentRoleResponsibilityAction();
651 						roleRspAction.setRoleResponsibilityActionId(entRoleRspAction.getId());
652                         roleRspAction.setRoleResponsibilityId(entRoleRspAction.getRoleResponsibilityId());
653 						roleRspAction.setActionTypeCode(entRoleRspAction.getActionTypeCode());
654 						roleRspAction.setActionPolicyCode(entRoleRspAction.getActionPolicyCode());
655 						roleRspAction.setPriorityNumber(entRoleRspAction.getPriorityNumber());
656 						roleRspAction.setRoleResponsibilityActionId(entRoleRspAction.getId());
657 						roleRspAction.refreshReferenceObject("roleResponsibility");
658 						roleMbr.getRoleRspActions().add(roleRspAction);
659 					}
660 				}
661 			}
662 		}
663 	}
664 
665 	protected void setAttrDefnIdForQualifier(KimDocumentRoleQualifier qualifier, KimAttributeField definition) {
666     	qualifier.setKimAttrDefnId(getAttributeDefnId(definition));
667     	qualifier.refreshReferenceObject("kimAttribute");
668     }
669 
670 	protected String getAttributeDefnId(KimAttributeField definition) {
671     	return definition.getId();
672     }
673 
674 	private PrincipalBo getPrincipalImpl(String principalId) {
675 		Map<String,String> criteria = new HashMap<String,String>(1);
676         criteria.put(KIMPropertyConstants.Principal.PRINCIPAL_ID, principalId);
677 		return (PrincipalBo)getBusinessObjectService().findByPrimaryKey(PrincipalBo.class, criteria);
678 	}
679 
680 	public List<EntityEmployment> getEntityEmploymentInformationInfo(String entityId) {
681         EntityBo entityImpl = getEntityBo(entityId);
682         List<EntityEmployment> empInfos = new ArrayList<EntityEmployment>();
683         EntityEmployment empInfo;
684         if(ObjectUtils.isNotNull(entityImpl) && CollectionUtils.isNotEmpty(entityImpl.getEmploymentInformation())){
685         	for(EntityEmploymentBo empImpl: entityImpl.getEmploymentInformation()){
686             	empInfos.add(EntityEmploymentBo.to(empImpl));
687         	}
688         }
689         return empInfos;
690 	}
691 
692 	private EntityBo getEntityBo(String entityId) {
693 		EntityBo entityImpl = getBusinessObjectService().findBySinglePrimaryKey(EntityBo.class, entityId);
694         //TODO - remove this hack... This is here because currently jpa only seems to be going 2 levels deep on the eager fetching.
695 		if(entityImpl!=null  && entityImpl.getEntityTypeContactInfos() != null) {
696         	for (EntityTypeContactInfoBo et : entityImpl.getEntityTypeContactInfos()) {
697         		et.refresh();
698         	}
699         }
700 		return entityImpl;
701 	}
702 
703     @SuppressWarnings("unchecked")
704 	protected List<RoleBo> getRolesForPrincipal(String principalId) {
705 		if ( principalId == null ) {
706 			return new ArrayList<RoleBo>();
707 		}
708 		Map<String,String> criteria = new HashMap<String,String>( 2 );
709 		criteria.put("members.memberId", principalId);
710 		criteria.put("members.typeCode", MemberType.PRINCIPAL.getCode());
711 		return (List<RoleBo>)getBusinessObjectService().findMatching(RoleBo.class, criteria);
712 	}
713 
714 	@SuppressWarnings("unchecked")
715 	protected List<RoleMemberBo> getRoleMembersForPrincipal(String principalId) {
716 		if ( principalId == null ) {
717 			return new ArrayList<RoleMemberBo>();
718 		}
719 		Map<String,String> criteria = new HashMap<String,String>( 2 );
720 		criteria.put("memberId", principalId);
721 		criteria.put("typeCode", MemberType.PRINCIPAL.getCode());
722 		return (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, criteria);
723 	}
724 
725 	public RoleMemberBo getRoleMember(String id) {
726 		if ( id == null ) {
727 			return null;
728 		}
729 		Map<String,String> criteria = new HashMap<String,String>( 2 );
730 		criteria.put("id", id);
731 		return getBusinessObjectService().findByPrimaryKey(RoleMemberBo.class, criteria);
732 	}
733 
734     @SuppressWarnings("unchecked")
735 	protected List<RoleResponsibilityActionBo> getRoleRspActions(String roleMemberId) {
736 		Map<String,String> criteria = new HashMap<String,String>( 1 );
737 		criteria.put(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId);
738 		return (List<RoleResponsibilityActionBo>)getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
739 	}
740 
741     protected List<KimDocumentRoleMember> populateDocRolePrncpl(String namespaceCode, List <RoleMemberBo> roleMembers, String principalId, List<KimAttributeField> definitions) {
742 		List <KimDocumentRoleMember> docRoleMembers = new ArrayList <KimDocumentRoleMember>();
743 		if(ObjectUtils.isNotNull(roleMembers)){
744 	    	for (RoleMemberBo rolePrincipal : roleMembers) {
745 	    		if (rolePrincipal.isActive(new Timestamp(System.currentTimeMillis())) && MemberType.PRINCIPAL.equals(
746                         rolePrincipal.getType()) &&
747 	    				StringUtils.equals(rolePrincipal.getMemberId(), principalId)) {
748 	        		KimDocumentRoleMember docRolePrncpl = new KimDocumentRoleMember();
749 	        		docRolePrncpl.setMemberId(rolePrincipal.getMemberId());
750 	        		docRolePrncpl.setRoleMemberId(rolePrincipal.getId());
751 	        		docRolePrncpl.setActive(rolePrincipal.isActive(new Timestamp(System.currentTimeMillis())));
752 	        		docRolePrncpl.setRoleId(rolePrincipal.getRoleId());
753 	        		docRolePrncpl.setActiveFromDate(rolePrincipal.getActiveFromDateValue());
754 	        		docRolePrncpl.setActiveToDate(rolePrincipal.getActiveToDateValue());
755 	         		docRolePrncpl.setQualifiers(populateDocRoleQualifier(namespaceCode, rolePrincipal.getAttributeDetails(), definitions));
756 	         		docRolePrncpl.setEdit(true);
757 	        		docRoleMembers.add(docRolePrncpl);
758 	    		 }
759 	    	}
760 		}
761     	return docRoleMembers;
762     }
763 
764     // UI layout for rolequalifier is a little different from kimroleattribute set up.
765     // each principal may have member with same role multiple times with different qualifier, but the role
766     // only displayed once, and the qualifier displayed multiple times.
767     protected List<KimDocumentRoleQualifier> populateDocRoleQualifier(String namespaceCode, List <RoleMemberAttributeDataBo> qualifiers, List<KimAttributeField> definitions) {
768 
769 		List <KimDocumentRoleQualifier> docRoleQualifiers = new ArrayList <KimDocumentRoleQualifier>();
770 		if(definitions!=null){
771 			for (KimAttributeField definition : definitions) {
772 				String attrDefId=definition.getId();
773 				boolean qualifierFound = false;
774 				if(ObjectUtils.isNotNull(qualifiers)){
775 					for (RoleMemberAttributeDataBo qualifier : qualifiers) {
776 						if (attrDefId!=null && StringUtils.equals(attrDefId, qualifier.getKimAttributeId())) {
777 				    		KimDocumentRoleQualifier docRoleQualifier = new KimDocumentRoleQualifier();
778 				    		docRoleQualifier.setAttrDataId(qualifier.getId());
779 				    		docRoleQualifier.setAttrVal(qualifier.getAttributeValue());
780 				    		docRoleQualifier.setKimAttrDefnId(qualifier.getKimAttributeId());
781 				    		docRoleQualifier.setKimAttribute(qualifier.getKimAttribute());
782 				    		docRoleQualifier.setKimTypId(qualifier.getKimTypeId());
783 				    		docRoleQualifier.setRoleMemberId(qualifier.getAssignedToId());
784 				    		docRoleQualifier.setEdit(true);
785 				    		formatAttrValIfNecessary(docRoleQualifier);
786 				    		docRoleQualifiers.add(docRoleQualifier);
787 				    		qualifierFound = true;
788 				    		break;
789 						}
790 					}
791 				}
792 				if (!qualifierFound) {
793 		    		KimDocumentRoleQualifier docRoleQualifier = new KimDocumentRoleQualifier();
794 		    		docRoleQualifier.setAttrVal("");
795 		    		docRoleQualifier.setKimAttrDefnId(attrDefId);
796 		    		docRoleQualifier.refreshReferenceObject("kimAttribute");
797 		    		docRoleQualifiers.add(docRoleQualifier);
798 				}
799 			}
800 			// If all of the qualifiers are empty, return an empty list
801 			// This is to prevent dynamic qualifiers from appearing in the
802 			// person maintenance roles tab.  see KULRICE-3989 for more detail
803 			// and KULRICE-5071 for detail on switching from config value to 
804 			// application-scoped parameter
805 			if (!isBlankRoleQualifierVisible(namespaceCode)) {
806 				int qualCount = 0;
807 				for (KimDocumentRoleQualifier qual : docRoleQualifiers){
808 					if (StringUtils.isEmpty(qual.getAttrVal())){
809 						qualCount++;
810 					}
811 				}
812 				if (qualCount == docRoleQualifiers.size()){
813 					return new ArrayList <KimDocumentRoleQualifier>();
814 				}
815 			}
816 		}
817     	return docRoleQualifiers;
818     }
819 
820     protected List<PersonDocumentName> loadNames( IdentityManagementPersonDocument personDoc, String principalId, List <EntityName> names, boolean suppressDisplay ) {
821 		List<PersonDocumentName> docNames = new ArrayList<PersonDocumentName>();
822 		if(ObjectUtils.isNotNull(names)){
823 			for (EntityName name: names) {
824 				if(name.isActive()){
825 					PersonDocumentName docName = new PersonDocumentName();
826                     if (name.getNameType() != null) {
827 					    docName.setNameCode(name.getNameType().getCode());
828                     }
829 
830 					//We do not need to check the privacy setting here - The UI should care of it
831 					docName.setFirstName(name.getFirstNameUnmasked());
832 					docName.setLastName(name.getLastNameUnmasked());
833 					docName.setMiddleName(name.getMiddleNameUnmasked());
834 					docName.setNamePrefix(name.getNamePrefixUnmasked());
835 					docName.setNameSuffix(name.getNameSuffixUnmasked());
836 
837 					docName.setActive(name.isActive());
838 					docName.setDflt(name.isDefaultValue());
839 					docName.setEdit(true);
840 					docName.setEntityNameId(name.getId());
841 					docNames.add(docName);
842 				}
843 			}
844 		}
845 		return docNames;
846 	}
847 
848 	public boolean canModifyEntity( String currentUserPrincipalId, String toModifyPrincipalId ){
849 		return (StringUtils.isNotBlank(currentUserPrincipalId) && StringUtils.isNotBlank(toModifyPrincipalId) &&
850 				currentUserPrincipalId.equals(toModifyPrincipalId)) ||
851 				getPermissionService().isAuthorized(
852 						currentUserPrincipalId,
853 						KimConstants.NAMESPACE_CODE,
854 						KimConstants.PermissionNames.MODIFY_ENTITY,
855 						Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, currentUserPrincipalId));
856 	}
857 
858 	public boolean canOverrideEntityPrivacyPreferences( String currentUserPrincipalId, String toModifyPrincipalId ){
859 		return (StringUtils.isNotBlank(currentUserPrincipalId) && StringUtils.isNotBlank(toModifyPrincipalId) &&
860 				currentUserPrincipalId.equals(toModifyPrincipalId)) ||
861 				getPermissionService().isAuthorized(
862 						currentUserPrincipalId,
863 						KimConstants.NAMESPACE_CODE,
864 						KimConstants.PermissionNames.OVERRIDE_ENTITY_PRIVACY_PREFERENCES,
865 						Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, currentUserPrincipalId) );
866 	}
867 
868 	protected boolean canAssignToRole(IdentityManagementRoleDocument document, String initiatorPrincipalId){
869         boolean rulePassed = true;
870         Map<String,String> additionalPermissionDetails = new HashMap<String,String>();
871         additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace());
872         additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName());
873 		if(!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate(
874 				document, KimConstants.NAMESPACE_CODE, KimConstants.PermissionTemplateNames.ASSIGN_ROLE,
875 				initiatorPrincipalId, additionalPermissionDetails, null)){
876             rulePassed = false;
877 		}
878 		return rulePassed;
879 	}
880 
881 	protected List<PersonDocumentAffiliation> loadAffiliations(List <EntityAffiliation> affiliations, List<EntityEmployment> empInfos) {
882 		List<PersonDocumentAffiliation> docAffiliations = new ArrayList<PersonDocumentAffiliation>();
883 		if(ObjectUtils.isNotNull(affiliations)){
884 			for (EntityAffiliation affiliation: affiliations) {
885 				if(affiliation.isActive()){
886 					PersonDocumentAffiliation docAffiliation = new PersonDocumentAffiliation();
887 					docAffiliation.setAffiliationTypeCode(affiliation.getAffiliationType().getCode());
888 					docAffiliation.setCampusCode(affiliation.getCampusCode());
889 					docAffiliation.setActive(affiliation.isActive());
890 					docAffiliation.setDflt(affiliation.isDefaultValue());
891 					docAffiliation.setEntityAffiliationId(affiliation.getId());
892 					docAffiliation.refreshReferenceObject("affiliationType");
893 					// EntityAffiliationImpl does not define empinfos as collection
894 					docAffiliations.add(docAffiliation);
895 					docAffiliation.setEdit(true);
896 					// employment informations
897 					List<PersonDocumentEmploymentInfo> docEmploymentInformations = new ArrayList<PersonDocumentEmploymentInfo>();
898 					if(ObjectUtils.isNotNull(empInfos)){
899 						for (EntityEmployment empInfo: empInfos) {
900 							if (empInfo.isActive()
901                                     && StringUtils.equals(docAffiliation.getEntityAffiliationId(),
902                                                           (empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null))) {
903 								PersonDocumentEmploymentInfo docEmpInfo = new PersonDocumentEmploymentInfo();
904 								docEmpInfo.setEntityEmploymentId(empInfo.getEmployeeId());
905 								docEmpInfo.setEmployeeId(empInfo.getEmployeeId());
906 								docEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
907 								docEmpInfo.setBaseSalaryAmount(empInfo.getBaseSalaryAmount());
908 								docEmpInfo.setPrimaryDepartmentCode(empInfo.getPrimaryDepartmentCode());
909 								docEmpInfo.setEmploymentStatusCode(empInfo.getEmployeeStatus() != null ? empInfo.getEmployeeStatus().getCode() : null);
910 								docEmpInfo.setEmploymentTypeCode(empInfo.getEmployeeType() != null ? empInfo.getEmployeeType().getCode() : null);
911 								docEmpInfo.setActive(empInfo.isActive());
912 								docEmpInfo.setPrimary(empInfo.isPrimary());
913 								docEmpInfo.setEntityAffiliationId(empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null);
914 								// there is no version number on KimEntityEmploymentInformationInfo
915 								//docEmpInfo.setVersionNumber(empInfo.getVersionNumber());
916 								docEmpInfo.setEdit(true);
917 								docEmpInfo.refreshReferenceObject("employmentType");
918 								docEmploymentInformations.add(docEmpInfo);
919 							}
920 						}
921 					}
922 					docAffiliation.setEmpInfos(docEmploymentInformations);
923 				}
924 			}
925 		}
926 		return docAffiliations;
927 
928 	}
929 
930     protected boolean setupPrincipal(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, List<PrincipalBo> origPrincipals) {
931     	boolean inactivatingPrincipal = false;
932 		List<PrincipalBo> principals = new ArrayList<PrincipalBo>();
933 		PrincipalBo principal = new PrincipalBo();
934         principal.setPrincipalName(identityManagementPersonDocument.getPrincipalName());
935 		principal.setPrincipalId(identityManagementPersonDocument.getPrincipalId());
936 		principal.setActive(identityManagementPersonDocument.isActive());
937 		principal.setEntityId(identityManagementPersonDocument.getEntityId());
938 		if(ObjectUtils.isNotNull(origPrincipals)){
939 			for (PrincipalBo prncpl : origPrincipals) {
940 				if (prncpl.getPrincipalId()!=null && StringUtils.equals(prncpl.getPrincipalId(), principal.getPrincipalId())) {
941 					principal.setVersionNumber(prncpl.getVersionNumber());
942                     principal.setObjectId(prncpl.getObjectId());
943                     principal.setPassword(prncpl.getPassword());
944 					// check if inactivating the principal
945 					if ( prncpl.isActive() && !principal.isActive() ) {
946 						inactivatingPrincipal = true;
947 					}
948 				}
949 			}
950 		}
951 		principals.add(principal);
952 
953 		kimEntity.setPrincipals(principals);
954 		return inactivatingPrincipal;
955 	}
956 
957     protected void setupPrivacy(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, EntityPrivacyPreferencesBo origPrivacy) {
958 		EntityPrivacyPreferencesBo privacyPreferences = new EntityPrivacyPreferencesBo();
959 		privacyPreferences.setEntityId(identityManagementPersonDocument.getEntityId());
960 		privacyPreferences.setSuppressAddress(identityManagementPersonDocument.getPrivacy().isSuppressAddress());
961 		privacyPreferences.setSuppressEmail(identityManagementPersonDocument.getPrivacy().isSuppressEmail());
962 		privacyPreferences.setSuppressName(identityManagementPersonDocument.getPrivacy().isSuppressName());
963 		privacyPreferences.setSuppressPhone(identityManagementPersonDocument.getPrivacy().isSuppressPhone());
964 		privacyPreferences.setSuppressPersonal(identityManagementPersonDocument.getPrivacy().isSuppressPersonal());
965 		if (ObjectUtils.isNotNull(origPrivacy)) {
966 			privacyPreferences.setVersionNumber(origPrivacy.getVersionNumber());
967             privacyPreferences.setObjectId(origPrivacy.getObjectId());
968 		}
969 		kimEntity.setPrivacyPreferences(privacyPreferences);
970 	}
971     protected PersonDocumentPrivacy loadPrivacyReferences(EntityPrivacyPreferences privacyPreferences) {
972 		PersonDocumentPrivacy docPrivacy = new PersonDocumentPrivacy();
973 		docPrivacy.setSuppressAddress(privacyPreferences.isSuppressAddress());
974 		docPrivacy.setSuppressEmail(privacyPreferences.isSuppressEmail());
975 		docPrivacy.setSuppressName(privacyPreferences.isSuppressName());
976 		docPrivacy.setSuppressPhone(privacyPreferences.isSuppressPhone());
977 		docPrivacy.setSuppressPersonal(privacyPreferences.isSuppressPersonal());
978 		docPrivacy.setEdit(true);
979 		return docPrivacy;
980 	}
981 
982     protected void setupName(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity, List<EntityNameBo> origNames) {
983     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressName() ||
984     			canOverrideEntityPrivacyPreferences( getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId() ) ) {
985 	    	List<EntityNameBo> entityNames = new ArrayList<EntityNameBo>();
986 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getNames())){
987 				for (PersonDocumentName name : identityManagementPersonDocument.getNames()) {
988 				    EntityNameBo entityName = new EntityNameBo();
989 					entityName.setNameCode(name.getNameCode());
990                     if (name.getEntityNameType() != null) {
991                         entityName.setNameType(name.getEntityNameType());
992                     } else {
993                         if (StringUtils.isNotEmpty(name.getNameCode())) {
994                             entityName.setNameType(
995                                     EntityNameTypeBo.from(getIdentityService().getNameType(name.getNameCode())));
996                         }
997                     }
998 					entityName.setFirstName(name.getFirstName());
999 					entityName.setLastName(name.getLastName());
1000 					entityName.setMiddleName(name.getMiddleName());
1001 					entityName.setNamePrefix(name.getNamePrefix());
1002 					entityName.setNameSuffix(name.getNameSuffix());
1003 					entityName.setActive(name.isActive());
1004 					entityName.setDefaultValue(name.isDflt());
1005 					entityName.setId(name.getEntityNameId());
1006 					entityName.setEntityId(identityManagementPersonDocument.getEntityId());
1007 					if(ObjectUtils.isNotNull(origNames)){
1008 						for (EntityNameBo origName : origNames) {
1009 							if (origName.getId()!=null && StringUtils.equals(origName.getId(), entityName.getId())) {
1010 								entityName.setVersionNumber(origName.getVersionNumber());
1011 							}
1012 
1013 						}
1014 					}
1015 					entityNames.add(entityName);
1016 				}
1017 			}
1018 			kimEntity.setNames(entityNames);
1019     	}
1020 	}
1021 
1022     protected void setupAffiliation(IdentityManagementPersonDocument identityManagementPersonDocument, EntityBo kimEntity,List<EntityAffiliationBo> origAffiliations, List<EntityEmploymentBo> origEmpInfos) {
1023 		List<EntityAffiliationBo> entityAffiliations = new ArrayList<EntityAffiliationBo>();
1024 		// employment informations
1025 		List<EntityEmploymentBo> entityEmploymentInformations = new ArrayList<EntityEmploymentBo>();
1026 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getAffiliations())){
1027 			for (PersonDocumentAffiliation affiliation : identityManagementPersonDocument.getAffiliations()) {
1028 				EntityAffiliationBo entityAffiliation = new EntityAffiliationBo();
1029 				entityAffiliation.setAffiliationTypeCode(affiliation.getAffiliationTypeCode());
1030                 if (affiliation.getAffiliationType() != null) {
1031                         entityAffiliation.setAffiliationType(affiliation.getAffiliationType());
1032                 } else {
1033                     if (StringUtils.isNotEmpty(affiliation.getAffiliationTypeCode())) {
1034                         entityAffiliation.setAffiliationType(EntityAffiliationTypeBo.from(getIdentityService().getAffiliationType(
1035                                 affiliation.getAffiliationTypeCode())));
1036                     }
1037                 }
1038 				entityAffiliation.setCampusCode(affiliation.getCampusCode());
1039 				entityAffiliation.setActive(affiliation.isActive());
1040 				entityAffiliation.setDefaultValue(affiliation.isDflt());
1041 				entityAffiliation.setEntityId(identityManagementPersonDocument.getEntityId());
1042 				entityAffiliation.setId(affiliation.getEntityAffiliationId());
1043 				if(ObjectUtils.isNotNull(origAffiliations)){
1044 				// EntityAffiliationImpl does not define empinfos as collection
1045 					for (EntityAffiliationBo origAffiliation : origAffiliations) {
1046 						if(isSameAffiliation(origAffiliation, entityAffiliation)){
1047 							entityAffiliation.setId(origAffiliation.getId());
1048 						}
1049 						if (origAffiliation.getId()!=null && StringUtils.equals(origAffiliation.getId(), entityAffiliation.getId())) {
1050 							entityAffiliation.setVersionNumber(origAffiliation.getVersionNumber());
1051 						}
1052 					}
1053 				}
1054 				entityAffiliations.add(entityAffiliation);
1055 				int employeeRecordCounter = origEmpInfos==null?0:origEmpInfos.size();
1056 				if(CollectionUtils.isNotEmpty(affiliation.getEmpInfos())){
1057 					for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
1058 						EntityEmploymentBo entityEmpInfo = new EntityEmploymentBo();
1059 						entityEmpInfo.setId(empInfo.getEntityEmploymentId());
1060 						entityEmpInfo.setEmployeeId(empInfo.getEmployeeId());
1061 						entityEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
1062 						entityEmpInfo.setBaseSalaryAmount(empInfo.getBaseSalaryAmount());
1063 						entityEmpInfo.setPrimaryDepartmentCode(empInfo.getPrimaryDepartmentCode());
1064 						entityEmpInfo.setEmployeeStatusCode(empInfo.getEmploymentStatusCode());
1065                         if (empInfo.getEmploymentStatus() != null) {
1066                             entityEmpInfo.setEmployeeStatus(empInfo.getEmploymentStatus());
1067                         } else {
1068                             if (StringUtils.isNotEmpty(empInfo.getEmploymentStatusCode())) {
1069                                 entityEmpInfo.setEmployeeStatus(EntityEmploymentStatusBo
1070                                         .from(getIdentityService().getEmploymentStatus(empInfo.getEmploymentStatusCode())));
1071                             }
1072                         }
1073 						entityEmpInfo.setEmployeeTypeCode(empInfo.getEmploymentTypeCode());
1074                         if (empInfo.getEmploymentType() != null) {
1075                             entityEmpInfo.setEmployeeType(empInfo.getEmploymentType());
1076                         } else {
1077                             if (StringUtils.isNotEmpty(empInfo.getEmploymentTypeCode())) {
1078                                 entityEmpInfo.setEmployeeType(EntityEmploymentTypeBo
1079                                         .from(getIdentityService().getEmploymentType(empInfo.getEmploymentTypeCode())));
1080                             }
1081                         }
1082 						entityEmpInfo.setActive(empInfo.isActive());
1083 						entityEmpInfo.setPrimary(empInfo.isPrimary());
1084 						entityEmpInfo.setEntityId(identityManagementPersonDocument.getEntityId());
1085 						entityEmpInfo.setEntityAffiliationId(empInfo.getEntityAffiliationId());
1086 						if(ObjectUtils.isNotNull(origEmpInfos)){
1087 							for (EntityEmploymentBo origEmpInfo : origEmpInfos) {
1088 								if(isSameEmpInfo(origEmpInfo, entityEmpInfo)){
1089 									entityEmpInfo.setId(origEmpInfo.getId());
1090 								}
1091 
1092 								if (origEmpInfo.getId()!=null && StringUtils.equals(origEmpInfo.getId(), entityEmpInfo.getId())) {
1093 									entityEmpInfo.setVersionNumber(origEmpInfo.getVersionNumber());
1094 									entityEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId());
1095 								}
1096 							}
1097 						}
1098 						if(StringUtils.isEmpty(entityEmpInfo.getEmploymentRecordId())){
1099 							employeeRecordCounter++;
1100 							entityEmpInfo.setEmploymentRecordId(employeeRecordCounter+"");
1101 						}
1102 						entityEmploymentInformations.add(entityEmpInfo);
1103 					}
1104 				}
1105 			}
1106 		}
1107 		kimEntity.setEmploymentInformation(entityEmploymentInformations);
1108 		kimEntity.setAffiliations(entityAffiliations);
1109 	}
1110 
1111     /*
1112      * Added to address KULRICE-5071 : "Move the 'show blank qualifier' kim toggle from a Config param to a System param"
1113      * 
1114      * This method first checks for a namespace specific parameter with a detailTypeCode of "All" and parameterName of "KIM_SHOW_BLANK_QUALIFIERS". 
1115      * If no parameter is found, it checks for the config property "kim.show.blank.qualifiers", and defaults to true if no config property exists. 
1116      *
1117      */
1118     private boolean isBlankRoleQualifierVisible(String namespaceCode) {
1119     	boolean showBlankQualifiers = true;
1120 		
1121 		Parameter param = getParameterService().getParameter(namespaceCode, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, KimConstants.ParameterKey.SHOW_BLANK_QUALIFIERS);
1122 	    if (param != null) {
1123 	    	showBlankQualifiers = "Y".equals(param.getValue());
1124 	    } else {
1125 	    	String configProperty = ConfigContext.getCurrentContextConfig().getProperty(SHOW_BLANK_QUALIFIERS);
1126 	    	if (configProperty != null) {
1127 	    		showBlankQualifiers = Boolean.valueOf(configProperty);
1128             }
1129 	    }
1130 	    
1131 	    return showBlankQualifiers;
1132     }
1133     
1134    private boolean isSameAffiliation(EntityAffiliationBo origAffiliation, EntityAffiliationBo entityAffiliation){
1135     	//entityId
1136     	//affiliationTypeCode
1137     	//campusCode
1138     	return (origAffiliation!=null && entityAffiliation!=null) &&
1139     	(StringUtils.isNotEmpty(origAffiliation.getCampusCode()) && StringUtils.equals(origAffiliation.getCampusCode(), entityAffiliation.getCampusCode()))
1140     	&&
1141     	(StringUtils.isNotEmpty(origAffiliation.getAffiliationTypeCode()) && StringUtils.equals(origAffiliation.getAffiliationTypeCode(), entityAffiliation.getAffiliationTypeCode()))
1142  		&&
1143  		(StringUtils.isNotEmpty(origAffiliation.getEntityId()) && StringUtils.equals(origAffiliation.getEntityId(), entityAffiliation.getEntityId()));
1144     }
1145 
1146     private boolean isSameEmpInfo(EntityEmploymentBo origEmpInfo, EntityEmploymentBo entityEmpInfo){
1147     	//emp_info:
1148     		//employmentRecordId
1149     		//entityId
1150     		//These should be unique - add a business rule
1151     	return (origEmpInfo!=null && entityEmpInfo!=null)
1152     			&& (StringUtils.isNotEmpty(origEmpInfo.getEmploymentRecordId())
1153     					&& StringUtils.equals(origEmpInfo.getEmploymentRecordId(), entityEmpInfo.getEmploymentRecordId() )
1154     				)
1155     			&& StringUtils.equals( origEmpInfo.getEntityId(),entityEmpInfo.getEntityId());
1156     }
1157 
1158     protected void setupPhone(IdentityManagementPersonDocument identityManagementPersonDocument, EntityTypeContactInfoBo entityType, List<EntityPhoneBo> origPhones) {
1159     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressPhone() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1160 			List<EntityPhoneBo> entityPhones = new ArrayList<EntityPhoneBo>();
1161 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getPhones())){
1162 				for (PersonDocumentPhone phone : identityManagementPersonDocument.getPhones()) {
1163 					EntityPhoneBo entityPhone = new EntityPhoneBo();
1164 					entityPhone.setPhoneTypeCode(phone.getPhoneTypeCode());
1165                     if (phone.getPhoneType() != null) {
1166                         entityPhone.setPhoneType(phone.getPhoneType());
1167                     } else {
1168                         if (StringUtils.isNotEmpty(phone.getPhoneTypeCode())) {
1169                             entityPhone.setPhoneType(EntityPhoneTypeBo
1170                                     .from(getIdentityService().getAddressType(phone.getPhoneTypeCode())));
1171                         }
1172                     }
1173 					entityPhone.setEntityId(identityManagementPersonDocument.getEntityId());
1174 					entityPhone.setId(phone.getEntityPhoneId());
1175 					entityPhone.setEntityTypeCode(entityType.getEntityTypeCode());
1176 					entityPhone.setPhoneNumber(phone.getPhoneNumber());
1177 					entityPhone.setCountryCode(phone.getCountryCode());
1178 					entityPhone.setExtension(phone.getExtension());
1179 					entityPhone.setExtensionNumber(phone.getExtensionNumber());
1180 					entityPhone.setActive(phone.isActive());
1181 					entityPhone.setDefaultValue(phone.isDflt());
1182 					if(ObjectUtils.isNotNull(origPhones)){
1183 						for (EntityPhoneContract origPhone : origPhones) {
1184 							if (origPhone.getId()!=null && StringUtils.equals(origPhone.getId(), entityPhone.getId())) {
1185 								entityPhone.setVersionNumber(origPhone.getVersionNumber());
1186 							}
1187 						}
1188 					}
1189 					entityPhone.setId(phone.getEntityPhoneId());
1190 					entityPhones.add(entityPhone);
1191 				}
1192 			}
1193 			entityType.setPhoneNumbers(entityPhones);
1194     	}
1195 	}
1196 
1197     protected List<PersonDocumentPhone> loadPhones(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityPhone> entityPhones, boolean suppressDisplay ) {
1198 		List<PersonDocumentPhone> docPhones = new ArrayList<PersonDocumentPhone>();
1199 		if(ObjectUtils.isNotNull(entityPhones)){
1200 			for (EntityPhone phone: entityPhones) {
1201 				if(phone.isActive()){
1202 					PersonDocumentPhone docPhone = new PersonDocumentPhone();
1203                     if (phone.getPhoneType() != null) {
1204 					    docPhone.setPhoneTypeCode(phone.getPhoneType().getCode());
1205                     }
1206 					//docPhone.setPhoneType(((KimEntityPhoneImpl)phone).getPhoneType());
1207 					docPhone.setEntityTypeCode(phone.getEntityTypeCode());
1208 					//We do not need to check the privacy setting here - The UI should care of it
1209 					docPhone.setPhoneNumber(phone.getPhoneNumberUnmasked());
1210 					docPhone.setCountryCode(phone.getCountryCodeUnmasked());
1211 					docPhone.setExtensionNumber(phone.getExtensionNumberUnmasked());
1212 
1213 					docPhone.setActive(phone.isActive());
1214 					docPhone.setDflt(phone.isDefaultValue());
1215 					docPhone.setEntityPhoneId(phone.getId());
1216 					docPhone.setEdit(true);
1217 					docPhones.add(docPhone);
1218 				}
1219 			}
1220 		}
1221 		return docPhones;
1222 
1223 	}
1224 
1225     protected void setupEmail(
1226 			IdentityManagementPersonDocument identityManagementPersonDocument,
1227 			EntityTypeContactInfoBo entityType, List<EntityEmailBo> origEmails) {
1228     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressEmail() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1229 			List<EntityEmailBo> entityEmails = new ArrayList<EntityEmailBo>();
1230 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getEmails())){
1231 				for (PersonDocumentEmail email : identityManagementPersonDocument.getEmails()) {
1232 					EntityEmailBo entityEmail = new EntityEmailBo();
1233 					entityEmail.setEntityId(identityManagementPersonDocument.getEntityId());
1234 					entityEmail.setEntityTypeCode(entityType.getEntityTypeCode());
1235                     if (email.getEmailType() != null) {
1236                         entityEmail.setEmailType(email.getEmailType());
1237                     } else {
1238                         if (StringUtils.isNotEmpty(email.getEmailTypeCode())) {
1239                             entityEmail.setEmailType(
1240                                     EntityEmailTypeBo.from(getIdentityService().getEmailType(email.getEmailTypeCode())));
1241                         }
1242                     }
1243 					entityEmail.setEmailTypeCode(email.getEmailTypeCode());
1244 					entityEmail.setEmailAddress(email.getEmailAddress());
1245 					entityEmail.setActive(email.isActive());
1246 					entityEmail.setDefaultValue(email.isDflt());
1247 					entityEmail.setId(email.getEntityEmailId());
1248 					if(ObjectUtils.isNotNull(origEmails)){
1249 						for (EntityEmailContract origEmail : origEmails) {
1250 							if (origEmail.getId()!=null && StringUtils.equals(origEmail.getId(), entityEmail.getId())) {
1251 								entityEmail.setVersionNumber(origEmail.getVersionNumber());
1252 							}
1253 						}
1254 					}
1255 					entityEmails.add(entityEmail);
1256 				}
1257 			}
1258 			entityType.setEmailAddresses(entityEmails);
1259     	}
1260 	}
1261     protected List<PersonDocumentEmail> loadEmails(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityEmail> entityEmails, boolean suppressDisplay ) {
1262 		List<PersonDocumentEmail> emails = new ArrayList<PersonDocumentEmail>();
1263 		if(ObjectUtils.isNotNull(entityEmails)){
1264 			for (EntityEmail email: entityEmails) {
1265 				if(email.isActive()){
1266 					PersonDocumentEmail docEmail = new PersonDocumentEmail();
1267 					//docEmail.setEntityId(email.getEntityId());
1268 					docEmail.setEntityTypeCode(email.getEntityTypeCode());
1269                     if (email.getEmailType() != null) {
1270 					    docEmail.setEmailTypeCode(email.getEmailType().getCode());
1271                     }
1272 					// EmailType not on info object.
1273 					//docEmail.setEmailType(((KimEntityEmailImpl)email).getEmailType());
1274 					//We do not need to check the privacy setting here - The UI should care of it
1275 					docEmail.setEmailAddress(email.getEmailAddressUnmasked());
1276 
1277 					docEmail.setActive(email.isActive());
1278 					docEmail.setDflt(email.isDefaultValue());
1279 					docEmail.setEntityEmailId(email.getId());
1280 					docEmail.setEdit(true);
1281 					emails.add(docEmail);
1282 				}
1283 			}
1284 		}
1285 		return emails;
1286 	}
1287 
1288     protected void setupAddress(
1289 			IdentityManagementPersonDocument identityManagementPersonDocument,
1290 			EntityTypeContactInfoBo entityType, List<EntityAddressBo> origAddresses) {
1291     	if ( !identityManagementPersonDocument.getPrivacy().isSuppressAddress() || canOverrideEntityPrivacyPreferences(getInitiatorPrincipalId(identityManagementPersonDocument), identityManagementPersonDocument.getPrincipalId()) ) {
1292 			List<EntityAddressBo> entityAddresses = new ArrayList<EntityAddressBo>();
1293 			if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getAddrs())){
1294 				for (PersonDocumentAddress address : identityManagementPersonDocument.getAddrs()) {
1295 					EntityAddressBo entityAddress = new EntityAddressBo();
1296 					entityAddress.setEntityId(identityManagementPersonDocument.getEntityId());
1297 					entityAddress.setEntityTypeCode(entityType.getEntityTypeCode());
1298 					entityAddress.setAddressTypeCode(address.getAddressTypeCode());
1299                     if (address.getAddressType() != null) {
1300                         entityAddress.setAddressType(address.getAddressType());
1301                     } else {
1302                         if (StringUtils.isNotEmpty(address.getAddressTypeCode())) {
1303                             entityAddress.setAddressType(EntityAddressTypeBo.from(
1304                                     getIdentityService().getAddressType(address.getAddressTypeCode())));
1305                         }
1306                     }
1307 					entityAddress.setLine1(address.getLine1());
1308 					entityAddress.setLine2(address.getLine2());
1309 					entityAddress.setLine3(address.getLine3());
1310 					entityAddress.setStateProvinceCode(address.getStateProvinceCode());
1311 					entityAddress.setPostalCode(address.getPostalCode());
1312 					entityAddress.setCountryCode(address.getCountryCode());
1313 					entityAddress.setCity(address.getCity());
1314 					entityAddress.setActive(address.isActive());
1315 					entityAddress.setDefaultValue(address.isDflt());
1316 					entityAddress.setId(address.getEntityAddressId());
1317 					if(ObjectUtils.isNotNull(origAddresses)){
1318 						for (EntityAddressContract origAddress : origAddresses) {
1319 							if (origAddress.getId()!=null && StringUtils.equals(origAddress.getId(), entityAddress.getId())) {
1320 								entityAddress.setVersionNumber(origAddress.getVersionNumber());
1321 							}
1322 						}
1323 					}
1324 					entityAddresses.add(entityAddress);
1325 				}
1326 			}
1327 			entityType.setAddresses(entityAddresses);
1328     	}
1329 	}
1330 
1331     protected List<PersonDocumentAddress> loadAddresses(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityAddress> entityAddresses, boolean suppressDisplay ) {
1332 		List<PersonDocumentAddress> docAddresses = new ArrayList<PersonDocumentAddress>();
1333 		if(ObjectUtils.isNotNull(entityAddresses)){
1334 			for (EntityAddress address: entityAddresses) {
1335 				if(address.isActive()){
1336 					PersonDocumentAddress docAddress = new PersonDocumentAddress();
1337 					docAddress.setEntityTypeCode(address.getEntityTypeCode());
1338 					docAddress.setAddressTypeCode(address.getAddressType().getCode());
1339 
1340 					//We do not need to check the privacy setting here - The UI should care of it
1341 					docAddress.setLine1(address.getLine1Unmasked());
1342 					docAddress.setLine2(address.getLine2Unmasked());
1343 					docAddress.setLine3(address.getLine3Unmasked());
1344 					docAddress.setStateProvinceCode(address.getStateProvinceCodeUnmasked());
1345 					docAddress.setPostalCode(address.getPostalCodeUnmasked());
1346 					docAddress.setCountryCode(address.getCountryCodeUnmasked());
1347 					docAddress.setCity(address.getCityUnmasked());
1348 
1349 					docAddress.setActive(address.isActive());
1350 					docAddress.setDflt(address.isDefaultValue());
1351 					docAddress.setEntityAddressId(address.getId());
1352 					docAddress.setEdit(true);
1353 					docAddresses.add(docAddress);
1354 				}
1355 			}
1356 		}
1357 		return docAddresses;
1358 	}
1359 
1360 
1361     protected List <GroupMemberBo> populateGroupMembers(IdentityManagementPersonDocument identityManagementPersonDocument) {
1362 		List <GroupMemberBo>  groupPrincipals = new ArrayList<GroupMemberBo>();
1363 //		List<? extends Group> origGroups = getGroupService().getGroupsByPrincipalId(identityManagementPersonDocument.getPrincipalId());
1364 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getGroups())){
1365 			for (PersonDocumentGroup group : identityManagementPersonDocument.getGroups()) {
1366 				GroupMember.Builder groupPrincipalImpl = GroupMember.Builder.create(group.getGroupId(), identityManagementPersonDocument.getPrincipalId(), KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
1367 				if (group.getActiveFromDate() != null) {
1368 					groupPrincipalImpl.setActiveFromDate(new DateTime(group.getActiveFromDate().getTime()));
1369 				}
1370 				if (group.getActiveToDate() != null) {
1371 					groupPrincipalImpl.setActiveToDate(new DateTime(group.getActiveToDate().getTime()));
1372 				}
1373 				groupPrincipalImpl.setId(group.getGroupMemberId());
1374 
1375 
1376                 //groupPrincipalImpl.setVersionNumber(group.getVersionNumber());
1377 				// get the ORM-layer optimisic locking value
1378 				// TODO: this should be replaced with the retrieval and storage of that value
1379 				// in the document tables and not re-retrieved here
1380 				Collection<GroupMember> currGroupMembers = getGroupService().getMembers(Collections.singletonList(group.getGroupId()));
1381 				if(ObjectUtils.isNotNull(currGroupMembers)){
1382 					for (GroupMember origGroupMember: currGroupMembers) {
1383                         if (origGroupMember.isActive(new DateTime(System.currentTimeMillis()))
1384                             && KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.equals(origGroupMember.getType())) {
1385                             if(origGroupMember.getId()!=null && StringUtils.equals(origGroupMember.getId(), group.getGroupMemberId())){
1386                                 groupPrincipalImpl.setObjectId(origGroupMember.getObjectId());
1387                                 groupPrincipalImpl.setVersionNumber(origGroupMember.getVersionNumber());
1388                             }
1389                         }
1390 					}
1391 				}
1392 
1393 				groupPrincipals.add(GroupMemberBo.from(groupPrincipalImpl.build()));
1394 
1395 			}
1396 		}
1397 		return groupPrincipals;
1398 	}
1399 
1400     protected List<RoleMemberBo> populateRoleMembers(IdentityManagementPersonDocument identityManagementPersonDocument) {
1401 		List<RoleBo> origRoles = getRolesForPrincipal(identityManagementPersonDocument.getPrincipalId());
1402 
1403 		List <RoleMemberBo> roleMembers = new ArrayList<RoleMemberBo>();
1404 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getRoles())){
1405 			for (PersonDocumentRole role : identityManagementPersonDocument.getRoles()) {
1406 				//if(role.isEditable()){
1407 					List<RoleMemberBo> origRoleMembers = new ArrayList<RoleMemberBo>();
1408 					if(ObjectUtils.isNotNull(origRoles)){
1409 						for (RoleBo origRole : origRoles) {
1410 							if (origRole.getId()!=null && StringUtils.equals(origRole.getId(), role.getRoleId())) {
1411 								origRoleMembers = origRole.getMembers();
1412 								break;
1413 							}
1414 						}
1415 					}
1416 					if (role.getRolePrncpls().isEmpty()) {
1417 						if (!role.getDefinitions().isEmpty()) {
1418 							RoleMemberBo roleMemberImpl = new RoleMemberBo();
1419 							roleMemberImpl.setRoleId(role.getRoleId());
1420 							roleMemberImpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
1421 							roleMemberImpl.setType(MemberType.PRINCIPAL);
1422 							roleMembers.add(roleMemberImpl);
1423 						}
1424 					} else {
1425 						for (KimDocumentRoleMember roleMember : role.getRolePrncpls()) {
1426 							RoleMemberBo roleMemberImpl = new RoleMemberBo();
1427 							roleMemberImpl.setRoleId(role.getRoleId());
1428 							// TODO : principalId is not ready here yet ?
1429 							roleMemberImpl.setMemberId(identityManagementPersonDocument.getPrincipalId());
1430 							roleMemberImpl.setType(MemberType.PRINCIPAL);
1431 							roleMemberImpl.setId(roleMember.getRoleMemberId());
1432 							if (roleMember.getActiveFromDate() != null) {
1433 								roleMemberImpl.setActiveFromDateValue(
1434                                         new java.sql.Timestamp(roleMember.getActiveFromDate().getTime()));
1435 							}
1436 							if (roleMember.getActiveToDate() != null) {
1437 								roleMemberImpl.setActiveToDateValue(
1438                                         new java.sql.Timestamp(roleMember.getActiveToDate().getTime()));
1439 							}
1440 							List<RoleMemberAttributeDataBo> origAttributes = new ArrayList<RoleMemberAttributeDataBo>();
1441 							if(ObjectUtils.isNotNull(origRoleMembers)){
1442 								for (RoleMemberBo origMember : origRoleMembers) {
1443 									if (origMember.getId()!=null && StringUtils.equals(origMember.getId(), roleMember.getRoleMemberId())) {
1444 										origAttributes = origMember.getAttributeDetails();
1445 										roleMemberImpl.setVersionNumber(origMember.getVersionNumber());
1446 									}
1447 								}
1448 							}
1449 							List<RoleMemberAttributeDataBo> attributes = new ArrayList<RoleMemberAttributeDataBo>();
1450 							if(CollectionUtils.isNotEmpty(roleMember.getQualifiers())){
1451 								for (KimDocumentRoleQualifier qualifier : roleMember.getQualifiers()) {
1452 									//if (StringUtils.isNotBlank(qualifier.getAttrVal())) {
1453 										RoleMemberAttributeDataBo attribute = new RoleMemberAttributeDataBo();
1454 										attribute.setId(qualifier.getAttrDataId());
1455 										attribute.setAttributeValue(qualifier.getAttrVal());
1456 										attribute.setKimAttributeId(qualifier.getKimAttrDefnId());
1457 										attribute.setAssignedToId(qualifier.getRoleMemberId());
1458 										attribute.setKimTypeId(qualifier.getKimTypId());
1459 
1460 										updateAttrValIfNecessary(attribute);
1461 
1462 										if(ObjectUtils.isNotNull(origAttributes)){
1463 											for (RoleMemberAttributeDataBo origAttribute : origAttributes) {
1464 												if (origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), qualifier.getAttrDataId())) {
1465 													attribute.setVersionNumber(origAttribute.getVersionNumber());
1466 												}
1467 											}
1468 										}
1469 										if (attribute.getVersionNumber() != null || StringUtils.isNotBlank(qualifier.getAttrVal())) {
1470 											attributes.add(attribute);
1471 										}
1472 									//}
1473 								}
1474 							}
1475 							roleMemberImpl.setAttributeDetails(attributes);
1476 							roleMembers.add(roleMemberImpl);
1477 						}
1478 					}
1479 				//}
1480 			}
1481 		}
1482 		return roleMembers;
1483 	}
1484 
1485 	protected List<DelegateTypeBo> populateDelegations(IdentityManagementPersonDocument identityManagementPersonDocument){
1486 		List<DelegateTypeBo> origDelegations = getPersonDelegations(identityManagementPersonDocument.getPrincipalId());
1487 		List<DelegateTypeBo> kimDelegations = new ArrayList<DelegateTypeBo>();
1488 		DelegateTypeBo newKimDelegation;
1489 		DelegateTypeBo origDelegationImplTemp = null;
1490 		List<DelegateMemberBo> origMembers;
1491 		boolean activatingInactive = false;
1492 		String newDelegationIdAssigned = "";
1493 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getDelegations())){
1494 			for(RoleDocumentDelegation roleDocumentDelegation: identityManagementPersonDocument.getDelegations()){
1495 				newKimDelegation = new DelegateTypeBo();
1496 				KimCommonUtilsInternal.copyProperties(newKimDelegation, roleDocumentDelegation);
1497 				newKimDelegation.setRoleId(roleDocumentDelegation.getRoleId());
1498 				if(ObjectUtils.isNotNull(origDelegations)){
1499 					for(DelegateTypeBo origDelegationImpl: origDelegations){
1500 						if((origDelegationImpl.getRoleId()!=null && StringUtils.equals(origDelegationImpl.getRoleId(), newKimDelegation.getRoleId())) &&
1501 								(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId()))){
1502 							//TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
1503 							newDelegationIdAssigned = newKimDelegation.getDelegationId();
1504 							newKimDelegation.setDelegationId(origDelegationImpl.getDelegationId());
1505 							activatingInactive = true;
1506 						}
1507 						if(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
1508 							newKimDelegation.setVersionNumber(origDelegationImpl.getVersionNumber());
1509 							origDelegationImplTemp = origDelegationImpl;
1510 						}
1511 					}
1512 				}
1513 				origMembers = (origDelegationImplTemp==null || origDelegationImplTemp.getMembers()==null)?
1514 									new ArrayList<DelegateMemberBo>():origDelegationImplTemp.getMembers();
1515 				newKimDelegation.setMembers(getDelegationMembers(roleDocumentDelegation.getMembers(), origMembers, null, activatingInactive, newDelegationIdAssigned));
1516 				kimDelegations.add(newKimDelegation);
1517 				activatingInactive = false;
1518 			}
1519 		}
1520 		return kimDelegations;
1521 	}
1522 
1523     protected List <RoleMemberAttributeDataBo> getBlankRoleMemberAttrs(List <RoleMemberBo> rolePrncpls) {
1524 
1525 		List <RoleMemberAttributeDataBo>  blankRoleMemberAttrs = new ArrayList<RoleMemberAttributeDataBo>();
1526 		if(ObjectUtils.isNotNull(rolePrncpls)){
1527 			for (RoleMemberBo roleMbr : rolePrncpls) {
1528 				List <RoleMemberAttributeDataBo>  roleMemberAttrs = new ArrayList<RoleMemberAttributeDataBo>();
1529 				if (CollectionUtils.isNotEmpty(roleMbr.getAttributeDetails())) {
1530 					for (RoleMemberAttributeDataBo attr : roleMbr.getAttributeDetails()) {
1531 						if (StringUtils.isBlank(attr.getAttributeValue())) {
1532 							roleMemberAttrs.add(attr);
1533 						}
1534 					}
1535 					if (!roleMemberAttrs.isEmpty()) {
1536 						roleMbr.getAttributeDetails().removeAll(roleMemberAttrs);
1537 						blankRoleMemberAttrs.addAll(roleMemberAttrs);
1538 					}
1539 
1540 				}
1541 			}
1542 		}
1543 
1544 		return blankRoleMemberAttrs;
1545 
1546 	}
1547 
1548     protected List <RoleResponsibilityActionBo> populateRoleRspActions(IdentityManagementPersonDocument identityManagementPersonDocument) {
1549 //		List<RoleImpl> origRoles = getRolesForPrincipal(identityManagementPersonDocument.getPrincipalId());
1550 
1551 		List <RoleResponsibilityActionBo>  roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
1552 		if(CollectionUtils.isNotEmpty(identityManagementPersonDocument.getRoles())){
1553 			for (PersonDocumentRole role : identityManagementPersonDocument.getRoles()) {
1554 				if(CollectionUtils.isNotEmpty(role.getRolePrncpls())){
1555 					for (KimDocumentRoleMember roleMbr : role.getRolePrncpls()) {
1556 						if(CollectionUtils.isNotEmpty(roleMbr.getRoleRspActions())){
1557 							for (KimDocumentRoleResponsibilityAction roleRspAction : roleMbr.getRoleRspActions()) {
1558 								RoleResponsibilityActionBo entRoleRspAction = new RoleResponsibilityActionBo();
1559 								entRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
1560 								entRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
1561 								entRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
1562 								entRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
1563 								entRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
1564 								entRoleRspAction.setRoleResponsibilityId(roleRspAction.getRoleResponsibilityId());
1565 								List<RoleResponsibilityActionBo> actions = getRoleRspActions( roleMbr.getRoleMemberId());
1566 								if(ObjectUtils.isNotNull(actions)){
1567 									for(RoleResponsibilityActionBo orgRspAction : actions) {
1568 										if (orgRspAction.getId()!=null && StringUtils.equals(orgRspAction.getId(), roleRspAction.getRoleResponsibilityActionId())) {
1569 											entRoleRspAction.setVersionNumber(orgRspAction.getVersionNumber());
1570 										}
1571 									}
1572 								}
1573 								roleRspActions.add(entRoleRspAction);
1574 							}
1575 						}
1576 					}
1577 				}
1578 			}
1579 		}
1580 		return roleRspActions;
1581 
1582 	}
1583 
1584 	protected BusinessObjectService getBusinessObjectService() {
1585 		if ( businessObjectService == null ) {
1586 			businessObjectService = KRADServiceLocator.getBusinessObjectService();
1587 		}
1588 		return businessObjectService;
1589 	}
1590 
1591 	protected IdentityService getIdentityService() {
1592 		if ( identityService == null ) {
1593 			identityService = KimApiServiceLocator.getIdentityService();
1594 		}
1595 		return identityService;
1596 	}
1597 
1598 	protected GroupService getGroupService() {
1599 		if ( groupService == null ) {
1600 			groupService = KimApiServiceLocator.getGroupService();
1601 		}
1602 		return groupService;
1603 	}
1604 
1605 	protected DocumentHelperService getDocumentHelperService() {
1606 	    if ( documentHelperService == null ) {
1607 	        documentHelperService = KNSServiceLocator.getDocumentHelperService();
1608 		}
1609 	    return this.documentHelperService;
1610 	}
1611 
1612 	protected RoleService getRoleService() {
1613 	   	if(roleService == null){
1614 	   		roleService = KimApiServiceLocator.getRoleService();
1615     	}
1616 		return roleService;
1617 	}
1618 
1619 	public void setRoleService(RoleService roleService) {
1620 		this.roleService = roleService;
1621 	}
1622 
1623 	protected ResponsibilityService getResponsibilityService() {
1624 	   	if ( responsibilityService == null ) {
1625     		responsibilityService = KimApiServiceLocator.getResponsibilityService();
1626     	}
1627 		return responsibilityService;
1628 	}
1629 
1630 	public void setResponsibilityService(ResponsibilityService responsibilityService) {
1631 		this.responsibilityService = responsibilityService;
1632 	}
1633 
1634 
1635 	/* Role document methods */
1636 	@SuppressWarnings("unchecked")
1637 	public void loadRoleDoc(IdentityManagementRoleDocument identityManagementRoleDocument, Role role){
1638         Map<String, String> criteria = new HashMap<String, String>();
1639 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, role.getId());
1640 		RoleBo roleBo = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
1641 
1642         Map<String, String> subClassCriteria = new HashMap<String, String>();
1643 		subClassCriteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, role.getId());
1644 
1645 		identityManagementRoleDocument.setRoleId(roleBo.getId());
1646 		identityManagementRoleDocument.setKimType(KimTypeBo.to(roleBo.getKimRoleType()));
1647 		identityManagementRoleDocument.setRoleTypeName(roleBo.getKimRoleType().getName());
1648 		identityManagementRoleDocument.setRoleTypeId(roleBo.getKimTypeId());
1649 		identityManagementRoleDocument.setRoleName(roleBo.getName());
1650 		identityManagementRoleDocument.setRoleDescription(roleBo.getDescription());
1651 		identityManagementRoleDocument.setActive(roleBo.isActive());
1652 		identityManagementRoleDocument.setRoleNamespace(roleBo.getNamespaceCode());
1653 		identityManagementRoleDocument.setEditing(true);
1654 
1655 		identityManagementRoleDocument.setPermissions(loadPermissions(
1656                 (List<RolePermissionBo>) getBusinessObjectService().findMatching(RolePermissionBo.class,
1657                         subClassCriteria)));
1658         identityManagementRoleDocument.setResponsibilities(loadResponsibilities(
1659                 (List<RoleResponsibilityBo>) getBusinessObjectService().findMatching(RoleResponsibilityBo.class,
1660                         subClassCriteria)));
1661         loadResponsibilityRoleRspActions(identityManagementRoleDocument);
1662         identityManagementRoleDocument.setMembers(loadRoleMembers(identityManagementRoleDocument, roleBo.getMembers()));
1663         loadMemberRoleRspActions(identityManagementRoleDocument);
1664 		identityManagementRoleDocument.setDelegations(loadRoleDocumentDelegations(identityManagementRoleDocument, getRoleDelegations(roleBo.getId())));
1665 		//Since delegation members are flattened out on the UI...
1666 		setDelegationMembersInDocument(identityManagementRoleDocument);
1667 		identityManagementRoleDocument.setKimType(KimTypeBo.to(roleBo.getKimRoleType()));
1668     }
1669 
1670     @SuppressWarnings("unchecked")
1671     public void loadRoleMembersBasedOnSearch(IdentityManagementRoleDocument identityManagementRoleDocument,
1672                                                     String memberSearchValue){
1673 
1674         List<KimDocumentRoleMember> roleMembersRestricted = new ArrayList<KimDocumentRoleMember>();
1675         List<KimDocumentRoleMember> members = identityManagementRoleDocument.getMembers();
1676         for (KimDocumentRoleMember roleMember : members){
1677             String memberName = roleMember.getMemberName().toLowerCase();
1678             if (memberName.startsWith(memberSearchValue.toLowerCase())) {
1679                 roleMembersRestricted.add(roleMember);
1680             }
1681         }
1682 
1683         identityManagementRoleDocument.setSearchResultMembers(roleMembersRestricted);
1684     }
1685 
1686     @SuppressWarnings("unchecked")
1687     public void clearRestrictedRoleMembersSearchResults(IdentityManagementRoleDocument identityManagementRoleDocument) {
1688         List<KimDocumentRoleMember> roleMembersRestricted =  new ArrayList<KimDocumentRoleMember>();
1689         List<KimDocumentRoleMember> members = identityManagementRoleDocument.getMembers();
1690         identityManagementRoleDocument.setSearchResultMembers(roleMembersRestricted);
1691         identityManagementRoleDocument.setMembers(members);
1692     }
1693 
1694     public void setDelegationMembersInDocument(IdentityManagementRoleDocument identityManagementRoleDocument){
1695         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
1696             for(RoleDocumentDelegation delegation: identityManagementRoleDocument.getDelegations()){
1697                 if(CollectionUtils.isNotEmpty(delegation.getMembers())){
1698                     RoleMemberBo roleMember;
1699                     for(RoleDocumentDelegationMember member: delegation.getMembers()){
1700                         member.setDelegationTypeCode(delegation.getDelegationTypeCode());
1701                         if (StringUtils.isEmpty(member.getRoleMemberName())) {
1702                             roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
1703                             if(roleMember!=null){
1704                                 member.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
1705                                 member.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
1706                             }
1707                         }
1708                         member.setEdit(true);
1709                         identityManagementRoleDocument.getDelegationMembers().add(member);
1710                     }
1711                 }
1712             }
1713         }
1714     }
1715 
1716 	protected List<KimDocumentRoleResponsibility> loadResponsibilities(List<RoleResponsibilityBo> roleResponsibilities){
1717 		List<KimDocumentRoleResponsibility> documentRoleResponsibilities = new ArrayList<KimDocumentRoleResponsibility>();
1718 		if(ObjectUtils.isNotNull(roleResponsibilities)){
1719 			for(RoleResponsibilityBo roleResponsibility: roleResponsibilities){
1720 				if(roleResponsibility.isActive()) {
1721 					KimDocumentRoleResponsibility roleResponsibilityCopy = new KimDocumentRoleResponsibility();
1722 					KimCommonUtilsInternal.copyProperties(roleResponsibilityCopy, roleResponsibility);
1723 					roleResponsibilityCopy.setEdit(true);
1724 					documentRoleResponsibilities.add(roleResponsibilityCopy);
1725 				}
1726 			}
1727 		}
1728 		return documentRoleResponsibilities;
1729 	}
1730 
1731 	protected List<KimDocumentRolePermission> loadPermissions(List<RolePermissionBo> rolePermissions){
1732 		List<KimDocumentRolePermission> documentRolePermissions = new ArrayList<KimDocumentRolePermission>();
1733 		KimDocumentRolePermission rolePermissionCopy;
1734 		if(ObjectUtils.isNotNull(rolePermissions)){
1735 			for(RolePermissionBo rolePermission: rolePermissions){
1736 				if ( rolePermission.isActive() ) {
1737 					rolePermissionCopy = new KimDocumentRolePermission();
1738 					rolePermissionCopy.setRolePermissionId(rolePermission.getId());
1739 					rolePermissionCopy.setRoleId(rolePermission.getRoleId());
1740 					rolePermissionCopy.setPermissionId(rolePermission.getPermissionId());
1741 					rolePermissionCopy.setPermission(PermissionBo.to(rolePermission.getPermission()));
1742 					rolePermissionCopy.setEdit(true);
1743 					documentRolePermissions.add(rolePermissionCopy);
1744 				}
1745 			}
1746 		}
1747 		return documentRolePermissions;
1748 	}
1749 
1750     public void setMembersInDocument(IdentityManagementRoleDocument identityManagementRoleDocument){
1751         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
1752             Map<String, String> criteria = new HashMap<String, String>();
1753             criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, identityManagementRoleDocument.getRoleId());
1754             RoleBo roleBo = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
1755             List<RoleMemberBo> members = roleBo.getMembers();
1756             List<RoleMemberBo> membersToRemove = new ArrayList<RoleMemberBo>();
1757             boolean found = false;
1758             for(KimDocumentRoleMember modifiedMember : identityManagementRoleDocument.getModifiedMembers() ) {
1759                 for(RoleMemberBo member : members) {
1760                     if (modifiedMember.getRoleMemberId().equals(member.getId())) {
1761                         membersToRemove.add(member);
1762                         found = true;
1763                     }
1764                     if (found) break;
1765                 }
1766             }
1767             for(RoleMemberBo memberToRemove : membersToRemove ) {
1768                 members.remove(memberToRemove);
1769             }
1770 
1771             identityManagementRoleDocument.setMembers(loadRoleMembers(identityManagementRoleDocument, members));
1772             loadMemberRoleRspActions(identityManagementRoleDocument);
1773         }
1774     }
1775 
1776     protected List<KimDocumentRoleMember> loadRoleMembers(
1777             IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleMemberBo> members){
1778         List<KimDocumentRoleMember> pndMembers = new ArrayList<KimDocumentRoleMember>();
1779         KimDocumentRoleMember pndMember;
1780 
1781         Map<String, PrincipalBo> principalsForPrincipalIds = new HashMap<String, PrincipalBo>();
1782         Map<String, EntityName> entityNamesForPrincipals = new HashMap<String,EntityName>();
1783         Map<String, String> principalIdEntityIdMap = new HashMap<String,String>();
1784         List<String> roleMemberPrincipalIds = new ArrayList<String>();
1785 
1786         if(ObjectUtils.isNotNull(members)){
1787             for(RoleMemberBo roleMember : members) {
1788                 if (roleMember.getType().getCode().equals(KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode())) {
1789                     if ((!roleMemberPrincipalIds.contains(roleMember.getMemberId())) && roleMember.isActive()) {
1790                         roleMemberPrincipalIds.add(roleMember.getMemberId());
1791                     }
1792                 }
1793             }
1794 
1795             Collection<PrincipalBo> principals = findPrincipalsByPrincipalIds(roleMemberPrincipalIds);
1796             if (principals != null) {
1797                 for(PrincipalBo principal : principals) {
1798                     principalsForPrincipalIds.put(principal.getPrincipalId(), principal);
1799                     principalIdEntityIdMap.put(principal.getPrincipalId(), principal.getEntityId());
1800                 }
1801                 entityNamesForPrincipals = getUiDocumentServiceDAO().findEntityNamesForRole(
1802                         identityManagementRoleDocument.getRoleId());
1803             }
1804 
1805             Map<String, Group> roleGroupMembers = getUiDocumentServiceDAO().findGroupsForRole(identityManagementRoleDocument.getRoleId());
1806 
1807             for(RoleMemberBo member: members){
1808                 pndMember = new KimDocumentRoleMember();
1809                 pndMember.setActiveFromDate(member.getActiveFromDateValue());
1810                 pndMember.setActiveToDate(member.getActiveToDateValue());
1811                 pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
1812                 if(pndMember.isActive()){
1813                     pndMember.setRoleMemberId(member.getId());
1814                     pndMember.setRoleId(member.getRoleId());
1815                     pndMember.setMemberId(member.getMemberId());
1816                     pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
1817 
1818                     PrincipalBo principal =  principalsForPrincipalIds.get(member.getMemberId());
1819                     Group group =  null;
1820 
1821                     if (principal != null) {
1822                         pndMember.setMemberName(principal.getPrincipalName());
1823                     } else {
1824                         group =  roleGroupMembers.get(member.getMemberId());
1825                         if (group != null) {
1826                             pndMember.setMemberName(group.getName());
1827                             pndMember.setMemberNamespaceCode(group.getNamespaceCode());
1828                         } else {
1829                             pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
1830                         }
1831                     }
1832 
1833                     EntityName entityName =  entityNamesForPrincipals.get(principalIdEntityIdMap.get(member.getMemberId()));
1834                     if (entityName != null) {
1835                         pndMember.setMemberFullName(entityName.getFirstName() + " " + entityName.getLastName());
1836                     } else {
1837                         if (group != null) {
1838                             pndMember.setMemberFullName(group.getName());
1839                         } else {
1840                             pndMember.setMemberFullName(getMemberFullName(member.getType(), member.getMemberId()));
1841                         }
1842                     }
1843                     pndMember.setMemberTypeCode(member.getType().getCode());
1844                     pndMember.setQualifiers(loadRoleMemberQualifiers(identityManagementRoleDocument, member.getAttributeDetails()));
1845                     pndMember.setEdit(true);
1846                     pndMembers.add(pndMember);
1847                 }
1848             }
1849         }
1850         Collections.sort(pndMembers, identityManagementRoleDocument.getMemberMetaDataType());
1851         return pndMembers;
1852     }
1853 
1854     public Collection<PrincipalBo>  findPrincipalsByPrincipalIds(Collection<String> principalIds) {
1855         if (!principalIds.isEmpty()) {
1856             Map<String,Collection> prncplNameSearchCrit = new HashMap<String,Collection>();
1857             prncplNameSearchCrit.put("PRNCPL_ID", principalIds);
1858             return getBusinessObjectService().findMatching(PrincipalBo.class, prncplNameSearchCrit);
1859         } else {
1860             return null;
1861         }
1862     }
1863 
1864     protected void loadResponsibilityRoleRspActions(IdentityManagementRoleDocument identityManagementRoleDocument){
1865 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
1866 			for(KimDocumentRoleResponsibility responsibility: identityManagementRoleDocument.getResponsibilities()){
1867 				responsibility.getRoleRspActions().addAll(loadKimDocumentRoleRespActions(
1868 						getRoleResponsibilityActionImpls(responsibility.getRoleResponsibilityId())));
1869 			}
1870 		}
1871 	}
1872 
1873     @SuppressWarnings("unchecked")
1874     protected RoleResponsibilityActionBo getRoleResponsibilityActionImpl(String roleResponsibilityActionId){
1875         Map<String, String> criteria = new HashMap<String, String>();
1876         criteria.put(KimConstants.PrimaryKeyConstants.ID, roleResponsibilityActionId);
1877         return getBusinessObjectService().findByPrimaryKey(RoleResponsibilityActionBo.class, criteria);
1878     }
1879 
1880 	@SuppressWarnings("unchecked")
1881 	protected List<RoleResponsibilityActionBo> getRoleResponsibilityActionImpls(String roleResponsibilityId){
1882 		Map<String, String> criteria = new HashMap<String, String>();
1883 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, "*");
1884 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_RESPONSIBILITY_ID, roleResponsibilityId);
1885 		return (List<RoleResponsibilityActionBo>)
1886 			getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
1887 	}
1888 
1889 	@SuppressWarnings("unchecked")
1890 	public List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActionImpls(String roleMemberId){
1891 		Map<String, String> criteria = new HashMap<String, String>(1);
1892 		criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId);
1893 		return (List<RoleResponsibilityActionBo>)
1894 			getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria);
1895 	}
1896 
1897 	protected void loadMemberRoleRspActions(IdentityManagementRoleDocument identityManagementRoleDocument){
1898 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getMembers())){
1899 			for(KimDocumentRoleMember member: identityManagementRoleDocument.getMembers()){
1900 				member.getRoleRspActions().addAll(loadKimDocumentRoleRespActions(
1901 						getRoleMemberResponsibilityActionImpls(member.getRoleMemberId()) ) );
1902 			}
1903 		}
1904 	}
1905 
1906 	protected List<KimDocumentRoleResponsibilityAction> loadKimDocumentRoleRespActions(
1907 			List<RoleResponsibilityActionBo> roleRespActionImpls){
1908 		List<KimDocumentRoleResponsibilityAction> documentRoleRespActions = new ArrayList<KimDocumentRoleResponsibilityAction>();
1909 		KimDocumentRoleResponsibilityAction documentRoleRespAction;
1910 		if(ObjectUtils.isNotNull(roleRespActionImpls)){
1911 			for(RoleResponsibilityActionBo roleRespActionImpl: roleRespActionImpls){
1912 				documentRoleRespAction = new KimDocumentRoleResponsibilityAction();
1913 				KimCommonUtilsInternal.copyProperties(documentRoleRespAction, roleRespActionImpl);
1914 
1915                 //primary key has different name in these objects!  we need to make sure to copy it over
1916                 documentRoleRespAction.setRoleResponsibilityActionId(roleRespActionImpl.getId());
1917 
1918 				// handle the roleResponsibility object being null since not all may be defined when ID value is "*"
1919 				if ( ObjectUtils.isNotNull(roleRespActionImpl.getRoleResponsibility()) ) {
1920 					documentRoleRespAction.setKimResponsibility(roleRespActionImpl.getRoleResponsibility().getKimResponsibility());
1921 				}
1922 				documentRoleRespActions.add(documentRoleRespAction);
1923 			}
1924 		}
1925 		return documentRoleRespActions;
1926 	}
1927 
1928     public BusinessObject getMember(MemberType memberType, String memberId){
1929         Class<? extends BusinessObject> roleMemberTypeClass = null;
1930         String roleMemberIdName = "";
1931     	if(MemberType.PRINCIPAL.equals(memberType)) {
1932         	roleMemberTypeClass = PrincipalBo.class;
1933         	roleMemberIdName = KimConstants.PrimaryKeyConstants.PRINCIPAL_ID;
1934         } else if(MemberType.GROUP.equals(memberType)){
1935         	roleMemberTypeClass = GroupBo.class;
1936         	roleMemberIdName = KimConstants.PrimaryKeyConstants.GROUP_ID;
1937         } else if(MemberType.ROLE.equals(memberType)){
1938         	roleMemberTypeClass = RoleBo.class;
1939         	roleMemberIdName = KimConstants.PrimaryKeyConstants.ROLE_ID;
1940         }
1941         Map<String, String> criteria = new HashMap<String, String>();
1942         criteria.put(roleMemberIdName, memberId);
1943         return getBusinessObjectService().findByPrimaryKey(roleMemberTypeClass, criteria);
1944     }
1945 
1946 	public String getMemberName(MemberType memberType, String memberId){
1947 		if (memberType == null || StringUtils.isEmpty(memberId)) { return "";}
1948 		BusinessObject member = getMember(memberType, memberId);
1949 		if (member == null) { //not a REAL principal, try to fake the name
1950 			String fakeName = "";
1951 			Principal kp = KimApiServiceLocator.getIdentityService().getPrincipal(memberId);
1952 			if(kp != null && kp.getPrincipalName() != null && !"".equals(kp.getPrincipalName())){
1953 				fakeName = kp.getPrincipalName();
1954 			}
1955 
1956 			return fakeName;
1957 		}
1958 		return getMemberName(memberType, member);
1959 	}
1960 
1961 	public String getMemberFullName(MemberType memberType, String memberId){
1962 		if(memberType == null || StringUtils.isEmpty(memberId)) {return "";}
1963 	   	String memberFullName = "";
1964         if(MemberType.PRINCIPAL.equals(memberType)){
1965         	Principal principalInfo = null;
1966         	principalInfo = getIdentityService().getPrincipal(memberId);
1967         	if (principalInfo != null) {
1968         		String principalName = principalInfo.getPrincipalName();
1969         		Person psn = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName);
1970         		if (psn != null) {
1971         		    memberFullName = psn.getFirstName() + " " + psn.getLastName();
1972                 }
1973         	}        	        	
1974         } else if(MemberType.GROUP.equals(memberType)){
1975         	Group group = null;
1976         	group = getGroupService().getGroup(memberId);
1977         	if (group != null) {
1978         		memberFullName = group.getName();
1979         	}
1980         	
1981         } else if(MemberType.ROLE.equals(memberType)){
1982         	Role role = getRoleService().getRole(memberId);
1983         	memberFullName = role.getName();
1984         }
1985         return memberFullName;
1986 	}
1987 
1988 	public String getMemberNamespaceCode(MemberType memberType, String memberId){
1989 		if(memberType == null || StringUtils.isEmpty(memberId)) {return "";}
1990     	String roleMemberNamespaceCode = "";
1991         if(MemberType.PRINCIPAL.equals(memberType)){
1992         	roleMemberNamespaceCode = "";
1993         } else if(MemberType.GROUP.equals(memberType)){
1994         	Group groupInfo = getGroupService().getGroup(memberId);
1995         	if (groupInfo!= null) {
1996         		roleMemberNamespaceCode = groupInfo.getNamespaceCode();
1997         	}
1998         } else if(MemberType.ROLE.equals(memberType)){
1999         	Role role = getRoleService().getRole(memberId);
2000         	if (role != null) {
2001         		roleMemberNamespaceCode = role.getNamespaceCode();
2002         	}        	
2003         }
2004         return roleMemberNamespaceCode;
2005 	}
2006 
2007     public String getMemberIdByName(MemberType memberType, String memberNamespaceCode, String memberName){
2008     	String memberId = "";
2009         if(MemberType.PRINCIPAL.equals(memberType)){
2010             Principal principal = getIdentityService().getPrincipalByPrincipalName(memberName);
2011             if(principal!=null) {
2012                 memberId = principal.getPrincipalId();
2013             }
2014 
2015        } else if(MemberType.GROUP.equals(memberType)){
2016         	Group groupInfo = getGroupService().getGroupByNamespaceCodeAndName(memberNamespaceCode, memberName);
2017         	if (groupInfo!=null) {
2018                 memberId = groupInfo.getId();
2019             }
2020 
2021         } else if(MemberType.ROLE.equals(memberType)){
2022         	memberId = getRoleService().getRoleIdByNamespaceCodeAndName(memberNamespaceCode, memberName);
2023         }
2024         return memberId;
2025     }
2026 
2027     public String getMemberName(MemberType memberType, BusinessObject member){
2028     	String roleMemberName = "";
2029         if(MemberType.PRINCIPAL.equals(memberType)){
2030         	roleMemberName = ((PrincipalBo)member).getPrincipalName();
2031         } else if(MemberType.GROUP.equals(memberType)){
2032         	roleMemberName = ((GroupBo)member).getName();
2033         } else if(MemberType.ROLE.equals(memberType)){
2034         	roleMemberName = ((RoleBo)member).getName();
2035         }
2036         return roleMemberName;
2037     }
2038 
2039     public String getMemberNamespaceCode(MemberType memberType, BusinessObject member){
2040     	String roleMemberNamespaceCode = "";
2041         if(MemberType.PRINCIPAL.equals(memberType)){
2042         	roleMemberNamespaceCode = "";
2043         } else if(MemberType.GROUP.equals(memberType)){
2044         	roleMemberNamespaceCode = ((GroupBo)member).getNamespaceCode();
2045         } else if(MemberType.ROLE.equals(memberType)){
2046         	roleMemberNamespaceCode = ((RoleBo)member).getNamespaceCode();
2047         }
2048         return roleMemberNamespaceCode;
2049     }
2050 
2051     protected List<KimDocumentRoleQualifier> loadRoleMemberQualifiers(IdentityManagementRoleDocument identityManagementRoleDocument,
2052 			List<RoleMemberAttributeDataBo> attributeDataList){
2053 		List<KimDocumentRoleQualifier> pndMemberRoleQualifiers = new ArrayList<KimDocumentRoleQualifier>();
2054 		KimDocumentRoleQualifier pndMemberRoleQualifier;
2055 
2056 		// add all attributes from attributeDataList
2057 		if(attributeDataList!=null){
2058 			for(RoleMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2059 				pndMemberRoleQualifier = new KimDocumentRoleQualifier();
2060 				pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
2061 				pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
2062 				pndMemberRoleQualifier.setRoleMemberId(memberRoleQualifier.getAssignedToId());
2063 				pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
2064 				pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
2065 				pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
2066 				formatAttrValIfNecessary(pndMemberRoleQualifier);
2067 				pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2068 			}
2069 		}
2070 		// also add any attributes already in the document that are not in the attributeDataList
2071 		int countOfOriginalAttributesNotPresent = 0;
2072 		List<KimDocumentRoleQualifier> fillerRoleQualifiers = new ArrayList<KimDocumentRoleQualifier>();
2073 
2074 		List<KimAttributeField> origAttributes = identityManagementRoleDocument.getDefinitions();
2075 		if ( origAttributes != null ) {
2076 			for(KimAttributeField key: origAttributes) {
2077 				boolean attributePresent = false;
2078 				String origAttributeId = identityManagementRoleDocument.getKimAttributeDefnId(key);
2079 				if(attributeDataList!=null){
2080 					for(RoleMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2081 						if(origAttributeId!=null && StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
2082 							attributePresent = true;
2083 							break;
2084 						}
2085 					}
2086 				}
2087 				if(!attributePresent){
2088 					countOfOriginalAttributesNotPresent++;
2089 					pndMemberRoleQualifier = new KimDocumentRoleQualifier();
2090 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
2091 					pndMemberRoleQualifier.refreshReferenceObject("kimAttribute");
2092 					fillerRoleQualifiers.add(pndMemberRoleQualifier);
2093 				}
2094 			}
2095 
2096 			if(countOfOriginalAttributesNotPresent != origAttributes.size()) {
2097 				pndMemberRoleQualifiers.addAll(fillerRoleQualifiers);
2098 			}
2099 		}
2100 		return pndMemberRoleQualifiers;
2101 	}
2102 
2103     @SuppressWarnings("unchecked")
2104 	public List<DelegateTypeBo> getRoleDelegations(String roleId){
2105 		if(roleId==null) {
2106 			return new ArrayList<DelegateTypeBo>();
2107         }
2108 		Map<String,String> criteria = new HashMap<String,String>(1);
2109 		criteria.put("roleId", roleId);
2110 		return (List<DelegateTypeBo>)getBusinessObjectService().findMatching(DelegateTypeBo.class, criteria);
2111 	}
2112 
2113     protected List<RoleDocumentDelegation> loadRoleDocumentDelegations(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateTypeBo> delegations){
2114 		List<RoleDocumentDelegation> delList = new ArrayList<RoleDocumentDelegation>();
2115 		RoleDocumentDelegation documentDelegation;
2116 		if(ObjectUtils.isNotNull(delegations)){
2117 			for(DelegateTypeBo del: delegations){
2118 				documentDelegation = new RoleDocumentDelegation();
2119 				documentDelegation.setActive(del.isActive());
2120 				if(documentDelegation.isActive()){
2121 					documentDelegation.setDelegationId(del.getDelegationId());
2122 					documentDelegation.setDelegationTypeCode(del.getDelegationTypeCode());
2123 					documentDelegation.setKimTypeId(del.getKimTypeId());
2124 					documentDelegation.setMembers(loadDelegationMembers(identityManagementRoleDocument, del.getMembers()));
2125 					documentDelegation.setRoleId(del.getRoleId());
2126 					documentDelegation.setEdit(true);
2127 					delList.add(documentDelegation);
2128 				}
2129 			}
2130 		}
2131 		return delList;
2132 	}
2133 
2134     protected List<RoleDocumentDelegationMember> loadDelegationMembers(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateMemberBo> members){
2135 		List<RoleDocumentDelegationMember> pndMembers = new ArrayList<RoleDocumentDelegationMember>();
2136 		RoleDocumentDelegationMember pndMember;
2137 		RoleMemberBo roleMember;
2138 		if(ObjectUtils.isNotNull(members)){
2139 			for(DelegateMemberBo member: members){
2140 				pndMember = new RoleDocumentDelegationMember();
2141 				pndMember.setActiveFromDate(member.getActiveFromDateValue());
2142 				pndMember.setActiveToDate(member.getActiveToDateValue());
2143 				pndMember.setActive(member.isActive(new Timestamp(System.currentTimeMillis())));
2144 				if(pndMember.isActive()){
2145 					//KimCommonUtilsInternal.copyProperties(pndMember, member);
2146                     pndMember.setDelegationId(member.getDelegationId());
2147                     pndMember.setDelegationMemberId(member.getDelegationMemberId());
2148                     pndMember.setDelegationTypeCode(member.getType().getCode());
2149                     pndMember.setRoleMemberId(member.getRoleMemberId());
2150                     pndMember.setMemberId(member.getMemberId());
2151                     pndMember.setMemberTypeCode(member.getType().getCode());
2152 
2153 					roleMember = getRoleMemberForRoleMemberId(member.getRoleMemberId());
2154 					if(roleMember!=null){
2155 						pndMember.setRoleMemberName(getMemberName(roleMember.getType(), roleMember.getMemberId()));
2156 						pndMember.setRoleMemberNamespaceCode(getMemberNamespaceCode(roleMember.getType(), roleMember.getMemberId()));
2157 					}
2158 					pndMember.setMemberNamespaceCode(getMemberNamespaceCode(member.getType(), member.getMemberId()));
2159 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
2160 					pndMember.setEdit(true);
2161 					pndMember.setQualifiers(loadDelegationMemberQualifiers(identityManagementRoleDocument, member.getAttributeDetails()));
2162 					pndMembers.add(pndMember);
2163 				}
2164 			}
2165 		}
2166 		return pndMembers;
2167 	}
2168 
2169     protected RoleMemberBo getRoleMemberForRoleMemberId(String roleMemberId){
2170 		Map<String,String> criteria = new HashMap<String,String>( 2 );
2171 		criteria.put(KimConstants.PrimaryKeyConstants.ID, roleMemberId);
2172 		return getBusinessObjectService().findByPrimaryKey(RoleMemberBo.class, criteria);
2173     }
2174 
2175     protected List<RoleDocumentDelegationMemberQualifier> loadDelegationMemberQualifiers(IdentityManagementRoleDocument identityManagementRoleDocument,
2176 			List<DelegateMemberAttributeDataBo> attributeDataList){
2177 		List<RoleDocumentDelegationMemberQualifier> pndMemberRoleQualifiers = new ArrayList<RoleDocumentDelegationMemberQualifier>();
2178 		RoleDocumentDelegationMemberQualifier pndMemberRoleQualifier;
2179 		List<KimAttributeField> origAttributes = identityManagementRoleDocument.getDefinitions();
2180 		boolean attributePresent = false;
2181 		String origAttributeId;
2182 		if(origAttributes!=null){
2183 			for(KimAttributeField key: origAttributes) {
2184 				origAttributeId = identityManagementRoleDocument.getKimAttributeDefnId(key);
2185 				if(attributeDataList!=null){
2186 					for(DelegateMemberAttributeDataBo memberRoleQualifier: attributeDataList){
2187 						if(origAttributeId!=null && StringUtils.equals(origAttributeId, memberRoleQualifier.getKimAttribute().getId())){
2188 							pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
2189 							pndMemberRoleQualifier.setAttrDataId(memberRoleQualifier.getId());
2190 							pndMemberRoleQualifier.setAttrVal(memberRoleQualifier.getAttributeValue());
2191 							pndMemberRoleQualifier.setDelegationMemberId(memberRoleQualifier.getAssignedToId());
2192 							pndMemberRoleQualifier.setKimTypId(memberRoleQualifier.getKimTypeId());
2193 							pndMemberRoleQualifier.setKimAttrDefnId(memberRoleQualifier.getKimAttributeId());
2194 							pndMemberRoleQualifier.setKimAttribute(memberRoleQualifier.getKimAttribute());
2195 							pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2196 							attributePresent = true;
2197 						}
2198 					}
2199 				}
2200 				if(!attributePresent){
2201 					pndMemberRoleQualifier = new RoleDocumentDelegationMemberQualifier();
2202 					pndMemberRoleQualifier.setKimAttrDefnId(origAttributeId);
2203 					pndMemberRoleQualifier.refreshReferenceObject("kimAttribute");
2204 					pndMemberRoleQualifiers.add(pndMemberRoleQualifier);
2205 				}
2206 				attributePresent = false;
2207 			}
2208 		}
2209 		return pndMemberRoleQualifiers;
2210 	}
2211 
2212 	/**
2213 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
2214 	 */
2215 	@SuppressWarnings("unchecked")
2216 	public void saveRole(IdentityManagementRoleDocument identityManagementRoleDocument) {
2217         RoleBo roleBo = new RoleBo();
2218 		Map<String, String> criteria = new HashMap<String, String>();
2219 		String roleId = identityManagementRoleDocument.getRoleId();
2220 		criteria.put(KimConstants.PrimaryKeyConstants.ID, roleId);
2221 		RoleBo origRole = getBusinessObjectService().findByPrimaryKey(RoleBo.class, criteria);
2222 
2223 		List<RolePermissionBo> origRolePermissions = new ArrayList<RolePermissionBo>();
2224 		List<RoleResponsibilityBo> origRoleResponsibilities = new ArrayList<RoleResponsibilityBo>();
2225 		List<RoleMemberBo> origRoleMembers = new ArrayList<RoleMemberBo>();
2226         List<DelegateTypeBo> origRoleDelegations = new ArrayList<DelegateTypeBo>();
2227 
2228 		roleBo.setId(identityManagementRoleDocument.getRoleId());
2229 		roleBo.setKimTypeId(identityManagementRoleDocument.getRoleTypeId());
2230 		roleBo.setNamespaceCode(identityManagementRoleDocument.getRoleNamespace());
2231 		roleBo.setName(identityManagementRoleDocument.getRoleName());
2232 		roleBo.setDescription(identityManagementRoleDocument.getRoleDescription());
2233 
2234 		if (origRole == null) {
2235 			origRole = new RoleBo();
2236 			roleBo.setActive(true);
2237 		} else {
2238 			roleBo.setActive(identityManagementRoleDocument.isActive());
2239 			roleBo.setVersionNumber(origRole.getVersionNumber());
2240             Map<String, String> altCriteria = new HashMap<String, String>();
2241             altCriteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId);
2242 			origRolePermissions = new ArrayList<RolePermissionBo>(getBusinessObjectService().findMatching(RolePermissionBo.class, altCriteria));
2243             origRoleResponsibilities = (List<RoleResponsibilityBo>)getBusinessObjectService().findMatching(RoleResponsibilityBo.class, altCriteria);
2244             origRoleMembers = (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, altCriteria);
2245             origRoleDelegations = (List<DelegateTypeBo>)getBusinessObjectService().findMatching(DelegateTypeBo.class, altCriteria);
2246 		}
2247 
2248 		if( getKimTypeInfoService().getKimType(identityManagementRoleDocument.getRoleTypeId()) == null ) {
2249 			LOG.error( "Kim type not found for:"+identityManagementRoleDocument.getRoleTypeId(), new Throwable() );
2250 		}
2251 
2252 		List<PersistableBusinessObject> bos = new ArrayList<PersistableBusinessObject>();
2253 
2254         bos.add(roleBo);
2255 		bos.addAll(getRolePermissions(identityManagementRoleDocument, origRolePermissions));
2256 		bos.addAll(getRoleResponsibilities(identityManagementRoleDocument, origRoleResponsibilities));
2257 		bos.addAll(getRoleResponsibilitiesActions(identityManagementRoleDocument));
2258 		String initiatorPrincipalId = getInitiatorPrincipalId(identityManagementRoleDocument);
2259 
2260 		if(canAssignToRole(identityManagementRoleDocument, initiatorPrincipalId)){
2261 			List<RoleMemberBo> newRoleMembersList = getRoleMembers(identityManagementRoleDocument, origRoleMembers);
2262             roleBo.setMembers(newRoleMembersList);
2263 
2264 			bos.addAll(getRoleMemberResponsibilityActions(newRoleMembersList));
2265 			//bos.addAll(getRoleMemberResponsibilityActions(identityManagementRoleDocument));
2266 			bos.addAll(getRoleDelegations(identityManagementRoleDocument, origRoleDelegations));
2267 		}
2268        // bos.add(roleBo);
2269 		getBusinessObjectService().save(bos);
2270 		KimImplServiceLocator.getResponsibilityInternalService().updateActionRequestsForResponsibilityChange(getChangedRoleResponsibilityIds(identityManagementRoleDocument, origRoleResponsibilities));
2271 		if(!roleBo.isActive()){
2272 			// when a role is inactivated, inactivate the memberships of principals, groups, and roles in
2273 			// that role, delegations, and delegation members, and that roles memberships in other roles
2274 			KimImplServiceLocator.getRoleInternalService().roleInactivated(identityManagementRoleDocument.getRoleId());
2275 		}
2276 	}
2277 
2278 	protected List<RolePermissionBo> getRolePermissions(
2279 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RolePermissionBo> origRolePermissions){
2280 		List<RolePermissionBo> rolePermissions = new ArrayList<RolePermissionBo>();
2281 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getPermissions())){
2282 			for(KimDocumentRolePermission documentRolePermission: identityManagementRoleDocument.getPermissions()){
2283 				RolePermissionBo newRolePermission = new RolePermissionBo();
2284 				newRolePermission.setId(documentRolePermission.getRolePermissionId());
2285 				newRolePermission.setRoleId(identityManagementRoleDocument.getRoleId());
2286 				newRolePermission.setPermissionId(documentRolePermission.getPermissionId());
2287 				newRolePermission.setActive( documentRolePermission.isActive() );
2288 
2289 				newRolePermission.setActive(documentRolePermission.isActive());
2290 				if (ObjectUtils.isNotNull(origRolePermissions)) {
2291                     for (RolePermissionBo origPermissionImpl : origRolePermissions) {
2292                         if (!StringUtils.equals(origPermissionImpl.getRoleId(), newRolePermission.getRoleId())
2293                                 && StringUtils.equals(origPermissionImpl.getPermissionId(), newRolePermission.getPermissionId())
2294                                 && origPermissionImpl.isActive()
2295                                 && newRolePermission.isActive()) {
2296 							newRolePermission.setId(origPermissionImpl.getId());
2297 						}
2298 						if(origPermissionImpl.getId()!=null && StringUtils.equals(origPermissionImpl.getId(), newRolePermission.getId())){
2299 							newRolePermission.setVersionNumber(origPermissionImpl.getVersionNumber());
2300                             newRolePermission.setObjectId(origPermissionImpl.getObjectId());
2301 						}
2302 					}
2303 				}
2304 				rolePermissions.add(newRolePermission);
2305 			}
2306 		}
2307 		return rolePermissions;
2308 	}
2309 
2310 	protected List<RoleResponsibilityBo> getRoleResponsibilities(
2311 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleResponsibilityBo> origRoleResponsibilities){
2312 		List<RoleResponsibilityBo> roleResponsibilities = new ArrayList<RoleResponsibilityBo>();
2313 		RoleResponsibilityBo newRoleResponsibility;
2314 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
2315 			for(KimDocumentRoleResponsibility documentRoleResponsibility: identityManagementRoleDocument.getResponsibilities()){
2316 				newRoleResponsibility = new RoleResponsibilityBo();
2317 				KimCommonUtilsInternal.copyProperties(newRoleResponsibility, documentRoleResponsibility);
2318 				newRoleResponsibility.setActive(documentRoleResponsibility.isActive());
2319 				newRoleResponsibility.setRoleId(identityManagementRoleDocument.getRoleId());
2320 				if(ObjectUtils.isNotNull(origRoleResponsibilities)){
2321 					for(RoleResponsibilityBo origResponsibilityImpl: origRoleResponsibilities){
2322 						if(!StringUtils.equals(origResponsibilityImpl.getRoleId(), newRoleResponsibility.getRoleId()) &&
2323 								StringUtils.equals(origResponsibilityImpl.getResponsibilityId(), newRoleResponsibility.getResponsibilityId()) &&
2324 								!origResponsibilityImpl.isActive() && newRoleResponsibility.isActive()){
2325 							newRoleResponsibility.setRoleResponsibilityId(origResponsibilityImpl.getRoleResponsibilityId());
2326 						}
2327 						if(origResponsibilityImpl.getRoleResponsibilityId()!=null && StringUtils.equals(origResponsibilityImpl.getRoleResponsibilityId(), newRoleResponsibility.getRoleResponsibilityId())) {
2328                             newRoleResponsibility.setVersionNumber(origResponsibilityImpl.getVersionNumber());
2329                             newRoleResponsibility.setObjectId(origResponsibilityImpl.getObjectId());
2330                         }
2331 					}
2332 				}
2333 				roleResponsibilities.add(newRoleResponsibility);
2334 			}
2335 		}
2336 		return roleResponsibilities;
2337 	}
2338 
2339 
2340 	protected List <RoleResponsibilityActionBo> getRoleResponsibilitiesActions(
2341 			IdentityManagementRoleDocument identityManagementRoleDocument){
2342 		List <RoleResponsibilityActionBo>  roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2343 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
2344 		// loop over the responsibilities assigned to the role
2345 			for(KimDocumentRoleResponsibility roleResponsibility : identityManagementRoleDocument.getResponsibilities()){
2346 				// only process if the actions are not assigned at the role member level
2347 				if(!getResponsibilityInternalService().areActionsAtAssignmentLevelById(roleResponsibility.getResponsibilityId())){
2348 					List<KimDocumentRoleResponsibilityAction> documentRoleResponsibilityActions = roleResponsibility.getRoleRspActions();
2349 					if( ObjectUtils.isNotNull(documentRoleResponsibilityActions)
2350 							&& !documentRoleResponsibilityActions.isEmpty()
2351 							&& StringUtils.isNotBlank(documentRoleResponsibilityActions.get(0).getRoleResponsibilityActionId() ) ) {
2352 						RoleResponsibilityActionBo roleRspAction = new RoleResponsibilityActionBo();
2353 						roleRspAction.setId(documentRoleResponsibilityActions.get(0).getRoleResponsibilityActionId());
2354 						roleRspAction.setActionPolicyCode(documentRoleResponsibilityActions.get(0).getActionPolicyCode());
2355 						roleRspAction.setActionTypeCode(documentRoleResponsibilityActions.get(0).getActionTypeCode());
2356 						roleRspAction.setPriorityNumber(documentRoleResponsibilityActions.get(0).getPriorityNumber());
2357 						roleRspAction.setForceAction(documentRoleResponsibilityActions.get(0).isForceAction());
2358 						roleRspAction.setRoleMemberId("*");
2359 						roleRspAction.setRoleResponsibilityId(documentRoleResponsibilityActions.get(0).getRoleResponsibilityId());
2360 						updateResponsibilityActionVersionNumber(roleRspAction, getRoleResponsibilityActionImpl(roleRspAction.getId()));
2361 						roleRspActions.add(roleRspAction);
2362 					}
2363 				}
2364 			}
2365 		}
2366 		return roleRspActions;
2367 	}
2368 
2369 	// FIXME: This should be pulling by the PK, not using another method which pulls multiple records and then finds
2370 	// the right one here!
2371 	protected void updateResponsibilityActionVersionNumber(RoleResponsibilityActionBo newRoleRspAction,
2372 			RoleResponsibilityActionBo origRoleRespActionImpl){
2373 		if(ObjectUtils.isNotNull(origRoleRespActionImpl)){
2374             if(origRoleRespActionImpl.getId()!=null && StringUtils.equals(origRoleRespActionImpl.getId(), newRoleRspAction.getId())) {
2375                 newRoleRspAction.setVersionNumber(origRoleRespActionImpl.getVersionNumber());
2376                 newRoleRspAction.setObjectId(origRoleRespActionImpl.getObjectId());
2377             }
2378 		}
2379 	}
2380 
2381 	protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(List<RoleMemberBo> newRoleMembersList){
2382 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2383 		if(ObjectUtils.isNotNull(newRoleMembersList)){
2384 			for(RoleMemberBo roleMember: newRoleMembersList){
2385 				roleRspActions.addAll(roleMember.getRoleRspActions());
2386 			}
2387 		}
2388 		return roleRspActions;
2389 	}
2390 
2391 	/*protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(IdentityManagementRoleDocument identityManagementRoleDocument){
2392 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2393 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getMembers())){
2394 			for(KimDocumentRoleMember roleMember: identityManagementRoleDocument.getMembers()){
2395 				for(KimDocumentRoleResponsibilityAction roleRspAction : roleMember.getRoleRspActions()){
2396 					RoleResponsibilityActionBo entRoleRspAction = new RoleResponsibilityActionBo();
2397 					entRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
2398 					entRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
2399 					entRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
2400 					entRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
2401 					entRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
2402 					entRoleRspAction.setForceAction(roleRspAction.isForceAction());
2403 					entRoleRspAction.setRoleResponsibilityId(roleRspAction.getRoleResponsibilityId());
2404 					List<RoleResponsibilityActionBo> actions = getRoleRspActions(roleMember.getRoleMemberId());
2405 					if(ObjectUtils.isNotNull(actions)){
2406 						for(RoleResponsibilityActionBo orgRspAction : actions) {
2407 							if (orgRspAction.getId()!=null && StringUtils.equals(orgRspAction.getId(), roleRspAction.getRoleResponsibilityActionId())) {
2408 								entRoleRspAction.setVersionNumber(orgRspAction.getVersionNumber());
2409 							}
2410 						}
2411 					}
2412 					roleRspActions.add(entRoleRspAction);
2413 				}
2414 			}
2415 		}
2416 		return roleRspActions;
2417 	}*/
2418 
2419     protected List<RoleMemberBo> getRoleMembers(IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleMemberBo> origRoleMembers){
2420         List<RoleMemberBo> roleMembers = new ArrayList<RoleMemberBo>();
2421         RoleMemberBo newRoleMember;
2422         RoleMemberBo origRoleMemberImplTemp;
2423         List<RoleMemberAttributeDataBo> origAttributes;
2424         boolean activatingInactive = false;
2425         String newRoleMemberIdAssigned = "";
2426 
2427         identityManagementRoleDocument.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(identityManagementRoleDocument.getRoleTypeId()));
2428         KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(identityManagementRoleDocument.getKimType());
2429 
2430         if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getModifiedMembers())){
2431             for(KimDocumentRoleMember documentRoleMember: identityManagementRoleDocument.getModifiedMembers()){
2432                 origRoleMemberImplTemp = null;
2433 
2434                 newRoleMember = new RoleMemberBo();
2435                 KimCommonUtilsInternal.copyProperties(newRoleMember, documentRoleMember);
2436                 newRoleMember.setId(documentRoleMember.getRoleMemberId());
2437                 newRoleMember.setRoleId(identityManagementRoleDocument.getRoleId());
2438                 if(ObjectUtils.isNotNull(origRoleMembers)){
2439                     for(RoleMemberBo origRoleMemberImpl: origRoleMembers){
2440                         if((origRoleMemberImpl.getRoleId()!=null && StringUtils.equals(origRoleMemberImpl.getRoleId(), newRoleMember.getRoleId())) &&
2441                             (origRoleMemberImpl.getMemberId()!=null && StringUtils.equals(origRoleMemberImpl.getMemberId(), newRoleMember.getMemberId())) &&
2442                             (origRoleMemberImpl.getType()!=null && org.apache.commons.lang.ObjectUtils.equals(origRoleMemberImpl.getType(), newRoleMember.getType())) &&
2443                             !origRoleMemberImpl.isActive() &&
2444                             !kimTypeService.validateUniqueAttributes(
2445                                     identityManagementRoleDocument.getKimType().getId(),
2446                                     documentRoleMember.getQualifierAsMap(), origRoleMemberImpl.getAttributes()).isEmpty()) {
2447 
2448                             //TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
2449 
2450                             newRoleMemberIdAssigned = newRoleMember.getId();
2451                             newRoleMember.setId(origRoleMemberImpl.getId());
2452                             activatingInactive = true;
2453                         }
2454                         if(origRoleMemberImpl.getId()!=null && StringUtils.equals(origRoleMemberImpl.getId(), newRoleMember.getId())){
2455                             newRoleMember.setVersionNumber(origRoleMemberImpl.getVersionNumber());
2456                             origRoleMemberImplTemp = origRoleMemberImpl;
2457 
2458                             // Obtain role rsp actions from db and assign to origRoleMemberImplTemp
2459                             List<RoleResponsibilityActionBo> roleRespActionBos = getRoleMemberResponsibilityActionImpls(origRoleMemberImplTemp.getId());
2460                             if(ObjectUtils.isNotNull(roleRespActionBos))
2461                                 origRoleMemberImplTemp.setRoleRspActions(roleRespActionBos);
2462                         }
2463                     }
2464                 }
2465                 origAttributes = (origRoleMemberImplTemp==null || origRoleMemberImplTemp.getAttributes()==null)?
2466                                     new ArrayList<RoleMemberAttributeDataBo>():origRoleMemberImplTemp.getAttributeDetails();
2467                 newRoleMember.setActiveFromDateValue(documentRoleMember.getActiveFromDate());
2468                 newRoleMember.setActiveToDateValue(documentRoleMember.getActiveToDate());
2469                 newRoleMember.setAttributeDetails(getRoleMemberAttributeData(documentRoleMember.getQualifiers(), origAttributes, activatingInactive, newRoleMemberIdAssigned));
2470                 newRoleMember.setRoleRspActions(getRoleMemberResponsibilityActions(documentRoleMember, origRoleMemberImplTemp, activatingInactive, newRoleMemberIdAssigned));
2471                 newRoleMember.setType(MemberType.fromCode(documentRoleMember.getMemberTypeCode()));
2472 
2473                 if( (origRoleMemberImplTemp == null) || (!newRoleMember.equals(origRoleMemberImplTemp)) ) {
2474                     roleMembers.add(newRoleMember);
2475                 }
2476                 activatingInactive = false;
2477                 origRoleMemberImplTemp = null;
2478             }
2479         }
2480         return roleMembers;
2481     }
2482 
2483 	protected List<RoleResponsibilityActionBo> getRoleMemberResponsibilityActions(
2484 			KimDocumentRoleMember documentRoleMember, RoleMemberBo origRoleMemberImplTemp, boolean activatingInactive, String newRoleMemberIdAssigned){
2485 		List<RoleResponsibilityActionBo> roleRspActions = new ArrayList<RoleResponsibilityActionBo>();
2486 		List<RoleResponsibilityActionBo> origActions = new ArrayList<RoleResponsibilityActionBo>();
2487 		if(origRoleMemberImplTemp!=null) {
2488 			origActions = getRoleRspActions(origRoleMemberImplTemp.getId());
2489 		}
2490 		if(CollectionUtils.isNotEmpty(documentRoleMember.getRoleRspActions())){
2491 			for(KimDocumentRoleResponsibilityAction roleRspAction : documentRoleMember.getRoleRspActions()){
2492 				RoleResponsibilityActionBo newRoleRspAction = new RoleResponsibilityActionBo();
2493 				newRoleRspAction.setId(roleRspAction.getRoleResponsibilityActionId());
2494 				newRoleRspAction.setActionPolicyCode(roleRspAction.getActionPolicyCode());
2495 				newRoleRspAction.setActionTypeCode(roleRspAction.getActionTypeCode());
2496 				newRoleRspAction.setPriorityNumber(roleRspAction.getPriorityNumber());
2497 				newRoleRspAction.setRoleMemberId(roleRspAction.getRoleMemberId());
2498 				newRoleRspAction.setForceAction(roleRspAction.isForceAction());
2499 				newRoleRspAction.setRoleResponsibilityId("*");
2500 				if(ObjectUtils.isNotNull(origActions)){
2501 					for(RoleResponsibilityActionBo origRspAction: origActions) {
2502 						if(activatingInactive && StringUtils.equals(origRspAction.getRoleResponsibilityId(), newRoleRspAction.getRoleResponsibilityId()) &&
2503 								StringUtils.equals(newRoleRspAction.getRoleMemberId(), newRoleMemberIdAssigned)){
2504 							newRoleRspAction.setRoleMemberId(origRspAction.getRoleMemberId());
2505 							newRoleRspAction.setId(origRspAction.getId());
2506 						}
2507 						if (origRspAction.getId()!=null && StringUtils.equals(origRspAction.getId(), newRoleRspAction.getId())) {
2508 							newRoleRspAction.setVersionNumber(origRspAction.getVersionNumber());
2509                             newRoleRspAction.setObjectId(origRspAction.getObjectId());
2510 
2511                         }
2512 					}
2513 				}
2514 				roleRspActions.add(newRoleRspAction);
2515 			}
2516 		}
2517 		return roleRspActions;
2518 	}
2519 
2520 	protected List<RoleMemberAttributeDataBo> getRoleMemberAttributeData(List<KimDocumentRoleQualifier> qualifiers,
2521 			List<RoleMemberAttributeDataBo> origAttributes, boolean activatingInactive, String newRoleMemberIdAssigned){
2522 		List<RoleMemberAttributeDataBo> roleMemberAttributeDataList = new ArrayList<RoleMemberAttributeDataBo>();
2523 		RoleMemberAttributeDataBo newRoleMemberAttributeData;
2524 		if(CollectionUtils.isNotEmpty(qualifiers)){
2525 			for(KimDocumentRoleQualifier memberRoleQualifier: qualifiers){
2526 				if(StringUtils.isNotBlank(memberRoleQualifier.getAttrVal())){
2527 					newRoleMemberAttributeData = new RoleMemberAttributeDataBo();
2528 					newRoleMemberAttributeData.setId(memberRoleQualifier.getAttrDataId());
2529 					newRoleMemberAttributeData.setAttributeValue(memberRoleQualifier.getAttrVal());
2530 					newRoleMemberAttributeData.setAssignedToId(memberRoleQualifier.getRoleMemberId());
2531 					newRoleMemberAttributeData.setKimTypeId(memberRoleQualifier.getKimTypId());
2532 					newRoleMemberAttributeData.setKimAttributeId(memberRoleQualifier.getKimAttrDefnId());
2533 
2534 					updateAttrValIfNecessary(newRoleMemberAttributeData);
2535 
2536 					if(ObjectUtils.isNotNull(origAttributes)){
2537 						for(RoleMemberAttributeDataBo origAttribute: origAttributes){
2538 							if(activatingInactive && StringUtils.equals(origAttribute.getKimAttributeId(), newRoleMemberAttributeData.getKimAttributeId()) &&
2539 									StringUtils.equals(newRoleMemberAttributeData.getAssignedToId(), newRoleMemberIdAssigned)){
2540 								newRoleMemberAttributeData.setAssignedToId(origAttribute.getAssignedToId());
2541 								newRoleMemberAttributeData.setId(origAttribute.getId());
2542 							}
2543 							if(origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), newRoleMemberAttributeData.getId())){
2544 								newRoleMemberAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2545 							}
2546 						}
2547 					}
2548 					roleMemberAttributeDataList.add(newRoleMemberAttributeData);
2549 				}
2550 			}
2551 		}
2552 		return roleMemberAttributeDataList;
2553 	}
2554 
2555 	/**
2556 	 * Determines if the attribute value on the attribute data should be updated; if so, it performs some attribute value formatting.
2557 	 * In the default implementation, this method formats checkbox controls
2558 	 *
2559 	 * @param roleMemberAttributeData a role member qualifier attribute to update
2560 	 */
2561 	protected void updateAttrValIfNecessary(RoleMemberAttributeDataBo roleMemberAttributeData) {
2562 		if (doCheckboxLogic(roleMemberAttributeData.getKimTypeId(), roleMemberAttributeData.getKimAttributeId())) {
2563 			convertCheckboxAttributeData(roleMemberAttributeData);
2564 		}
2565 	}
2566 
2567 	protected void formatAttrValIfNecessary(KimDocumentRoleQualifier roleQualifier) {
2568         if (doCheckboxLogic(roleQualifier.getKimTypId(), roleQualifier.getKimAttrDefnId())) {
2569             formatCheckboxAttributeData(roleQualifier);
2570         }
2571 	}
2572 
2573     private boolean doCheckboxLogic(String kimTypeId, String attrId) {
2574         final KimAttributeField attributeDefinition = getAttributeDefinition(kimTypeId, attrId);
2575         return attributeDefinition != null
2576                 && attributeDefinition.getAttributeField().getControl() != null
2577                 && (attributeDefinition.getAttributeField().getControl() instanceof RemotableCheckboxGroup
2578                         || attributeDefinition.getAttributeField().getControl() instanceof RemotableCheckbox);
2579     }
2580 
2581 	protected void formatCheckboxAttributeData(KimDocumentRoleQualifier roleQualifier) {
2582 		if (roleQualifier.getAttrVal().equals(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE)) {
2583 			roleQualifier.setAttrVal(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE_DISPLAY);
2584 		} else if (roleQualifier.getAttrVal().equals(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE)) {
2585 			roleQualifier.setAttrVal(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE_DISPLAY);
2586 		}
2587 	}
2588 
2589 	/**
2590 	 * Finds the KNS attribute used to render the given KimAttributeData
2591 	 *
2592      * @return the KNS attribute used to render that qualifier, or null if the AttributeDefinition cannot be determined
2593 	 */
2594 	protected KimAttributeField getAttributeDefinition(String kimTypId, String attrDefnId) {
2595 		final KimType type = getKimTypeInfoService().getKimType(kimTypId);
2596 		if (type != null) {
2597 			final KimTypeService typeService = GlobalResourceLoader.<KimTypeService>getService(QName.valueOf(type.getServiceName()));
2598 			if (typeService != null) {
2599 				final KimTypeAttribute attributeInfo = type.getAttributeDefinitionById(attrDefnId);
2600 				if (attributeInfo != null) {
2601 					final List<KimAttributeField> attributeMap = typeService.getAttributeDefinitions(type.getId());
2602 					if (attributeMap != null) {
2603 						return DataDictionaryTypeServiceHelper.findAttributeField(
2604                                 attributeInfo.getKimAttribute().getAttributeName(), attributeMap);
2605 					}
2606 				}
2607 			}
2608 		}
2609 		return null;
2610 	}
2611 
2612 	/**
2613 	 * Formats the attribute value on this checkbox attribute, changing "on" to "Y" and "off" to "N"
2614 	 *
2615 	 * @param roleMemberAttributeData the attribute data to format the attribute value of
2616 	 */
2617 	protected void convertCheckboxAttributeData(RoleMemberAttributeDataBo roleMemberAttributeData) {
2618 		if (roleMemberAttributeData.getAttributeValue().equalsIgnoreCase(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE_DISPLAY)) {
2619 			roleMemberAttributeData.setAttributeValue(KimConstants.KIM_ATTRIBUTE_BOOLEAN_TRUE_STR_VALUE);
2620 		} else if (roleMemberAttributeData.getAttributeValue().equalsIgnoreCase(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE_DISPLAY)) {
2621 			roleMemberAttributeData.setAttributeValue(KimConstants.KIM_ATTRIBUTE_BOOLEAN_FALSE_STR_VALUE);
2622 		}
2623 	}
2624 
2625 	protected List<DelegateTypeBo> getRoleDelegations(IdentityManagementRoleDocument identityManagementRoleDocument, List<DelegateTypeBo> origDelegations){
2626 		List<DelegateTypeBo> kimDelegations = new ArrayList<DelegateTypeBo>();
2627 		DelegateTypeBo newKimDelegation;
2628 		DelegateTypeBo origDelegationImplTemp = null;
2629 		List<DelegateMemberBo> origMembers;
2630         List<DelegateMemberBo> allOrigMembers = new ArrayList<DelegateMemberBo>();;
2631         boolean activatingInactive = false;
2632 		String newDelegationIdAssigned = "";
2633             if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getDelegations())){
2634 			for(RoleDocumentDelegation roleDocumentDelegation: identityManagementRoleDocument.getDelegations()){
2635 				newKimDelegation = new DelegateTypeBo();
2636 				KimCommonUtilsInternal.copyProperties(newKimDelegation, roleDocumentDelegation);
2637 				newKimDelegation.setRoleId(identityManagementRoleDocument.getRoleId());
2638 				if(ObjectUtils.isNotNull(origDelegations)){
2639 					for(DelegateTypeBo origDelegationImpl: origDelegations){
2640 						if(StringUtils.equals(origDelegationImpl.getRoleId(), newKimDelegation.getRoleId()) &&
2641 								StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
2642 							//TODO: verify if you want to add  && newRoleMember.isActive() condition to if...
2643 							newDelegationIdAssigned = newKimDelegation.getDelegationId();
2644 							newKimDelegation.setDelegationId(origDelegationImpl.getDelegationId());
2645 							activatingInactive = true;
2646 						}
2647 						if(origDelegationImpl.getDelegationId()!=null && StringUtils.equals(origDelegationImpl.getDelegationId(), newKimDelegation.getDelegationId())){
2648 							newKimDelegation.setVersionNumber(origDelegationImpl.getVersionNumber());
2649                             newKimDelegation.setObjectId(origDelegationImpl.getObjectId());
2650 							origDelegationImplTemp = origDelegationImpl;
2651 						}
2652                         for (DelegateMemberBo delegateMemberBo:origDelegationImpl.getMembers() ) {
2653                             allOrigMembers.add(delegateMemberBo);
2654                         }
2655                     }
2656 				}
2657 				origMembers = (origDelegationImplTemp == null || origDelegationImplTemp.getMembers()==null)?
2658 									new ArrayList<DelegateMemberBo>():origDelegationImplTemp.getMembers();
2659 				newKimDelegation.setMembers(getDelegationMembers(roleDocumentDelegation.getMembers(), origMembers, allOrigMembers, activatingInactive, newDelegationIdAssigned));
2660                 kimDelegations.add(newKimDelegation);
2661 				activatingInactive = false;
2662 			}
2663 		}
2664 		return kimDelegations;
2665 	}
2666 
2667 	protected List<DelegateMemberBo> getDelegationMembers(List<RoleDocumentDelegationMember> delegationMembers,
2668 			List<DelegateMemberBo> origDelegationMembers, List<DelegateMemberBo> allOrigMembers, boolean activatingInactive, String newDelegationIdAssigned){
2669 		List<DelegateMemberBo> delegationsMembersList = new ArrayList<DelegateMemberBo>();
2670 		DelegateMemberBo newDelegationMemberImpl;
2671 		DelegateMemberBo origDelegationMemberImplTemp = null;
2672 		List<DelegateMemberAttributeDataBo> origAttributes;
2673 		String delegationMemberId = "";
2674 		if(CollectionUtils.isNotEmpty(delegationMembers)){
2675 			for(RoleDocumentDelegationMember delegationMember: delegationMembers){
2676 				newDelegationMemberImpl = new DelegateMemberBo();
2677 				KimCommonUtilsInternal.copyProperties(newDelegationMemberImpl, delegationMember);
2678                 newDelegationMemberImpl.setType(MemberType.fromCode(delegationMember.getMemberTypeCode()));
2679 				if(ObjectUtils.isNotNull(origDelegationMembers)){
2680 					for(DelegateMemberBo origDelegationMember: origDelegationMembers){
2681 						if(activatingInactive && StringUtils.equals(origDelegationMember.getMemberId(), newDelegationMemberImpl.getMemberId()) &&
2682 								StringUtils.equals(newDelegationMemberImpl.getDelegationId(), newDelegationIdAssigned) &&
2683 								!origDelegationMember.isActive(new Timestamp(System.currentTimeMillis()))){
2684 							newDelegationMemberImpl.setDelegationId(origDelegationMember.getDelegationId());
2685 							delegationMemberId = newDelegationMemberImpl.getDelegationMemberId();
2686 							newDelegationMemberImpl.setDelegationMemberId(origDelegationMember.getDelegationMemberId());
2687 						}
2688 						if(origDelegationMember.getDelegationMemberId()!=null && StringUtils.equals(origDelegationMember.getDelegationMemberId(), newDelegationMemberImpl.getDelegationMemberId())){
2689 							newDelegationMemberImpl.setVersionNumber(origDelegationMember.getVersionNumber());
2690                             newDelegationMemberImpl.setObjectId(origDelegationMember.getObjectId());
2691                             origDelegationMemberImplTemp = origDelegationMember;
2692 						}
2693 					}
2694 				}
2695                 for (DelegateMemberBo origMember : allOrigMembers) {
2696                     if ((origMember.getDelegationMemberId() != null) &&
2697                         (origMember.getDelegationMemberId().equals(delegationMember.getDelegationMemberId())) &&
2698                         (origMember.getRoleMemberId() != null) &&
2699                         (origMember.getRoleMemberId().equals(delegationMember.getRoleMemberId()))) {
2700                             newDelegationMemberImpl.setVersionNumber(origMember.getVersionNumber());
2701                             newDelegationMemberImpl.setObjectId(origMember.getObjectId());
2702                             origDelegationMemberImplTemp = origMember;
2703                     }
2704                 }
2705 				origAttributes = (origDelegationMemberImplTemp==null || origDelegationMemberImplTemp.getAttributeDetails()==null)?
2706 						new ArrayList<DelegateMemberAttributeDataBo>():origDelegationMemberImplTemp.getAttributeDetails();
2707 				newDelegationMemberImpl.setAttributeDetails(getDelegationMemberAttributeData(delegationMember.getQualifiers(), origAttributes, activatingInactive, delegationMemberId));
2708 				newDelegationMemberImpl.setActiveFromDateValue(delegationMember.getActiveFromDate());
2709                 newDelegationMemberImpl.setActiveToDateValue(delegationMember.getActiveToDate());
2710                 delegationsMembersList.add(newDelegationMemberImpl);
2711 			}
2712 		}
2713 		return delegationsMembersList;
2714 	}
2715 
2716 	//TODO: implement logic same as role members - do not insert qualifiers with blank values
2717 	protected List<DelegateMemberAttributeDataBo> getDelegationMemberAttributeData(
2718 			List<RoleDocumentDelegationMemberQualifier> qualifiers, List<DelegateMemberAttributeDataBo> origAttributes,
2719 			boolean activatingInactive, String delegationMemberId){
2720 		List<DelegateMemberAttributeDataBo> delegationMemberAttributeDataList = new ArrayList<DelegateMemberAttributeDataBo>();
2721 		DelegateMemberAttributeDataBo newDelegationMemberAttributeData;
2722 		if(CollectionUtils.isNotEmpty(qualifiers)){
2723 			for(RoleDocumentDelegationMemberQualifier memberRoleQualifier: qualifiers){
2724 				if(StringUtils.isNotBlank(memberRoleQualifier.getAttrVal())){
2725 					newDelegationMemberAttributeData = new DelegateMemberAttributeDataBo();
2726 					newDelegationMemberAttributeData.setId(memberRoleQualifier.getAttrDataId());
2727 					newDelegationMemberAttributeData.setAttributeValue(memberRoleQualifier.getAttrVal());
2728 					newDelegationMemberAttributeData.setAssignedToId(memberRoleQualifier.getDelegationMemberId());
2729 					newDelegationMemberAttributeData.setKimTypeId(memberRoleQualifier.getKimTypId());
2730 					newDelegationMemberAttributeData.setKimAttributeId(memberRoleQualifier.getKimAttrDefnId());
2731 					if(ObjectUtils.isNotNull(origAttributes)){
2732 						for(DelegateMemberAttributeDataBo origAttribute: origAttributes){
2733 							if(activatingInactive && StringUtils.equals(origAttribute.getKimAttributeId(), newDelegationMemberAttributeData.getKimAttributeId()) &&
2734 									StringUtils.equals(newDelegationMemberAttributeData.getAssignedToId(), delegationMemberId)){
2735 								newDelegationMemberAttributeData.setAssignedToId(origAttribute.getAssignedToId());
2736 								newDelegationMemberAttributeData.setId(origAttribute.getId());
2737 							}
2738 							if(StringUtils.equals(origAttribute.getId(), newDelegationMemberAttributeData.getId())){
2739 								newDelegationMemberAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2740 							}
2741 						}
2742 					}
2743 					delegationMemberAttributeDataList.add(newDelegationMemberAttributeData);
2744 				}
2745 			}
2746 		}
2747 		return delegationMemberAttributeDataList;
2748 	}
2749 
2750 	/* Group document methods */
2751 	public void loadGroupDoc(IdentityManagementGroupDocument identityManagementGroupDocument, Group groupInfo){
2752 		//Map<String, String> criteria = new HashMap<String, String>();
2753 		//criteria.put(KimApiConstants.PrimaryKeyConstants.GROUP_ID, groupInfo.getId());
2754 		//GroupImpl kimGroupImpl = (GroupImpl)
2755 		//	getBusinessObjectService().findByPrimaryKey(GroupImpl.class, criteria);
2756 
2757 		identityManagementGroupDocument.setGroupId(groupInfo.getId());
2758         KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(groupInfo.getKimTypeId());
2759 		identityManagementGroupDocument.setKimType(kimType);
2760 		identityManagementGroupDocument.setGroupTypeName(kimType.getName());
2761 		identityManagementGroupDocument.setGroupTypeId(kimType.getId());
2762 		identityManagementGroupDocument.setGroupName(groupInfo.getName());
2763 		identityManagementGroupDocument.setGroupDescription(groupInfo.getDescription());
2764 		identityManagementGroupDocument.setActive(groupInfo.isActive());
2765 		identityManagementGroupDocument.setGroupNamespace(groupInfo.getNamespaceCode());
2766 
2767         List<GroupMember> members = new ArrayList(KimApiServiceLocator.getGroupService().getMembersOfGroup(groupInfo.getId()));
2768         identityManagementGroupDocument.setMembers(loadGroupMembers(identityManagementGroupDocument, members));
2769 
2770 
2771 
2772         identityManagementGroupDocument.setQualifiers(loadGroupQualifiers(identityManagementGroupDocument, groupInfo.getAttributes()));
2773 		identityManagementGroupDocument.setEditing(true);
2774 	}
2775 
2776 	protected static class GroupMemberNameComparator implements Comparator<GroupDocumentMember> {
2777 		/**
2778 		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
2779 		 */
2780 		public int compare(GroupDocumentMember m1, GroupDocumentMember m2) {
2781 			return m1.getMemberName().compareToIgnoreCase(m2.getMemberName());
2782 		}
2783 	}
2784 
2785 	protected GroupMemberNameComparator groupMemberNameComparator = new GroupMemberNameComparator();
2786 
2787 	protected List<GroupDocumentMember> loadGroupMembers(
2788 			IdentityManagementGroupDocument identityManagementGroupDocument, List<GroupMember> members){
2789 		List<GroupDocumentMember> pndMembers = new ArrayList<GroupDocumentMember>();
2790 		GroupDocumentMember pndMember = new GroupDocumentMember();
2791 		if(ObjectUtils.isNotNull(members)){
2792 			for(GroupMember member: members){
2793 				pndMember = new GroupDocumentMember();
2794 
2795 				pndMember.setActiveFromDate(member.getActiveFromDate() == null ? null : new Timestamp(member.getActiveFromDate().getMillis()));
2796 				pndMember.setActiveToDate(member.getActiveToDate() == null ? null : new Timestamp(member.getActiveToDate().getMillis()));
2797 				//pndMember.setActive(member.isActive());
2798 				if(pndMember.isActive()){
2799 					pndMember.setGroupMemberId(member.getMemberId());
2800 					pndMember.setGroupId(member.getGroupId());
2801 					pndMember.setMemberId(member.getMemberId());
2802 					pndMember.setMemberName(getMemberName(member.getType(), member.getMemberId()));
2803 					pndMember.setMemberFullName(getMemberFullName(member.getType(), member.getMemberId()));
2804 					pndMember.setMemberTypeCode(member.getType().getCode());
2805 					pndMember.setEdit(true);
2806 					pndMembers.add(pndMember);
2807 				}
2808 			}
2809 		}
2810 		Collections.sort(pndMembers, groupMemberNameComparator);
2811 		return pndMembers;
2812 	}
2813 
2814 	protected List<GroupDocumentQualifier> loadGroupQualifiers(IdentityManagementGroupDocument IdentityManagementGroupDocument,
2815 			Map<String, String> attributes){
2816 		List<GroupDocumentQualifier> pndGroupQualifiers = new ArrayList<GroupDocumentQualifier>();
2817 		GroupDocumentQualifier pndGroupQualifier = new GroupDocumentQualifier();
2818 		List<KimAttributeField> origAttributes = IdentityManagementGroupDocument.getDefinitions();
2819 		boolean attributePresent = false;
2820 		String origAttributeId;
2821 		if(origAttributes!=null){
2822 
2823 			for(KimAttributeField key: origAttributes) {
2824 				origAttributeId = IdentityManagementGroupDocument.getKimAttributeDefnId(key);
2825 				if(!attributes.isEmpty()){
2826 
2827 					for(GroupAttributeBo groupQualifier: KimAttributeDataBo.createFrom(GroupAttributeBo.class, attributes, IdentityManagementGroupDocument.getGroupTypeId())){
2828 						if(origAttributeId!=null && ObjectUtils.isNotNull(groupQualifier.getKimAttribute()) &&
2829 								StringUtils.equals(origAttributeId, groupQualifier.getKimAttribute().getId())){
2830 							pndGroupQualifier = new GroupDocumentQualifier();
2831 							KimCommonUtilsInternal.copyProperties(pndGroupQualifier, groupQualifier);
2832 							pndGroupQualifier.setAttrDataId(groupQualifier.getId());
2833 							pndGroupQualifier.setAttrVal(groupQualifier.getAttributeValue());
2834 							pndGroupQualifier.setKimAttrDefnId(groupQualifier.getKimAttribute().getId());
2835 							pndGroupQualifier.setKimTypId(groupQualifier.getKimType().getId());
2836 							pndGroupQualifier.setGroupId(groupQualifier.getAssignedToId());
2837 							pndGroupQualifiers.add(pndGroupQualifier);
2838 							attributePresent = true;
2839 						}
2840 					}
2841 				}
2842 				if(!attributePresent){
2843 					pndGroupQualifier = new GroupDocumentQualifier();
2844 					pndGroupQualifier.setKimAttrDefnId(origAttributeId);
2845 					pndGroupQualifiers.add(pndGroupQualifier);
2846 				}
2847 				attributePresent = false;
2848 			}
2849 		}
2850 		return pndGroupQualifiers;
2851 	}
2852 
2853 	/**
2854 	 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument)
2855 	 */
2856 	@SuppressWarnings("unchecked")
2857 	public void saveGroup(IdentityManagementGroupDocument identityManagementGroupDocument) {
2858 		GroupBo kimGroup = new GroupBo();
2859 		Map<String, String> criteria = new HashMap<String, String>();
2860 		String groupId = identityManagementGroupDocument.getGroupId();
2861 		criteria.put("groupId", groupId);
2862 		GroupBo origGroup = (GroupBo)getBusinessObjectService().findBySinglePrimaryKey(GroupBo.class, groupId);
2863 		List<GroupMemberBo> origGroupMembers = new ArrayList<GroupMemberBo>();
2864 		if (ObjectUtils.isNull(origGroup)) {
2865 			origGroup = new GroupBo();
2866 			kimGroup.setActive(true);
2867 		} else {
2868 			kimGroup.setVersionNumber(origGroup.getVersionNumber());
2869 			//TODO: when a group is inactivated, inactivate the memberships of principals in that group
2870 			//and the memberships of that group in roles
2871 			kimGroup.setActive(identityManagementGroupDocument.isActive());
2872 			origGroupMembers = (List<GroupMemberBo>)getBusinessObjectService().findMatching(GroupMemberBo.class, criteria);
2873 		}
2874 
2875 		kimGroup.setId(identityManagementGroupDocument.getGroupId());
2876 		KimType kimType = getKimTypeInfoService().getKimType(identityManagementGroupDocument.getGroupTypeId());
2877 		if( kimType == null ) {
2878 			throw new RuntimeException("Kim type not found for:"+identityManagementGroupDocument.getGroupTypeId());
2879 		}
2880 
2881 		kimGroup.setKimTypeId(kimType.getId());
2882 		kimGroup.setNamespaceCode(identityManagementGroupDocument.getGroupNamespace());
2883 		kimGroup.setName(identityManagementGroupDocument.getGroupName());
2884 		kimGroup.setDescription(identityManagementGroupDocument.getGroupDescription());
2885 		kimGroup.setAttributeDetails(getGroupAttributeData(identityManagementGroupDocument, origGroup.getAttributeDetails()));
2886 
2887 		List<String> oldIds;
2888 		List<String> newIds;
2889 		oldIds = getGroupService().getMemberPrincipalIds(kimGroup.getId()); // for the actionList update
2890 
2891 
2892 		List<GroupMemberBo> newGroupMembersList = getGroupMembers(identityManagementGroupDocument, origGroupMembers);
2893 		kimGroup.setMembers(newGroupMembersList);  // add the new, complete list to the group
2894 
2895 		kimGroup = (GroupBo)getBusinessObjectService().save(kimGroup);
2896 
2897 		newIds = kimGroup.getMemberPrincipalIds();
2898 		//newIds = getGroupService().getMemberPrincipalIds(kimGroup.getGroupId()); // for the action list update
2899 
2900 		// Do an async update of the action list for the updated groups
2901 		org.kuali.rice.kim.service.KIMServiceLocatorInternal.getGroupInternalService().updateForWorkgroupChange(kimGroup.getId(), oldIds, newIds);
2902 		if(!kimGroup.isActive()){
2903 			// when a group is inactivated, inactivate the memberships of principals in that group
2904 			// and the memberships of that group in roles
2905 			KimImplServiceLocator.getRoleInternalService().groupInactivated(identityManagementGroupDocument.getGroupId());
2906 		}
2907 
2908 	}
2909 
2910 	protected List<GroupMemberBo> getGroupMembers(IdentityManagementGroupDocument identityManagementGroupDocument, List<GroupMemberBo> origGroupMembers){
2911 		List<GroupMemberBo> groupMembers = new ArrayList<GroupMemberBo>();
2912 		GroupMemberBo newGroupMember;
2913 		if(CollectionUtils.isNotEmpty(identityManagementGroupDocument.getMembers())){
2914 			for(GroupDocumentMember documentGroupMember: identityManagementGroupDocument.getMembers()){
2915 				newGroupMember = new GroupMemberBo();
2916 				//KimCommonUtilsInternalInternal.copyProperties(newGroupMember, documentGroupMember);
2917                 //copy properties manually for now until new BO created for DocumentGroupMember
2918 
2919 				newGroupMember.setGroupId(identityManagementGroupDocument.getGroupId());
2920                 newGroupMember.setActiveFromDateValue(documentGroupMember.getActiveFromDate());
2921                 newGroupMember.setActiveToDateValue(documentGroupMember.getActiveToDate());
2922                 newGroupMember.setMemberId(documentGroupMember.getMemberId());
2923                 newGroupMember.setTypeCode(documentGroupMember.getMemberTypeCode());
2924 				if(ObjectUtils.isNotNull(origGroupMembers)){
2925 					for(GroupMemberBo origGroupMemberImpl: origGroupMembers){
2926 						if(StringUtils.equals(origGroupMemberImpl.getGroupId(), newGroupMember.getGroupId()) &&
2927 								StringUtils.equals(origGroupMemberImpl.getMemberId(), newGroupMember.getMemberId()) &&
2928 								!origGroupMemberImpl.isActive(new Timestamp(System.currentTimeMillis()))){
2929 							//TODO: verify if you want to add  && newGroupMember.isActive() condition to if...
2930 							newGroupMember.setMemberId(origGroupMemberImpl.getMemberId());
2931 						}
2932                         if(StringUtils.equals(origGroupMemberImpl.getGroupId(), newGroupMember.getGroupId()) &&
2933 								StringUtils.equals(origGroupMemberImpl.getMemberId(), newGroupMember.getMemberId()) &&
2934 								origGroupMemberImpl.isActive(new Timestamp(System.currentTimeMillis()))){
2935 							newGroupMember.setId(origGroupMemberImpl.getId());
2936                             newGroupMember.setVersionNumber(origGroupMemberImpl.getVersionNumber());
2937 						}
2938 					}
2939 				}
2940 				groupMembers.add(newGroupMember);
2941 			}
2942 		}
2943 		return groupMembers;
2944 	}
2945 
2946 	protected List<GroupAttributeBo> getGroupAttributeData(IdentityManagementGroupDocument identityManagementGroupDocument,
2947 			List<GroupAttributeBo> origAttributes){
2948 		List<GroupAttributeBo> groupAttributeDataList = new ArrayList<GroupAttributeBo>();
2949 		GroupAttributeBo newGroupAttributeData;
2950 		if(CollectionUtils.isNotEmpty(identityManagementGroupDocument.getQualifiers())){
2951 			for(GroupDocumentQualifier groupQualifier: identityManagementGroupDocument.getQualifiers()){
2952 				if(StringUtils.isNotBlank(groupQualifier.getAttrVal())){
2953 					newGroupAttributeData = new GroupAttributeBo();
2954 					newGroupAttributeData.setId(groupQualifier.getAttrDataId());
2955 					newGroupAttributeData.setAttributeValue(groupQualifier.getAttrVal());
2956 					newGroupAttributeData.setAssignedToId(groupQualifier.getGroupId());
2957 					newGroupAttributeData.setKimTypeId(groupQualifier.getKimTypId());
2958 					newGroupAttributeData.setKimAttributeId(groupQualifier.getKimAttrDefnId());
2959 					if(ObjectUtils.isNotNull(origAttributes)){
2960 						for(GroupAttributeBo origAttribute: origAttributes){
2961 							if(StringUtils.equals(origAttribute.getKimAttributeId(), newGroupAttributeData.getKimAttributeId()) &&
2962 									StringUtils.equals(newGroupAttributeData.getAssignedToId(), origAttribute.getAssignedToId())){
2963 							    newGroupAttributeData.setId(origAttribute.getId());
2964 							}
2965 							if(origAttribute.getId()!=null && StringUtils.equals(origAttribute.getId(), newGroupAttributeData.getId())){
2966 							    newGroupAttributeData.setVersionNumber(origAttribute.getVersionNumber());
2967 							}
2968 						}
2969 					}
2970 					groupAttributeDataList.add(newGroupAttributeData);
2971 				}
2972 			}
2973 		}
2974 		return groupAttributeDataList;
2975 	}
2976 
2977     @SuppressWarnings("unchecked")
2978 	public KimDocumentRoleMember getKimDocumentRoleMember(MemberType memberType, String memberId, String roleId){
2979     	if(memberType == null || StringUtils.isEmpty(memberId) || StringUtils.isEmpty(roleId)) {
2980     		return null;
2981         }
2982     	KimDocumentRoleMember documentRoleMember = new KimDocumentRoleMember();
2983     	documentRoleMember.setRoleId(roleId);
2984     	Map<String, String> criteria = new HashMap<String, String>();
2985     	criteria.put("roleId", roleId);
2986     	criteria.put("mbr_id", memberId);
2987 
2988     	List<RoleMemberBo> matchingRoleMembers = (List<RoleMemberBo>)getBusinessObjectService().findMatching(RoleMemberBo.class, criteria);
2989     	if (matchingRoleMembers==null || matchingRoleMembers.size()<1) { return null; }
2990 
2991     	RoleMemberBo roleMemberImpl = matchingRoleMembers.get(0);
2992     	documentRoleMember.setRoleMemberId(roleMemberImpl.getId());
2993     	if(MemberType.PRINCIPAL.equals(memberType)){
2994     		Principal principal = getIdentityService().getPrincipal(memberId);
2995     		if (principal != null) {
2996     			documentRoleMember.setMemberId(principal.getPrincipalId());
2997         		documentRoleMember.setMemberName(principal.getPrincipalName());
2998         		documentRoleMember.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
2999     		}    		
3000         } else if(MemberType.GROUP.equals(memberType)){
3001         	Group group = getGroupService().getGroup(memberId);
3002         	if (group != null) {
3003         		documentRoleMember.setMemberNamespaceCode(group.getNamespaceCode());
3004         		documentRoleMember.setMemberId(group.getId());
3005         		documentRoleMember.setMemberName(group.getName());
3006         		documentRoleMember.setMemberTypeCode(MemberType.GROUP.getCode());
3007         	}
3008         	
3009         } else if(MemberType.ROLE.equals(memberType)){
3010         	Role role = getRoleService().getRole(memberId);
3011         	if (role != null) {
3012         		documentRoleMember.setMemberNamespaceCode(role.getNamespaceCode());
3013         		documentRoleMember.setMemberId(role.getId());
3014         		documentRoleMember.setMemberName(role.getName());
3015         		documentRoleMember.setMemberTypeCode(MemberType.ROLE.getCode());
3016         	}        	
3017         }
3018     	return documentRoleMember;
3019     }
3020 
3021     protected Set<String> getChangedRoleResponsibilityIds(
3022 			IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleResponsibilityBo> origRoleResponsibilities){
3023 		Set<String> lRet = new HashSet<String>();
3024 		List<String> newResp = new ArrayList<String>();
3025 		List<String> oldResp = new ArrayList<String>();
3026 		if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getResponsibilities())){
3027 			for(KimDocumentRoleResponsibility documentRoleResponsibility: identityManagementRoleDocument.getResponsibilities()){
3028 				newResp.add(documentRoleResponsibility.getResponsibilityId());
3029 			}
3030 		}
3031 		if(ObjectUtils.isNotNull(origRoleResponsibilities)){
3032 			for(RoleResponsibilityBo roleRespBo: origRoleResponsibilities){
3033 				oldResp.add(roleRespBo.getResponsibilityId());
3034 			}
3035 		}
3036 		lRet.addAll(newResp);
3037 		lRet.addAll(oldResp);
3038 
3039 		return lRet;
3040 	}
3041 
3042 	public KimTypeInfoService getKimTypeInfoService() {
3043 		if ( kimTypeInfoService == null ) {
3044 			kimTypeInfoService = KimApiServiceLocator.getKimTypeInfoService();
3045 		}
3046 		return kimTypeInfoService;
3047 	}
3048 
3049     public List<KimDocumentRoleMember> getRoleMembers(Map<String,String> fieldValues) {
3050         List<KimDocumentRoleMember> matchingRoleMembers = new ArrayList<KimDocumentRoleMember>();
3051         //Remove since they are KNS fieldValues and not BO
3052         fieldValues.remove(KRADConstants.BACK_LOCATION);
3053         fieldValues.remove(KRADConstants.DOC_FORM_KEY);
3054         fieldValues.remove(KRADConstants.DOC_NUM);
3055 
3056 
3057 
3058 		List<RoleMember> matchingRoleMembersTemp = getRoleService().findRoleMembers(toQuery(fieldValues)).getResults();
3059 		KimDocumentRoleMember matchingRoleMember;
3060 		BusinessObject roleMemberObject;
3061 		RoleMemberBo roleMemberBo;
3062 		if(CollectionUtils.isNotEmpty(matchingRoleMembersTemp)){
3063 			for(RoleMember roleMember: matchingRoleMembersTemp){
3064 				roleMemberBo = getRoleMember(roleMember.getId());
3065 				roleMemberObject = getMember(roleMemberBo.getType(), roleMemberBo.getMemberId());
3066 				matchingRoleMember = new KimDocumentRoleMember();
3067 				KimCommonUtilsInternal.copyProperties(matchingRoleMember, roleMemberBo);
3068                 matchingRoleMember.setMemberId(roleMemberBo.getMemberId());
3069                 matchingRoleMember.setRoleMemberId(roleMemberBo.getId());
3070 				matchingRoleMember.setMemberName(getMemberName(roleMemberBo.getType(), roleMemberObject));
3071 				matchingRoleMember.setMemberNamespaceCode(getMemberNamespaceCode(roleMemberBo.getType(), roleMemberObject));
3072 				matchingRoleMember.setQualifiers(getQualifiers(roleMemberBo.getAttributeDetails()));
3073 				matchingRoleMembers.add(matchingRoleMember);
3074 			}
3075 		}
3076 		return matchingRoleMembers;
3077     }
3078 
3079    private QueryByCriteria toQuery(Map<String,String> fieldValues) {
3080        String memberTypeCode = fieldValues.get(KIMPropertyConstants.KimMember.MEMBER_TYPE_CODE);
3081        String memberName = fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAME);
3082        String memberNamespaceCode = fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAMESPACE_CODE);
3083 
3084        if(StringUtils.isNotEmpty(memberName) || StringUtils.isNotEmpty(memberNamespaceCode)) {
3085             String memberId  = getMemberIdByName(MemberType.fromCode(memberTypeCode),memberNamespaceCode,memberName)  ;
3086            if(StringUtils.isNotEmpty(memberId)) {
3087                   fieldValues.put(KIMPropertyConstants.KimMember.MEMBER_ID, memberId);
3088            }
3089        }
3090 
3091        List<Predicate> pred = new ArrayList<Predicate>();
3092 
3093        pred.add(PredicateUtils.convertMapToPredicate(fieldValues));
3094        Predicate[] predicates = new Predicate[0];
3095        predicates = pred.toArray(predicates)  ;
3096         return QueryByCriteria.Builder.fromPredicates(predicates);
3097     }
3098 
3099     private List<KimDocumentRoleQualifier> getQualifiers(List<RoleMemberAttributeDataBo> attributes){
3100     	if (attributes==null) {return null;}
3101     	List<KimDocumentRoleQualifier> qualifiers = new ArrayList<KimDocumentRoleQualifier>();
3102     	KimDocumentRoleQualifier qualifier;
3103     	if(ObjectUtils.isNotNull(attributes)){
3104 	    	for(RoleMemberAttributeDataBo attribute: attributes){
3105 		    	qualifier = new KimDocumentRoleQualifier();
3106 				qualifier.setAttrDataId(attribute.getId());
3107 				qualifier.setAttrVal(attribute.getAttributeValue());
3108 				qualifier.setRoleMemberId(attribute.getAssignedToId());
3109 				qualifier.setKimTypId(attribute.getKimTypeId());
3110 				qualifier.setKimAttrDefnId(attribute.getKimAttributeId());
3111 				qualifier.setKimAttribute(attribute.getKimAttribute());
3112 				qualifiers.add(qualifier);
3113 	    	}
3114     	}
3115     	return qualifiers;
3116     }
3117     
3118 	public ResponsibilityInternalService getResponsibilityInternalService() {
3119 		if ( responsibilityInternalService == null ) {
3120 				responsibilityInternalService = KimImplServiceLocator.getResponsibilityInternalService();
3121 		}
3122 		return responsibilityInternalService;
3123 	}
3124 
3125    public PermissionService getPermissionService() {
3126 		if ( permissionService == null ) {
3127 				permissionService = KimApiServiceLocator.getPermissionService();
3128 		}
3129 		return permissionService;
3130 	}
3131 
3132     public ParameterService getParameterService() {
3133     	if ( parameterService == null ) {
3134     		parameterService = CoreFrameworkServiceLocator.getParameterService();
3135     	}
3136     	return parameterService;
3137     }
3138 
3139     public void setParameterService(ParameterService parameterService) {
3140     	this.parameterService = parameterService;
3141     }
3142 
3143     public static IdentityArchiveService getIdentityArchiveService() {
3144         return GlobalResourceLoader.getService(KIM_IDENTITY_ARCHIVE_SERVICE);
3145     }
3146 
3147     public UiDocumentServiceDAO getUiDocumentServiceDAO() {
3148         if ( uiDocumentServiceDAO == null ) {
3149             uiDocumentServiceDAO = KIMServiceLocatorInternal.getUiDocumentServiceDAO();
3150         }
3151         return uiDocumentServiceDAO;
3152     }
3153 
3154     public void setUiDocumentService(UiDocumentServiceDAO uiDocumentServiceDAO) {
3155         this.uiDocumentServiceDAO = uiDocumentServiceDAO;
3156     }
3157 }