View Javadoc

1   /*
2    * Copyright 2007-2009 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.web.struts.action;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.struts.action.ActionForm;
20  import org.apache.struts.action.ActionForward;
21  import org.apache.struts.action.ActionMapping;
22  import org.kuali.rice.core.api.util.RiceConstants;
23  import org.kuali.rice.core.api.util.RiceKeyConstants;
24  import org.kuali.rice.kew.exception.WorkflowException;
25  import org.kuali.rice.kim.api.group.Group;
26  import org.kuali.rice.kim.api.identity.principal.Principal;
27  import org.kuali.rice.kim.api.role.Role;
28  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
29  import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
30  import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission;
31  import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
32  import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility;
33  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
34  import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
35  import org.kuali.rice.kim.document.IdentityManagementRoleDocument;
36  import org.kuali.rice.kim.impl.responsibility.AddResponsibilityEvent;
37  import org.kuali.rice.kim.impl.responsibility.ResponsibilityBo;
38  import org.kuali.rice.kim.impl.type.KimTypeLookupableHelperServiceImpl;
39  import org.kuali.rice.kim.rule.event.ui.AddDelegationMemberEvent;
40  import org.kuali.rice.kim.rule.event.ui.AddMemberEvent;
41  import org.kuali.rice.kim.rule.event.ui.AddPermissionEvent;
42  import org.kuali.rice.kim.util.KimConstants;
43  import org.kuali.rice.kim.web.struts.form.IdentityManagementRoleDocumentForm;
44  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
45  import org.kuali.rice.kns.web.struts.form.KualiTableRenderFormMetadata;
46  import org.kuali.rice.krad.question.ConfirmationQuestion;
47  import org.kuali.rice.krad.service.KRADServiceLocator;
48  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
49  import org.kuali.rice.krad.util.GlobalVariables;
50  import org.kuali.rice.krad.util.KRADConstants;
51  
52  import javax.servlet.http.HttpServletRequest;
53  import javax.servlet.http.HttpServletResponse;
54  import java.sql.Timestamp;
55  import java.util.ArrayList;
56  import java.util.Arrays;
57  import java.util.Calendar;
58  import java.util.HashMap;
59  import java.util.List;
60  import java.util.Map;
61  
62  /**
63   * @author Kuali Rice Team (rice.collab@kuali.org)
64   */
65  public class IdentityManagementRoleDocumentAction extends IdentityManagementDocumentActionBase {
66  
67      public static final String CHANGE_DEL_ROLE_MEMBER_METHOD_TO_CALL = "changeDelegationRoleMember";
68      public static final String SWITCH_TO_ROLE_MEMBER_METHOD_TO_CALL = "jumpToRoleMember";
69      public static final String REMOVE_AFFECTED_DELEGATES_QUESTION_ID = "RemoveAffectedDelegates";
70  
71      protected List<String> methodToCallToUncheckedList = new ArrayList<String>();
72  	
73      /**
74       * This method doesn't actually sort the column - it's just that we need a sort method in
75       * order to exploit the existing methodToCall logic. The sorting is handled in the execute
76       * method below, and delegated to the KualiTableRenderFormMetadata object. 
77       * 
78       * @param mapping
79       * @param form 
80       * @param request
81       * @param response
82       * @return
83       * @throws Exception
84       */
85      {
86          methodToCallToUncheckedList.add(CHANGE_DEL_ROLE_MEMBER_METHOD_TO_CALL);
87          methodToCallToUncheckedList.add(CHANGE_MEMBER_TYPE_CODE_METHOD_TO_CALL);
88          methodToCallToUncheckedList.add(CHANGE_NAMESPACE_METHOD_TO_CALL);
89          methodToCallToUncheckedList.add(SWITCH_TO_ROLE_MEMBER_METHOD_TO_CALL);
90      }
91  
92      /**
93       * This constructs a ...
94       */
95      public IdentityManagementRoleDocumentAction() {
96          super();
97          for (String methodToCallToUncheck : methodToCallToUncheckedList) {
98              addMethodToCallToUncheckedList(methodToCallToUncheck);
99          }
100     }
101 
102     public ActionForward sort(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
103 
104     	return mapping.findForward(RiceConstants.MAPPING_BASIC);
105     }
106 
107     @Override
108 	public ActionForward execute(ActionMapping mapping, ActionForm form,
109 			HttpServletRequest request, HttpServletResponse response) throws Exception {
110         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
111         if (roleDocumentForm.getRoleId() == null) {
112             String roleId = request.getParameter(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID);
113             roleDocumentForm.setRoleId(roleId);
114         }
115 
116 		KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata();
117 		if (roleDocumentForm.getRoleDocument()!=null && roleDocumentForm.getMemberRows() != null) {
118 			memberTableMetadata.jumpToPage(memberTableMetadata.getViewedPageNumber(), roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage());
119 			// KULRICE-3972: need to be able to sort by column header like on lookups when editing large roles and groups
120 			memberTableMetadata.sort(roleDocumentForm.getMemberRows(), roleDocumentForm.getRecordsPerPage());
121 		}
122 
123         // KULRICE-4762: active delegates of "inactivated" role members cause validation problems
124         ActionForward forward = promptForAffectedDelegates(mapping, form, request, response,
125                 roleDocumentForm);
126         // if we need to prompt the user due to affected delegates, do so:
127         if (forward != null) { return forward; }
128 
129         forward = super.execute(mapping, roleDocumentForm, request, response);
130 
131         roleDocumentForm.setCanAssignRole(validAssignRole(roleDocumentForm.getRoleDocument()));
132         if (KimTypeLookupableHelperServiceImpl.hasDerivedRoleTypeService(roleDocumentForm.getRoleDocument().getKimType())) {
133             roleDocumentForm.setCanModifyAssignees(false);
134         }
135         GlobalVariables.getUserSession().addObject(KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_SHORT_KEY, roleDocumentForm.getRoleDocument());
136         return forward;
137     }
138 
139     /**
140      * This overridden method ...
141      *
142      * @see org.kuali.rice.krad.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.rice.krad.web.struts.form.KualiDocumentFormBase)
143      */
144     @Override
145     protected void loadDocument(KualiDocumentFormBase form)
146             throws WorkflowException {
147         super.loadDocument(form);
148 
149         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
150         setKimType(roleDocumentForm.getRoleDocument().getRoleTypeId(), roleDocumentForm);
151         getUiDocumentService().setDelegationMembersInDocument(roleDocumentForm.getRoleDocument());
152 
153         roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember());
154         roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember());
155 
156         KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata();
157         if (roleDocumentForm.getMemberRows() != null) {
158             memberTableMetadata.jumpToFirstPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage());
159         }
160     }
161 
162     /**
163      * This overridden method ...
164      *
165      * @see org.kuali.rice.krad.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.krad.web.struts.form.KualiDocumentFormBase)
166      */
167     @Override
168     protected void createDocument(KualiDocumentFormBase form)
169             throws WorkflowException {
170         super.createDocument(form);
171         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
172 
173         if (roleDocumentForm.getRoleId() == null) {
174             roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType());
175             roleDocumentForm.getRoleDocument().initializeDocumentForNewRole();
176             roleDocumentForm.setRoleId(roleDocumentForm.getRoleDocument().getRoleId());
177             roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(roleDocumentForm.getRoleDocument().getRoleTypeId()));
178         } else {
179             loadRoleIntoDocument(roleDocumentForm.getRoleId(), roleDocumentForm);
180         }
181 
182         roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember());
183         roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember());
184 
185         KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata();
186         if (roleDocumentForm.getMemberRows() != null) {
187             memberTableMetadata.jumpToFirstPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage());
188         }
189     }
190 
191     protected void setKimType(String kimTypeId, IdentityManagementRoleDocumentForm roleDocumentForm) {
192         if (StringUtils.isNotBlank(kimTypeId)) {
193             roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId));
194             if (roleDocumentForm.getRoleDocument() != null) {
195                 roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType());
196             }
197         } else if (roleDocumentForm.getRoleDocument() != null && StringUtils.isNotBlank(roleDocumentForm.getRoleDocument().getRoleTypeId())) {
198             roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(
199                     roleDocumentForm.getRoleDocument().getRoleTypeId()));
200             roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType());
201         }
202     }
203 
204     protected void loadRoleIntoDocument(String roleId, IdentityManagementRoleDocumentForm roleDocumentForm) {
205         Role role = KimApiServiceLocator.getRoleService().getRole(roleId);
206         roleDocumentForm.getRoleDocument().setMemberMetaDataTypeToSort(roleDocumentForm.getMemberTableMetadata().getColumnToSortIndex());
207         getUiDocumentService().loadRoleDoc(roleDocumentForm.getRoleDocument(), role);
208     }
209 
210     /**
211      * @see org.kuali.rice.kim.web.struts.action.IdentityManagementDocumentActionBase#getActionName()
212      */
213     public String getActionName() {
214         return KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_ACTION;
215     }
216 
217     protected boolean validAssignRole(IdentityManagementRoleDocument document) {
218         boolean rulePassed = true;
219         if (StringUtils.isNotEmpty(document.getRoleNamespace())) {
220             Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
221             additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace());
222             additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName());
223             if (!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate(
224                     document,
225                     KimConstants.NAMESPACE_CODE,
226                     KimConstants.PermissionTemplateNames.ASSIGN_ROLE,
227                     GlobalVariables.getUserSession().getPrincipalId(),
228                     additionalPermissionDetails, null)) {
229                 rulePassed = false;
230             }
231         }
232         return rulePassed;
233     }
234 
235     public ActionForward changeMemberTypeCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
236         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
237         roleDocumentForm.getMember().setMemberId("");
238         return refresh(mapping, roleDocumentForm, request, response);
239     }
240 
241     public ActionForward changeDelegationMemberTypeCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
242         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
243         KimDocumentRoleMember roleMember = roleDocumentForm.getRoleDocument().getMember(roleDocumentForm.getDelegationMember().getRoleMemberId());
244         if (roleMember != null) {
245             RoleDocumentDelegationMemberQualifier delegationMemberQualifier;
246             for (KimDocumentRoleQualifier roleQualifier : roleMember.getQualifiers()) {
247                 delegationMemberQualifier = roleDocumentForm.getDelegationMember().getQualifier(roleQualifier.getKimAttrDefnId());
248                 delegationMemberQualifier.setAttrVal(roleQualifier.getAttrVal());
249             }
250         }
251         return refresh(mapping, roleDocumentForm, request, response);
252     }
253 
254     public ActionForward addResponsibility(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
255         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
256         KimDocumentRoleResponsibility newResponsibility = roleDocumentForm.getResponsibility();
257         if (newResponsibility != null && StringUtils.isNotBlank(newResponsibility.getResponsibilityId())) {
258             Map<String, String> criteria = new HashMap<String, String>();
259             criteria.put(KimConstants.PrimaryKeyConstants.RESPONSIBILITY_ID, newResponsibility.getResponsibilityId());
260             ResponsibilityBo responsibilityImpl = KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(ResponsibilityBo.class, criteria);
261             newResponsibility.setKimResponsibility(responsibilityImpl);
262         }
263 
264         if (KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddResponsibilityEvent("", roleDocumentForm.getRoleDocument(), newResponsibility))) {
265             if (newResponsibility != null) {
266                 newResponsibility.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber());
267             }
268             roleDocumentForm.getRoleDocument().addResponsibility(newResponsibility);
269             roleDocumentForm.setResponsibility(new KimDocumentRoleResponsibility());
270             roleDocumentForm.getRoleDocument().updateMembers(newResponsibility);
271         }
272         return mapping.findForward(RiceConstants.MAPPING_BASIC);
273     }
274 
275     public ActionForward deleteResponsibility(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
276         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
277         roleDocumentForm.getRoleDocument().getResponsibilities().remove(getLineToDelete(request));
278         roleDocumentForm.getRoleDocument().updateMembers(roleDocumentForm);
279         return mapping.findForward(RiceConstants.MAPPING_BASIC);
280     }
281 
282     public ActionForward addPermission(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
283         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
284         KimDocumentRolePermission newPermission = roleDocumentForm.getPermission();
285         if (KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddPermissionEvent("", roleDocumentForm.getRoleDocument(), newPermission))) {
286             newPermission.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber());
287             newPermission.setRoleId(roleDocumentForm.getRoleDocument().getRoleId());
288             roleDocumentForm.getRoleDocument().getPermissions().add(newPermission);
289             roleDocumentForm.setPermission(new KimDocumentRolePermission());
290         }
291         return mapping.findForward(RiceConstants.MAPPING_BASIC);
292     }
293 
294     public ActionForward addMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
295         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
296         KimDocumentRoleMember newMember = roleDocumentForm.getMember();
297 
298         //See if possible to add with just Group Details filled in (not returned from lookup)
299         if (StringUtils.isEmpty(newMember.getMemberId())
300                 && StringUtils.isNotEmpty(newMember.getMemberName())
301                 && StringUtils.isNotEmpty(newMember.getMemberNamespaceCode())
302                 && StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE)) {
303             Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByName(newMember.getMemberNamespaceCode(), newMember.getMemberName());
304             if (tempGroup != null) {
305                 newMember.setMemberId(tempGroup.getId());
306             }
307         }
308 
309         //See if possible to grab details for Principal
310         if (StringUtils.isEmpty(newMember.getMemberId())
311                 && StringUtils.isNotEmpty(newMember.getMemberName())
312                 && StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE)) {
313             Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newMember.getMemberName());
314             if (principal != null) {
315                 newMember.setMemberId(principal.getPrincipalId());
316             }
317         }
318         if (checkKimDocumentRoleMember(newMember) &&
319                 KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddMemberEvent("", roleDocumentForm.getRoleDocument(), newMember))) {
320             newMember.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber());
321             roleDocumentForm.getRoleDocument().addMember(newMember);
322             roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember());
323             roleDocumentForm.getMemberTableMetadata().jumpToLastPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage());
324         }
325         return mapping.findForward(RiceConstants.MAPPING_BASIC);
326     }
327 
328     protected boolean checkKimDocumentRoleMember(KimDocumentRoleMember newMember) {
329         boolean memberExists = false;
330         String memberName = null;
331         String memberNamespace = null;
332 
333         if (StringUtils.isBlank(newMember.getMemberTypeCode()) || StringUtils.isBlank(newMember.getMemberId())) {
334             GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_EMPTY_ENTRY,
335                     new String[]{"Member Type Code and Member ID"});
336             return false;
337         }
338 
339         if (KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE.equals(newMember.getMemberTypeCode())) {
340             Principal pi = this.getIdentityService().getPrincipal(newMember.getMemberId());
341             if (pi != null) {
342                 memberExists = true;
343                 memberName = pi.getPrincipalName();
344                 memberNamespace = "";
345             }
346         } else if (KimConstants.KimUIConstants.MEMBER_TYPE_GROUP_CODE.equals(newMember.getMemberTypeCode())) {
347             Group gi = KimApiServiceLocator.getGroupService().getGroup(newMember.getMemberId());
348             if (gi != null) {
349                 memberExists = true;
350                 memberName = gi.getName();
351                 memberNamespace = gi.getNamespaceCode();
352             }
353         } else if (KimConstants.KimUIConstants.MEMBER_TYPE_ROLE_CODE.equals(newMember.getMemberTypeCode())) {
354             Role ri = KimApiServiceLocator.getRoleService().getRole(newMember.getMemberId());
355             if (!validateRole(newMember.getMemberId(), ri, "document.member.memberId", "Role")) {
356                 return false;
357             } else {
358                 memberExists = true;
359                 memberName = ri.getName();
360                 memberNamespace = ri.getNamespaceCode();
361             }
362         }
363 
364         if (!memberExists) {
365             GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH,
366                     new String[]{newMember.getMemberId()});
367             return false;
368         }
369         newMember.setMemberName(memberName);
370         newMember.setMemberNamespaceCode(memberNamespace);
371         return true;
372     }
373 
374     public ActionForward deleteMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
375         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
376         KimDocumentRoleMember inactivatedRoleMember = roleDocumentForm.getRoleDocument().getMembers().get(getLineToDelete(request));
377 
378         // KULRICE-4762: active delegates of "inactivated" role members cause validation problems
379         ActionForward forward = promptForAffectedDelegates(mapping, form, request, response,
380                 roleDocumentForm, /* we haven't actually inactivated them yet, so specify them here */ inactivatedRoleMember);
381         // if we need to prompt the user due to affected delegates, do so:
382         if (forward != null) {
383             return forward;
384         }
385 
386         Calendar cal = Calendar.getInstance();
387         inactivatedRoleMember.setActiveToDate(new Timestamp(cal.getTimeInMillis()));
388 
389         roleDocumentForm.getRoleDocument().getMembers().set(getLineToDelete(request), inactivatedRoleMember);
390         return mapping.findForward(RiceConstants.MAPPING_BASIC);
391     }
392 
393     public ActionForward deletePermission(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
394         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
395         roleDocumentForm.getRoleDocument().getPermissions().remove(getLineToDelete(request));
396         return mapping.findForward(RiceConstants.MAPPING_BASIC);
397     }
398 
399     protected boolean checkDelegationMember(RoleDocumentDelegationMember newMember) {
400         if (StringUtils.isBlank(newMember.getMemberTypeCode()) || StringUtils.isBlank(newMember.getMemberId())) {
401             GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_EMPTY_ENTRY,
402                     new String[]{"Member Type Code and Member ID"});
403             return false;
404         }
405         if (KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE.equals(newMember.getMemberTypeCode())) {
406             Principal principalInfo = getIdentityService().getPrincipal(newMember.getMemberId());
407             if (principalInfo == null) {
408                 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH,
409                         new String[]{newMember.getMemberId()});
410                 return false;
411             } else {
412                 newMember.setMemberName(principalInfo.getPrincipalName());
413             }
414         } else if (KimConstants.KimUIConstants.MEMBER_TYPE_GROUP_CODE.equals(newMember.getMemberTypeCode())) {
415             Group groupInfo = null;
416             groupInfo = getGroupService().getGroup(newMember.getMemberId());
417             if (groupInfo == null) {
418                 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH,
419                         new String[]{newMember.getMemberId()});
420                 return false;
421             } else {
422                 newMember.setMemberName(groupInfo.getName());
423                 newMember.setMemberNamespaceCode(groupInfo.getNamespaceCode());
424             }
425         } else if (KimConstants.KimUIConstants.MEMBER_TYPE_ROLE_CODE.equals(newMember.getMemberTypeCode())) {
426             Role roleInfo = KimApiServiceLocator.getRoleService().getRole(newMember.getMemberId());
427             if (roleInfo == null) {
428                 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH,
429                         new String[]{newMember.getMemberId()});
430                 return false;
431             } else {
432                 newMember.setMemberName(roleInfo.getName());
433                 newMember.setMemberNamespaceCode(roleInfo.getNamespaceCode());
434             }
435         }
436         return true;
437     }
438 
439     public ActionForward addDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
440         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
441         RoleDocumentDelegationMember newDelegationMember = roleDocumentForm.getDelegationMember();
442 
443         //See if possible to add with just Group Details filled in (not returned from lookup)
444         if (StringUtils.isEmpty(newDelegationMember.getMemberId())
445                 && StringUtils.isNotEmpty(newDelegationMember.getMemberName())
446                 && StringUtils.isNotEmpty(newDelegationMember.getMemberNamespaceCode())
447                 && StringUtils.equals(newDelegationMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE)) {
448             Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByName(newDelegationMember.getMemberNamespaceCode(), newDelegationMember.getMemberName());
449             if (tempGroup != null) {
450                 newDelegationMember.setMemberId(tempGroup.getId());
451             }
452         }
453 
454         //See if possible to grab details for Principal
455         if (StringUtils.isEmpty(newDelegationMember.getMemberId())
456                 && StringUtils.isNotEmpty(newDelegationMember.getMemberName())
457                 && StringUtils.equals(newDelegationMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE)) {
458             Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newDelegationMember.getMemberName());
459             if (principal != null) {
460                 newDelegationMember.setMemberId(principal.getPrincipalId());
461             }
462         }
463 
464         if (checkDelegationMember(newDelegationMember) && KRADServiceLocatorWeb.getKualiRuleService().applyRules(
465                 new AddDelegationMemberEvent("", roleDocumentForm.getRoleDocument(), newDelegationMember))) {
466             newDelegationMember.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber());
467             roleDocumentForm.getRoleDocument().addDelegationMember(newDelegationMember);
468             roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember());
469         }
470         return mapping.findForward(RiceConstants.MAPPING_BASIC);
471     }
472 
473     public ActionForward deleteDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
474         IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form;
475         // Removing, not inactivating -- is this what we really want?
476         roleDocumentForm.getRoleDocument().getDelegationMembers().remove(getLineToDelete(request));
477         roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember());
478         return mapping.findForward(RiceConstants.MAPPING_BASIC);
479     }
480 
481     /**
482      * @see org.kuali.rice.krad.web.struts.action.KualiTableRenderAction#switchToPage(org.apache.struts.action.ActionMapping,
483      *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
484      */
485     public ActionForward jumpToRoleMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
486         IdentityManagementRoleDocumentForm idmForm = (IdentityManagementRoleDocumentForm) form;
487         String delegationRoleMemberId = getDelegationRoleMemberToJumpTo(request);
488         KualiTableRenderFormMetadata memberTableMetadata = idmForm.getMemberTableMetadata();
489         memberTableMetadata.jumpToPage(idmForm.getPageNumberOfRoleMemberId(delegationRoleMemberId),
490                 idmForm.getMemberRows().size(), idmForm.getRecordsPerPage());
491         memberTableMetadata.setColumnToSortIndex(memberTableMetadata.getPreviouslySortedColumnIndex());
492         idmForm.setAnchor(delegationRoleMemberId);
493         return mapping.findForward(RiceConstants.MAPPING_BASIC);
494     }
495 
496     protected String getDelegationRoleMemberToJumpTo(HttpServletRequest request) {
497         String delegationRoleMemberIdToJumpTo = "";
498         String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
499         if (StringUtils.isNotBlank(parameterName)) {
500             delegationRoleMemberIdToJumpTo = StringUtils.substringBetween(parameterName, ".dmrmi", ".");
501         }
502         return delegationRoleMemberIdToJumpTo;
503     }
504 
505 
506     /**
507      * Side-effecting method returns an ActionForward if needed for handling prompting of the user about automatically
508      * "inactivating" active delegates of inactive role members.  If the user has already responded "Yes", delegates are
509      * "inactivated" here, and a null forward is returned.  Otherwise, an appropriate forward is returned.
510      *
511      * @param roleMembersToConsiderInactive additional role members to consider inactive for the purposes of this computation
512      */
513     private ActionForward promptForAffectedDelegates(ActionMapping mapping,
514                                                      ActionForm form, HttpServletRequest request,
515                                                      HttpServletResponse response,
516                                                      IdentityManagementRoleDocumentForm roleDocumentForm, KimDocumentRoleMember... roleMembersToConsiderInactive)
517             throws Exception {
518         // KULRICE-4762: Role: Removed an Assignee who has delegations associated with him and now the Role cannot be updated
519         // To solve this issue, prompt for confirmation if there are active delegates for the role member being "inactivated",
520         // and upon confirmation, "inactivate" the delegates too.
521         List<RoleDocumentDelegationMember> activeDelegatesOfInactiveRoleMembers =
522                 getActiveDelegatesOfInactiveRoleMembers(roleDocumentForm, roleMembersToConsiderInactive);
523         ActionForward forward = getAffectedDelegatesQuestionActionForward(activeDelegatesOfInactiveRoleMembers, mapping, form, request,
524                 response, roleDocumentForm);
525         // if the question logic gave us a forward, do it
526         if (forward != null) {
527             return forward;
528         }
529         // otherwise, inactivate affected delegates
530         if (activeDelegatesOfInactiveRoleMembers.size() > 0) {
531             Calendar cal = Calendar.getInstance();
532             // deactivate (inactivate?) delegates
533             for (RoleDocumentDelegationMember delegateToDeactivate : activeDelegatesOfInactiveRoleMembers) {
534                 delegateToDeactivate.setActiveToDate(new Timestamp(cal.getTimeInMillis()));
535             }
536         }
537         return null;
538     }
539 
540     /**
541      * <p>If there are active delegates of an "inactivated" role member, return an ActionForward to prompt the user
542      * letting them know that the delegates will be "inactivated" too if they proceed.
543      * <p>Also, if the user has already responded to the question and the response was (1) "Yes", then return null, signifying
544      * that we can go ahead and take the needed action to "inactivate" the delegates; or (2) "No", then return a basic forward that
545      * will cancel further action.
546      */
547     private ActionForward getAffectedDelegatesQuestionActionForward(List<RoleDocumentDelegationMember> activeDelegatesOfInactiveRoleMembers,
548                                                                     ActionMapping mapping, ActionForm form, HttpServletRequest request,
549                                                                     HttpServletResponse response,
550                                                                     IdentityManagementRoleDocumentForm roleDocumentForm)
551             throws Exception {
552 
553         if (activeDelegatesOfInactiveRoleMembers.size() > 0) {
554             Object question = getQuestion(request);
555             // logic for delegates question
556             if (question == null || !REMOVE_AFFECTED_DELEGATES_QUESTION_ID.equals(question)) {
557                 return performQuestionWithoutInput(mapping, form, request, response, REMOVE_AFFECTED_DELEGATES_QUESTION_ID,
558                         getKualiConfigurationService().getPropertyValueAsString(
559                                 RiceKeyConstants.QUESTION_ACTIVE_DELEGATES_FOR_INACTIVE_MEMBERS),
560                         KRADConstants.CONFIRMATION_QUESTION, roleDocumentForm.getMethodToCall(), StringUtils.EMPTY);
561             }
562             Object buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON);
563             if ((REMOVE_AFFECTED_DELEGATES_QUESTION_ID.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
564                 // the question was answered in the affirmative.
565                 // fall through, no special mapping to return
566             } else {
567                 // NO was clicked ... what to do?  Return basic mapping without "inactivating" anything
568                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
569             }
570         }
571 
572         return null;
573     }
574 
575     /**
576      * This method returns a list of all active delegates for role members that are inactive
577      *
578      * @param roleDocumentForm              form bean
579      * @param roleMembersToConsiderInactive additional role members to consider inactive for the purposes of this computation
580      * @return the active delegates of inactive role members
581      */
582     private List<RoleDocumentDelegationMember> getActiveDelegatesOfInactiveRoleMembers(
583             IdentityManagementRoleDocumentForm roleDocumentForm, KimDocumentRoleMember... roleMembersToConsiderInactive) {
584         List<KimDocumentRoleMember> roleMembers = roleDocumentForm.getMemberRows();
585         List<KimDocumentRoleMember> inactiveRoleMembers = new ArrayList<KimDocumentRoleMember>();
586         List<RoleDocumentDelegationMember> activeDelegatesOfInactivatedRoleMembers = new ArrayList<RoleDocumentDelegationMember>();
587 
588         inactiveRoleMembers.addAll(Arrays.asList(roleMembersToConsiderInactive));
589 
590         if (roleMembers != null) {
591             for (KimDocumentRoleMember roleMember : roleMembers) {
592                 if (roleMember != null) {
593                     if (!roleMember.isActive()) {
594                         inactiveRoleMembers.add(roleMember);
595                     }
596                 }
597             }
598         }
599 
600         for (KimDocumentRoleMember inactiveRoleMember : inactiveRoleMembers) {
601             // check if there are delegates for the member being removed
602             List<RoleDocumentDelegationMember> delegationMembers = roleDocumentForm.getRoleDocument().getDelegationMembers();
603             if (delegationMembers != null) {
604                 for (RoleDocumentDelegationMember delegationMember : delegationMembers) {
605                     if (delegationMember != null && delegationMember.isActive()) {
606                         // if the roleMember for this delegation is the same as the inactivatedRoleMember
607                         if (delegationMember.getRoleMemberId().equals(inactiveRoleMember.getRoleMemberId())) {
608                             activeDelegatesOfInactivatedRoleMembers.add(delegationMember);
609                         }
610                     }
611                 }
612             }
613         }
614         return activeDelegatesOfInactivatedRoleMembers;
615     }
616 
617     /**
618      * This method overrides validateRole() from IdentityManagementDocumentActionBase.
619      * The difference with this method is that it allows derived roles.
620      * The base implementation returns false if the role is a derived role.
621      *
622      */
623     @Override
624     protected boolean validateRole(String roleId, Role role, String propertyName, String message) {
625         if (role == null) {
626             GlobalVariables.getMessageMap().putError(propertyName, RiceKeyConstants.ERROR_INVALID_ROLE, roleId);
627             return false;
628         }
629         return true;
630     }
631 
632 
633 }