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