001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kim.web.struts.action;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.struts.action.ActionForm;
020import org.apache.struts.action.ActionForward;
021import org.apache.struts.action.ActionMapping;
022import org.kuali.rice.core.api.membership.MemberType;
023import org.kuali.rice.core.api.util.RiceConstants;
024import org.kuali.rice.core.api.util.RiceKeyConstants;
025import org.kuali.rice.kew.api.exception.WorkflowException;
026import org.kuali.rice.kim.api.KimConstants;
027import org.kuali.rice.kim.api.group.Group;
028import org.kuali.rice.kim.api.identity.entity.EntityDefault;
029import org.kuali.rice.kim.api.identity.principal.Principal;
030import org.kuali.rice.kim.api.role.Role;
031import org.kuali.rice.kim.api.role.RoleResponsibility;
032import org.kuali.rice.kim.api.services.KimApiServiceLocator;
033import org.kuali.rice.kim.api.type.KimAttributeField;
034import org.kuali.rice.kim.api.type.KimType;
035import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
036import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
037import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibilityAction;
038import org.kuali.rice.kim.bo.ui.PersonDocumentAddress;
039import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
040import org.kuali.rice.kim.bo.ui.PersonDocumentCitizenship;
041import org.kuali.rice.kim.bo.ui.PersonDocumentEmail;
042import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
043import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
044import org.kuali.rice.kim.bo.ui.PersonDocumentName;
045import org.kuali.rice.kim.bo.ui.PersonDocumentPhone;
046import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
047import org.kuali.rice.kim.bo.ui.RoleDocumentDelegation;
048import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
049import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
050import org.kuali.rice.kim.document.IdentityManagementPersonDocument;
051import org.kuali.rice.kim.document.rule.AttributeValidationHelper;
052import org.kuali.rice.kim.framework.type.KimTypeService;
053import org.kuali.rice.kim.impl.KIMPropertyConstants;
054import org.kuali.rice.kim.impl.responsibility.ResponsibilityInternalService;
055import org.kuali.rice.kim.impl.role.RoleBo;
056import org.kuali.rice.kim.impl.role.RoleMemberBo;
057import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
058import org.kuali.rice.kim.impl.type.KimTypeAttributesHelper;
059import org.kuali.rice.kim.impl.type.KimTypeBo;
060import org.kuali.rice.kim.rule.event.ui.AddGroupEvent;
061import org.kuali.rice.kim.rule.event.ui.AddPersonDelegationMemberEvent;
062import org.kuali.rice.kim.rule.event.ui.AddPersonDocumentRoleQualifierEvent;
063import org.kuali.rice.kim.rule.event.ui.AddRoleEvent;
064import org.kuali.rice.kim.rules.ui.PersonDocumentRoleRule;
065import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
066import org.kuali.rice.kim.web.struts.form.IdentityManagementPersonDocumentForm;
067import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
068import org.kuali.rice.krad.data.KradDataServiceLocator;
069import org.kuali.rice.krad.util.GlobalVariables;
070import org.kuali.rice.krad.util.KRADConstants;
071import org.kuali.rice.krad.util.UrlFactory;
072
073import javax.servlet.http.HttpServletRequest;
074import javax.servlet.http.HttpServletResponse;
075import java.sql.Timestamp;
076import java.text.MessageFormat;
077import java.util.ArrayList;
078import java.util.Calendar;
079import java.util.List;
080import java.util.Map;
081import java.util.Properties;
082
083/**
084 * This is a description of what this class does - shyu don't forget to fill this in. 
085 * 
086 * @author Kuali Rice Team (rice.collab@kuali.org)
087 *
088 */
089public class IdentityManagementPersonDocumentAction extends IdentityManagementDocumentActionBase {
090
091    protected ResponsibilityInternalService responsibilityInternalService;
092
093        @Override
094        public ActionForward execute(ActionMapping mapping, ActionForm form,
095                        HttpServletRequest request, HttpServletResponse response)
096                        throws Exception {
097                ActionForward forward;
098        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
099        // accept either the principal name or principal ID, looking up the latter if necessary
100        // this allows inquiry links to work even when only the principal name is present
101        String principalId = request.getParameter(KIMPropertyConstants.Person.PRINCIPAL_ID);
102        String principalName = request.getParameter(KIMPropertyConstants.Person.PRINCIPAL_NAME);
103        if ( StringUtils.isBlank(principalId) && StringUtils.isNotBlank(principalName) ) {
104                Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
105                if ( principal != null ) {
106                        principalId = principal.getPrincipalId();
107                }
108        }
109        if ( principalId != null ) {
110                personDocumentForm.setPrincipalId(principalId);
111        }
112        forward = super.execute(mapping, form, request, response);
113        personDocumentForm.setCanModifyEntity(getUiDocumentService().canModifyEntity(GlobalVariables.getUserSession().getPrincipalId(), personDocumentForm.getPrincipalId()));
114        EntityDefault origEntity = null;
115        if(personDocumentForm.getPersonDocument()!=null) {
116                        origEntity = getIdentityService().getEntityDefault(personDocumentForm.getPersonDocument().getEntityId());
117                }
118        boolean isCreatingNew = (personDocumentForm.getPersonDocument()==null || origEntity==null)?true:false;
119        personDocumentForm.setCanOverrideEntityPrivacyPreferences(isCreatingNew || getUiDocumentService().canOverrideEntityPrivacyPreferences(GlobalVariables.getUserSession().getPrincipalId(), personDocumentForm.getPrincipalId()));
120                return forward;
121    }
122
123        @Override
124        protected void loadDocument(KualiDocumentFormBase form)
125                        throws WorkflowException {
126                super.loadDocument(form);
127        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
128                IdentityManagementPersonDocument personDoc = personDocumentForm.getPersonDocument();
129                populateRoleInformation(personDoc);
130        personDoc.resyncTransientState();
131        }
132
133        protected void populateRoleInformation( IdentityManagementPersonDocument personDoc ) {
134                for (PersonDocumentRole role : personDoc.getRoles()) {
135//                      try {
136            KimType type = KimApiServiceLocator.getKimTypeInfoService().getKimType(role.getKimTypeId());
137            KimTypeService kimTypeService = null;
138            if (StringUtils.isNotBlank(type.getServiceName()))  {
139                kimTypeService = (KimTypeService) KimImplServiceLocator.getBean(type.getServiceName());
140            } else {
141                kimTypeService = getKimTypeService(KimTypeBo.to(role.getKimRoleType()));
142            }
143                if ( kimTypeService != null ) {
144                role.setDefinitions(kimTypeService.getAttributeDefinitions(role.getKimTypeId()));
145                }
146                // when post again, it will need this during populate
147            role.setNewRolePrncpl(new KimDocumentRoleMember());
148            for (KimAttributeField key : role.getDefinitions()) {
149                KimDocumentRoleQualifier qualifier = new KimDocumentRoleQualifier();
150                //qualifier.setQualifierKey(key);
151                        setAttrDefnIdForQualifier(qualifier,key);
152                role.getNewRolePrncpl().getQualifiers().add(qualifier);
153            }
154                role.setAttributeEntry( getUiDocumentService().getAttributeEntries( role.getDefinitions() ) );
155                }
156    }
157
158        @Override
159        protected void createDocument(KualiDocumentFormBase form)
160                        throws WorkflowException {
161                super.createDocument(form);
162        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
163        if(StringUtils.isBlank(personDocumentForm.getPrincipalId())){
164                personDocumentForm.getPersonDocument().initializeDocumentForNewPerson();
165                personDocumentForm.setPrincipalId(personDocumentForm.getPersonDocument().getPrincipalId());
166        } else {
167                getUiDocumentService().loadEntityToPersonDoc(personDocumentForm.getPersonDocument(), personDocumentForm.getPrincipalId() );
168                populateRoleInformation( personDocumentForm.getPersonDocument() );
169                if(personDocumentForm.getPersonDocument()!=null) {
170                                personDocumentForm.getPersonDocument().setIfRolesEditable();
171                        }
172        }
173        }
174
175        /***
176         * @see org.kuali.rice.kim.web.struts.action.IdentityManagementDocumentActionBase#getActionName()
177         */
178        @Override
179        public String getActionName(){
180                return KimConstants.KimUIConstants.KIM_PERSON_DOCUMENT_ACTION;
181        }
182
183        public ActionForward addAffln(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
184        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
185        PersonDocumentAffiliation newAffln = personDocumentForm.getNewAffln();
186        newAffln.setDocumentNumber(personDocumentForm.getPersonDocument().getDocumentNumber());
187        KradDataServiceLocator.getDataObjectService().wrap(newAffln).fetchRelationship("affiliationType");
188        personDocumentForm.getPersonDocument().getAffiliations().add(newAffln);
189        personDocumentForm.setNewAffln(new PersonDocumentAffiliation());        
190        return mapping.findForward(RiceConstants.MAPPING_BASIC);
191    }
192        
193    public ActionForward deleteAffln(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
194        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
195        personDocumentForm.getPersonDocument().getAffiliations().remove(getLineToDelete(request));
196        return mapping.findForward(RiceConstants.MAPPING_BASIC);
197    }
198    public ActionForward addCitizenship(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
199        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
200        PersonDocumentCitizenship newCitizenship = personDocumentForm.getNewCitizenship();
201        personDocumentForm.getPersonDocument().getCitizenships().add(newCitizenship);
202        personDocumentForm.setNewCitizenship(new PersonDocumentCitizenship());        
203        return mapping.findForward(RiceConstants.MAPPING_BASIC);
204    }
205    
206    public ActionForward deleteCitizenship(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
207        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
208        personDocumentForm.getPersonDocument().getCitizenships().remove(getLineToDelete(request));
209        return mapping.findForward(RiceConstants.MAPPING_BASIC);
210    }
211
212    public ActionForward addEmpInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
213        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
214        IdentityManagementPersonDocument personDOc = personDocumentForm.getPersonDocument();
215        PersonDocumentAffiliation affiliation = personDOc.getAffiliations().get(getSelectedLine(request));        
216        PersonDocumentEmploymentInfo newempInfo = affiliation.getNewEmpInfo();
217        newempInfo.setDocumentNumber(personDOc.getDocumentNumber());
218        newempInfo.setVersionNumber(1L);
219        affiliation.getEmpInfos().add(newempInfo);
220        affiliation.setNewEmpInfo(new PersonDocumentEmploymentInfo());        
221        return mapping.findForward(RiceConstants.MAPPING_BASIC);
222    }
223    
224    public ActionForward deleteEmpInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
225        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
226        String selectedIndexes = getSelectedParentChildIdx(request);
227        if (selectedIndexes != null) {
228                String [] indexes = StringUtils.split(selectedIndexes,":");
229                PersonDocumentAffiliation affiliation = personDocumentForm.getPersonDocument().getAffiliations().get(Integer.parseInt(indexes[0]));
230                affiliation.getEmpInfos().remove(Integer.parseInt(indexes[1]));
231        }
232        return mapping.findForward(RiceConstants.MAPPING_BASIC);
233    }
234    
235    protected String getSelectedParentChildIdx(HttpServletRequest request) {
236        String lineNumber = null;
237        String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
238        if (StringUtils.isNotBlank(parameterName)) {
239            lineNumber = StringUtils.substringBetween(parameterName, ".line", ".");
240        }
241        return lineNumber;
242    }
243
244    public ActionForward addName(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
245        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
246        PersonDocumentName newName = personDocumentForm.getNewName();
247        newName.setDocumentNumber(personDocumentForm.getDocument().getDocumentNumber());
248        personDocumentForm.getPersonDocument().getNames().add(newName);
249        personDocumentForm.setNewName(new PersonDocumentName());        
250        return mapping.findForward(RiceConstants.MAPPING_BASIC);
251    }
252    
253    public ActionForward deleteName(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
254        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
255        personDocumentForm.getPersonDocument().getNames().remove(getLineToDelete(request));
256        return mapping.findForward(RiceConstants.MAPPING_BASIC);
257    }
258
259    public ActionForward addAddress(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
260        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
261        PersonDocumentAddress newAddress = personDocumentForm.getNewAddress();
262        newAddress.setDocumentNumber(personDocumentForm.getDocument().getDocumentNumber());
263        personDocumentForm.getPersonDocument().getAddrs().add(newAddress);
264        personDocumentForm.setNewAddress(new PersonDocumentAddress());        
265        return mapping.findForward(RiceConstants.MAPPING_BASIC);
266    }
267    
268    public ActionForward deleteAddress(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
269        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
270        personDocumentForm.getPersonDocument().getAddrs().remove(getLineToDelete(request));
271        return mapping.findForward(RiceConstants.MAPPING_BASIC);
272    }
273
274    public ActionForward addPhone(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
275        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
276        PersonDocumentPhone newPhone = personDocumentForm.getNewPhone();
277        newPhone.setDocumentNumber(personDocumentForm.getDocument().getDocumentNumber());
278        personDocumentForm.getPersonDocument().getPhones().add(newPhone);
279        personDocumentForm.setNewPhone(new PersonDocumentPhone());        
280        return mapping.findForward(RiceConstants.MAPPING_BASIC);
281    }
282    
283    public ActionForward deletePhone(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
284        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
285        personDocumentForm.getPersonDocument().getPhones().remove(getLineToDelete(request));
286        return mapping.findForward(RiceConstants.MAPPING_BASIC);
287    }
288
289    public ActionForward addEmail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
290        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
291        PersonDocumentEmail newEmail = personDocumentForm.getNewEmail();
292        newEmail.setDocumentNumber(personDocumentForm.getDocument().getDocumentNumber());
293        personDocumentForm.getPersonDocument().getEmails().add(newEmail);
294        personDocumentForm.setNewEmail(new PersonDocumentEmail());        
295        return mapping.findForward(RiceConstants.MAPPING_BASIC);
296    }
297    
298    public ActionForward deleteEmail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
299        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
300        personDocumentForm.getPersonDocument().getEmails().remove(getLineToDelete(request));
301        return mapping.findForward(RiceConstants.MAPPING_BASIC);
302    }
303
304    public ActionForward addGroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
305        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
306        PersonDocumentGroup newGroup = personDocumentForm.getNewGroup();
307        if (newGroup.getGroupName() == null 
308                        && newGroup.getNamespaceCode() == null 
309                        && newGroup.getGroupId() != null) {
310                Group tempGroup = KimApiServiceLocator.getGroupService().getGroup(newGroup.getGroupId());
311            if (tempGroup == null) {
312                GlobalVariables.getMessageMap().putError("newGroup.groupId",
313                    RiceKeyConstants.ERROR_ASSIGN_GROUP_INVALID,
314                    new String[] { newGroup.getGroupId(),""});
315                return mapping.findForward(RiceConstants.MAPPING_BASIC);
316            }
317                newGroup.setGroupName(tempGroup.getName());
318                newGroup.setNamespaceCode(tempGroup.getNamespaceCode());
319                newGroup.setKimTypeId(tempGroup.getKimTypeId());
320        } else if (StringUtils.isBlank(newGroup.getGroupName())
321                 || StringUtils.isBlank(newGroup.getNamespaceCode())) {
322                 GlobalVariables.getMessageMap().putError("newGroup.groupName",
323                      RiceKeyConstants.ERROR_ASSIGN_GROUP_INVALID,
324                      new String[] { newGroup.getNamespaceCode(), newGroup.getGroupName()});
325                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
326        }
327        Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(
328            newGroup.getNamespaceCode(), newGroup.getGroupName());
329        if (tempGroup == null) {
330            GlobalVariables.getMessageMap().putError("newGroup.groupName",
331                    RiceKeyConstants.ERROR_ASSIGN_GROUP_INVALID,
332                    new String[] { newGroup.getNamespaceCode(), newGroup.getGroupName()});
333            return mapping.findForward(RiceConstants.MAPPING_BASIC);
334        }
335        newGroup.setGroupId(tempGroup.getId());
336            newGroup.setKimTypeId(tempGroup.getKimTypeId());
337        if (getKualiRuleService().applyRules(new AddGroupEvent("",personDocumentForm.getPersonDocument(), newGroup))) {
338                Group group = getGroupService().getGroup(newGroup.getGroupId());
339                newGroup.setGroupName(group.getName());
340                newGroup.setNamespaceCode(group.getNamespaceCode());
341                newGroup.setKimTypeId(group.getKimTypeId());
342                personDocumentForm.getPersonDocument().getGroups().add(newGroup);
343                personDocumentForm.setNewGroup(new PersonDocumentGroup());
344        }
345        return mapping.findForward(RiceConstants.MAPPING_BASIC);
346    }
347    
348    public ActionForward deleteGroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
349        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
350        PersonDocumentGroup inactivedGroupMembership = personDocumentForm.getPersonDocument().getGroups().get(getLineToDelete(request));
351        Calendar cal = Calendar.getInstance();
352        inactivedGroupMembership.setActiveToDate(new Timestamp(cal.getTimeInMillis()));        
353        personDocumentForm.getPersonDocument().getGroups().set(getLineToDelete(request), inactivedGroupMembership);
354        return mapping.findForward(RiceConstants.MAPPING_BASIC);
355    }
356
357       public ActionForward addRole(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
358        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
359        PersonDocumentRole newRole = personDocumentForm.getNewRole();
360
361        if (getKualiRuleService().applyRules(new AddRoleEvent("",personDocumentForm.getPersonDocument(), newRole))) {
362         Role role = KimApiServiceLocator.getRoleService().getRole(newRole.getRoleId());
363         if(!validateRole(newRole.getRoleId(), role, PersonDocumentRoleRule.ERROR_PATH, "Person")){
364          return mapping.findForward(RiceConstants.MAPPING_BASIC);
365         }
366         newRole.setRoleName(role.getName());
367         newRole.setNamespaceCode(role.getNamespaceCode());
368         newRole.setKimTypeId(role.getKimTypeId());
369            KimDocumentRoleMember roleMember = new KimDocumentRoleMember();
370            roleMember.setMemberId(personDocumentForm.getPrincipalId());
371            roleMember.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
372            roleMember.setRoleId(newRole.getRoleId());
373            roleMember.setActiveFromDate(newRole.getNewRolePrncpl().getActiveFromDate());
374            roleMember.setActiveToDate(newRole.getNewRolePrncpl().getActiveToDate());
375            newRole.setNewRolePrncpl(roleMember);
376         if(!validateRoleAssignment(personDocumentForm.getPersonDocument(), newRole)){
377          return mapping.findForward(RiceConstants.MAPPING_BASIC);
378         }
379         KimTypeService kimTypeService = getKimTypeService(KimTypeBo.to(newRole.getKimRoleType()));
380         //AttributeDefinitionMap definitions = kimTypeService.getAttributeDefinitions();
381         // role type populated from form is not a complete record
382         if ( kimTypeService != null ) {
383          newRole.setDefinitions(kimTypeService.getAttributeDefinitions(newRole.getKimTypeId()));
384         }
385         KimDocumentRoleMember newRolePrncpl = newRole.getNewRolePrncpl();
386
387         for (KimAttributeField key : newRole.getDefinitions()) {
388          KimDocumentRoleQualifier qualifier = new KimDocumentRoleQualifier();
389          //qualifier.setQualifierKey(key);
390          setAttrDefnIdForQualifier(qualifier,key);
391          newRolePrncpl.getQualifiers().add(qualifier);
392         }
393         if (newRole.getDefinitions().isEmpty()) {
394          List<KimDocumentRoleMember> rolePrncpls = new ArrayList<KimDocumentRoleMember>();
395          setupRoleRspActions(newRole, newRolePrncpl);
396             rolePrncpls.add(newRolePrncpl);
397          newRole.setRolePrncpls(rolePrncpls);
398         }
399         //newRole.setNewRolePrncpl(newRolePrncpl);
400         newRole.setAttributeEntry( getUiDocumentService().getAttributeEntries( newRole.getDefinitions() ) );
401         personDocumentForm.getPersonDocument().getRoles().add(newRole);
402         personDocumentForm.setNewRole(new PersonDocumentRole());
403        }
404        return mapping.findForward(RiceConstants.MAPPING_BASIC);
405    }
406    
407        protected boolean validateRoleAssignment(IdentityManagementPersonDocument document, PersonDocumentRole newRole){
408        boolean rulePassed = true;
409        if(!document.validAssignRole(newRole)){
410                        GlobalVariables.getMessageMap().putError("newRole.roleId", 
411                                        RiceKeyConstants.ERROR_ASSIGN_ROLE, 
412                                        new String[] {newRole.getNamespaceCode(), newRole.getRoleName()});
413                rulePassed = false;
414        }
415                return rulePassed;
416        }
417
418    protected void setupRoleRspActions(PersonDocumentRole role, KimDocumentRoleMember rolePrncpl) {
419        for (RoleResponsibility roleResp : getResponsibilityInternalService().getRoleResponsibilities(role.getRoleId())) {
420                if (getResponsibilityInternalService().areActionsAtAssignmentLevelById(roleResp.getResponsibilityId())) {
421                        KimDocumentRoleResponsibilityAction roleRspAction = new KimDocumentRoleResponsibilityAction();
422                        roleRspAction.setRoleResponsibilityId("*");
423                        // not linked to a role responsibility - so we set the referenced object to null
424                        roleRspAction.setRoleResponsibility(null);
425                roleRspAction.setDocumentNumber(role.getDocumentNumber());
426
427                        if(rolePrncpl.getRoleRspActions()==null || rolePrncpl.getRoleRspActions().isEmpty()){
428                                if(rolePrncpl.getRoleRspActions()==null) {
429                                                rolePrncpl.setRoleRspActions(new ArrayList<KimDocumentRoleResponsibilityAction>());
430                                        }
431                                 rolePrncpl.getRoleRspActions().add(roleRspAction);
432                        }
433                }               
434        }
435    }
436    
437//      protected boolean isUniqueRoleRspAction(List<KimDocumentRoleResponsibilityAction> roleRspActions, KimDocumentRoleResponsibilityAction roleRspAction){
438//      if(roleRspActions==null || roleRspAction==null) return false;
439//      for(KimDocumentRoleResponsibilityAction roleRspActionTemp: roleRspActions){
440//              if((StringUtils.isNotEmpty(roleRspActionTemp.getRoleMemberId()) && roleRspActionTemp.getRoleMemberId().equals(roleRspAction.getRoleMemberId())) && 
441//                      (StringUtils.isNotEmpty(roleRspActionTemp.getRoleResponsibilityId())    && roleRspActionTemp.getRoleResponsibilityId().equals(roleRspAction.getRoleResponsibilityId())))
442//                      return false;
443//      }
444//      return true;
445//    }
446            
447
448    protected void setAttrDefnIdForQualifier(KimDocumentRoleQualifier qualifier,KimAttributeField definition) {
449                qualifier.setKimAttrDefnId(definition.getId());
450                KradDataServiceLocator.getDataObjectService().wrap(qualifier).fetchRelationship("kimAttribute");
451    }
452
453    public ActionForward deleteRole(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
454        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
455        PersonDocumentRole personDocumentRole = personDocumentForm.getPersonDocument().getRoles().get(getLineToDelete(request));
456        Calendar cal = Calendar.getInstance();
457        personDocumentRole.getRolePrncpls().get(0).setActiveToDate(new Timestamp(cal.getTimeInMillis()));
458        personDocumentForm.getPersonDocument().getRoles().set(getLineToDelete(request), personDocumentRole);
459        return mapping.findForward(RiceConstants.MAPPING_BASIC);
460    }
461
462    public ActionForward addRoleQualifier(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
463        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
464        IdentityManagementPersonDocument personDOc = personDocumentForm.getPersonDocument();
465        int selectedRoleIdx = getSelectedLine(request);
466        PersonDocumentRole role = personDOc.getRoles().get(selectedRoleIdx);
467        KimDocumentRoleMember newRolePrncpl = role.getNewRolePrncpl();
468        newRolePrncpl.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
469        newRolePrncpl.setMemberId(personDOc.getPrincipalId());
470        
471        if (getKualiRuleService().applyRules(new AddPersonDocumentRoleQualifierEvent("",
472                        personDOc, newRolePrncpl, role, selectedRoleIdx))) {
473                setupRoleRspActions(role, newRolePrncpl);
474                role.getRolePrncpls().add(newRolePrncpl);
475            KimDocumentRoleMember roleMember = new KimDocumentRoleMember();
476            roleMember.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
477            roleMember.setMemberId(personDocumentForm.getPrincipalId());
478                role.setNewRolePrncpl(roleMember);
479                for (KimAttributeField key : role.getDefinitions()) {
480                        KimDocumentRoleQualifier qualifier = new KimDocumentRoleQualifier();
481                        //qualifier.setQualifierKey(key);
482                        setAttrDefnIdForQualifier(qualifier,key);
483                        role.getNewRolePrncpl().getQualifiers().add(qualifier);
484                }
485        }
486
487        return mapping.findForward(RiceConstants.MAPPING_BASIC);
488    }
489
490    public ActionForward deleteRoleQualifier(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
491        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
492        String selectedIndexes = getSelectedParentChildIdx(request);
493        if (selectedIndexes != null) {
494                String [] indexes = StringUtils.split(selectedIndexes,":");
495                PersonDocumentRole role = personDocumentForm.getPersonDocument().getRoles().get(Integer.parseInt(indexes[0]));
496            KimDocumentRoleMember member = role.getRolePrncpls().get(Integer.parseInt(indexes[1]));
497            Calendar cal = Calendar.getInstance();
498            member.setActiveToDate(new Timestamp(cal.getTimeInMillis()));
499            // role.getRolePrncpls().remove(Integer.parseInt(indexes[1]));
500        }
501        return mapping.findForward(RiceConstants.MAPPING_BASIC);
502
503    }
504    
505    public ActionForward addDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
506        IdentityManagementPersonDocumentForm personDocumentForm = (IdentityManagementPersonDocumentForm) form;
507        IdentityManagementPersonDocument personDocument = personDocumentForm.getPersonDocument();
508        RoleDocumentDelegationMember newDelegationMember = personDocumentForm.getNewDelegationMember();
509        KimTypeAttributesHelper attrHelper = newDelegationMember.getAttributesHelper();
510        if (getKualiRuleService().applyRules(new AddPersonDelegationMemberEvent("", personDocumentForm.getPersonDocument(), newDelegationMember))) {
511                Role role = KimApiServiceLocator.getRoleService().getRole(newDelegationMember.getRoleBo().getId());
512                if (role != null) {
513                        if(!validateRole(newDelegationMember.getRoleBo().getId(),role, PersonDocumentRoleRule.ERROR_PATH, "Person")){
514                                return mapping.findForward(RiceConstants.MAPPING_BASIC);
515                        }
516                        newDelegationMember.setRoleBo(RoleBo.from(role));
517                }
518                KimAttributeField attrDefinition;
519                RoleMemberBo roleMember = KIMServiceLocatorInternal.getUiDocumentService().getRoleMember(newDelegationMember.getRoleMemberId());
520                Map<String, String>
521                    roleMemberAttributes = (new AttributeValidationHelper()).convertAttributesToMap(roleMember.getAttributeDetails());
522                for (KimAttributeField key: attrHelper.getDefinitions()) {
523                        RoleDocumentDelegationMemberQualifier qualifier = new RoleDocumentDelegationMemberQualifier();
524                        attrDefinition = key;
525                        qualifier.setKimAttrDefnId(attrHelper.getKimAttributeDefnId(attrDefinition));
526                        qualifier.setAttrVal(attrHelper.getAttributeValue(roleMemberAttributes, attrDefinition.getAttributeField().getName()));
527                        newDelegationMember.setMemberTypeCode(MemberType.PRINCIPAL.getCode());
528                        newDelegationMember.getQualifiers().add(qualifier);
529                }
530                //newDelegationMember.setAttributeEntry(getUiDocumentService().getAttributeEntries(newDelegationMember.getAttributesHelper().getDefinitions())));
531            newDelegationMember.setMemberId(personDocument.getPrincipalId());
532                personDocument.getDelegationMembers().add(newDelegationMember);
533                personDocumentForm.setNewDelegationMember(new RoleDocumentDelegationMember());
534        }
535        return mapping.findForward(RiceConstants.MAPPING_BASIC);
536    }
537    
538    public ActionForward deleteDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
539        IdentityManagementPersonDocument personDocument = ((IdentityManagementPersonDocumentForm)form).getPersonDocument();
540        int lineToDelete = getLineToDelete(request);
541        RoleDocumentDelegationMember deletedMember = personDocument.getDelegationMembers().remove(lineToDelete);
542
543        // determine if we just deleted the last member from the role delegation, there should only be one but we will
544        // use a list just to make sure we get any delegations that no longer have any members
545        List<RoleDocumentDelegation> delegationsToRemove = new ArrayList<>();
546        for (RoleDocumentDelegation delegation : personDocument.getDelegations()) {
547            delegation.getMembers().remove(deletedMember);
548            if (delegation.getMembers().isEmpty()) {
549                delegationsToRemove.add(delegation);
550            }
551        }
552        for (RoleDocumentDelegation delegationToRemove : delegationsToRemove) {
553            personDocument.getDelegations().remove(delegationToRemove);
554        }
555
556        return mapping.findForward(RiceConstants.MAPPING_BASIC);
557    }
558
559        @Override
560        public ActionForward save(ActionMapping mapping, ActionForm form,
561                        HttpServletRequest request, HttpServletResponse response)
562                        throws Exception {
563
564                return super.save(mapping, form, request, response);
565        }
566        
567    @Override
568    public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
569        IdentityManagementPersonDocumentForm impdForm = (IdentityManagementPersonDocumentForm) form;
570
571        ActionForward forward = this.refreshAfterDelegationMemberRoleSelection(mapping, impdForm, request);
572        if (forward != null) {
573            return forward;
574        }
575
576        return super.refresh(mapping, form, request, response);
577        }
578    
579    protected ActionForward refreshAfterDelegationMemberRoleSelection(ActionMapping mapping, IdentityManagementPersonDocumentForm impdForm, HttpServletRequest request) {
580        String refreshCaller = impdForm.getRefreshCaller();
581
582        boolean isRoleLookupable = KimConstants.KimUIConstants.ROLE_LOOKUPABLE_IMPL.equals(refreshCaller);
583        boolean isRoleMemberLookupable = KimConstants.KimUIConstants.KIM_DOCUMENT_ROLE_MEMBER_LOOKUPABLE_IMPL.equals(refreshCaller);
584
585        // do not execute the further refreshing logic if the refresh caller is not a lookupable
586        if (!isRoleLookupable && !isRoleMemberLookupable) {
587            return null;
588        }
589
590        //In case of delegation member lookup impdForm.getNewDelegationMemberRoleId() will be populated.
591        if(impdForm.getNewDelegationMemberRoleId() == null){
592            return null;
593        }
594        if(isRoleLookupable){
595            return renderRoleMemberSelection(mapping, request, impdForm);
596        }
597
598        String roleMemberId = request.getParameter(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID);
599        if(StringUtils.isNotBlank(roleMemberId)){
600            impdForm.getNewDelegationMember().setRoleMemberId(roleMemberId);
601            RoleMemberBo roleMember = getUiDocumentService().getRoleMember(roleMemberId);
602            impdForm.getNewDelegationMember().setRoleMemberMemberId(roleMember.getMemberId());
603            impdForm.getNewDelegationMember().setRoleMemberMemberTypeCode(roleMember.getType().getCode());
604            impdForm.getNewDelegationMember().setRoleMemberName(getUiDocumentService().getMemberName(MemberType.fromCode(impdForm.getNewDelegationMember().getRoleMemberMemberTypeCode()), impdForm.getNewDelegationMember().getRoleMemberMemberId()));
605            impdForm.getNewDelegationMember().setRoleMemberNamespaceCode(getUiDocumentService().getMemberNamespaceCode(MemberType.fromCode(impdForm.getNewDelegationMember().getRoleMemberMemberTypeCode()), impdForm.getNewDelegationMember().getRoleMemberMemberId()));
606
607            Role role;
608                role = KimApiServiceLocator.getRoleService().getRole(impdForm.getNewDelegationMember().getRoleBo().getId());
609                if (role != null) {
610                        if(!validateRole(impdForm.getNewDelegationMember().getRoleBo().getId(), role, PersonDocumentRoleRule.ERROR_PATH, "Person")){
611                                return mapping.findForward(RiceConstants.MAPPING_BASIC);
612                        }
613                        impdForm.getNewDelegationMember().setRoleBo(RoleBo.from(role));
614                }
615        }
616        impdForm.setNewDelegationMemberRoleId(null);
617        return null;
618    }
619    
620    protected ActionForward renderRoleMemberSelection(ActionMapping mapping, HttpServletRequest request, IdentityManagementPersonDocumentForm impdForm) {
621        Properties props = new Properties();
622
623        props.put(KRADConstants.SUPPRESS_ACTIONS, Boolean.toString(true));
624        props.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, KimDocumentRoleMember.class.getName());
625        props.put(KRADConstants.LOOKUP_ANCHOR, KRADConstants.ANCHOR_TOP_OF_FORM);
626        props.put(KRADConstants.LOOKED_UP_COLLECTION_NAME, KimConstants.KimUIConstants.ROLE_MEMBERS_COLLECTION_NAME);
627
628        String conversionPatttern = "{0}" + KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR + "{0}";
629        StringBuilder fieldConversion = new StringBuilder();
630        fieldConversion.append(MessageFormat.format(conversionPatttern, 
631                KimConstants.PrimaryKeyConstants.SUB_ROLE_ID)).append(KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
632        fieldConversion.append(MessageFormat.format(conversionPatttern, 
633                        KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID)).append(KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
634
635        props.put(KRADConstants.CONVERSION_FIELDS_PARAMETER, fieldConversion);
636
637        props.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, impdForm.getNewDelegationMember().getRoleBo().getId());
638
639        props.put(KRADConstants.RETURN_LOCATION_PARAMETER, this.getReturnLocation(request, mapping));
640     //   props.put(KRADConstants.BACK_LOCATION, this.getReturnLocation(request, mapping));
641
642        props.put(KRADConstants.LOOKUP_AUTO_SEARCH, "Yes");
643        props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.SEARCH_METHOD);
644
645        props.put(KRADConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(impdForm));
646     //   props.put(KRADConstants.DOC_NUM, impdForm.getDocument().getDocumentNumber());
647
648        // TODO: how should this forward be handled
649        String url = UrlFactory.parameterizeUrl(getApplicationBaseUrl() + "/kr/" + KRADConstants.LOOKUP_ACTION, props);
650
651        impdForm.registerEditableProperty("methodToCall");
652
653        return new ActionForward(url, true);
654    }
655
656
657    public ResponsibilityInternalService getResponsibilityInternalService() {
658        if ( responsibilityInternalService == null ) {
659                responsibilityInternalService = KimImplServiceLocator.getResponsibilityInternalService();
660        }
661                return responsibilityInternalService;
662        }
663}