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