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