1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.actionrequest;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.kuali.rice.core.api.delegation.DelegationType;
22 import org.kuali.rice.core.api.exception.RiceRuntimeException;
23 import org.kuali.rice.core.api.membership.MemberType;
24 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
25 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
26 import org.kuali.rice.kew.api.WorkflowRuntimeException;
27 import org.kuali.rice.kew.api.action.ActionRequestPolicy;
28 import org.kuali.rice.kew.api.action.ActionRequestStatus;
29 import org.kuali.rice.kew.api.action.RecipientType;
30 import org.kuali.rice.kew.api.identity.Id;
31 import org.kuali.rice.kew.api.user.UserId;
32 import org.kuali.rice.kew.api.util.CodeTranslator;
33 import org.kuali.rice.kew.engine.RouteContext;
34 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
35 import org.kuali.rice.kew.identity.service.IdentityHelperService;
36 import org.kuali.rice.kew.role.KimRoleRecipient;
37 import org.kuali.rice.kew.role.KimRoleResponsibilityRecipient;
38 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
39 import org.kuali.rice.kew.rule.ResolvedQualifiedRole;
40 import org.kuali.rice.kew.service.KEWServiceLocator;
41 import org.kuali.rice.kew.user.RoleRecipient;
42 import org.kuali.rice.kew.api.KewApiConstants;
43 import org.kuali.rice.kew.util.Utilities;
44 import org.kuali.rice.kew.workgroup.GroupId;
45 import org.kuali.rice.kim.api.common.delegate.DelegateMember;
46 import org.kuali.rice.kim.api.common.delegate.DelegateType;
47 import org.kuali.rice.kim.api.group.Group;
48 import org.kuali.rice.kim.api.group.GroupService;
49 import org.kuali.rice.kim.api.identity.IdentityService;
50 import org.kuali.rice.kim.api.identity.principal.Principal;
51 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
52 import org.kuali.rice.kim.api.responsibility.ResponsibilityAction;
53 import org.kuali.rice.kim.api.role.Role;
54 import org.kuali.rice.kim.api.role.RoleMembership;
55 import org.kuali.rice.kim.api.role.RoleService;
56 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
57 import org.kuali.rice.krad.util.KRADConstants;
58 import org.kuali.rice.krad.util.ObjectUtils;
59
60 import java.sql.Timestamp;
61 import java.util.ArrayList;
62 import java.util.Collection;
63 import java.util.HashSet;
64 import java.util.Iterator;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.Set;
68
69
70
71
72
73
74
75 public class ActionRequestFactory {
76
77 private static final Logger LOG = Logger.getLogger(ActionRequestFactory.class);
78
79 private static RoleService roleService;
80 private static IdentityHelperService identityHelperService;
81 private static IdentityService identityService;
82 private static GroupService groupService;
83 private static ActionRequestService actionRequestService;
84
85 private DocumentRouteHeaderValue document;
86 private RouteNodeInstance routeNode;
87 private List<ActionRequestValue> requestGraphs = new ArrayList<ActionRequestValue>();
88
89 public ActionRequestFactory() {
90 }
91
92 public ActionRequestFactory(DocumentRouteHeaderValue document) {
93 this.document = document;
94 }
95
96 public ActionRequestFactory(DocumentRouteHeaderValue document, RouteNodeInstance routeNode) {
97 this.document = document;
98 this.routeNode = routeNode;
99 }
100
101 public ActionRequestFactory(RouteContext routeContext) {
102 this(routeContext.getDocument(), routeContext.getNodeInstance());
103 }
104
105
106
107
108
109
110
111
112
113
114
115 public ActionRequestValue createActionRequest(String actionRequested, Recipient recipient, String description, Boolean forceAction, String annotation) {
116 return createActionRequest(actionRequested, new Integer(0), recipient, description, KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, forceAction, annotation);
117 }
118
119 public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String annotation) {
120 return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, null, null, annotation);
121 }
122
123 public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId, String annotation) {
124 return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, annotation, null);
125 }
126
127 public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId, String annotation, String requestLabel) {
128 ActionRequestValue actionRequest = new ActionRequestValue();
129 actionRequest.setActionRequested(actionRequested);
130 actionRequest.setDocVersion(document.getDocVersion());
131 actionRequest.setPriority(priority);
132 actionRequest.setRouteHeader(document);
133 actionRequest.setDocumentId(document.getDocumentId());
134 actionRequest.setRouteLevel(document.getDocRouteLevel());
135 actionRequest.setNodeInstance(routeNode);
136 actionRequest.setResponsibilityId(responsibilityId);
137 actionRequest.setResponsibilityDesc(description);
138 actionRequest.setApprovePolicy(approvePolicy);
139 actionRequest.setForceAction(forceAction);
140 actionRequest.setRuleBaseValuesId(ruleId);
141 actionRequest.setAnnotation(annotation);
142 actionRequest.setRequestLabel(requestLabel);
143 setDefaultProperties(actionRequest);
144 resolveRecipient(actionRequest, recipient);
145
146 return actionRequest;
147 }
148
149 public ActionRequestValue createBlankActionRequest() {
150 ActionRequestValue request = new ActionRequestValue();
151 request.setRouteHeader(document);
152 if (document != null) {
153 request.setDocumentId(document.getDocumentId());
154 }
155 request.setNodeInstance(routeNode);
156 return request;
157 }
158
159
160 public ActionRequestValue createNotificationRequest(String actionRequestCode, PrincipalContract principal, String reasonActionCode, PrincipalContract reasonActionUser, String responsibilityDesc) {
161 ActionRequestValue request = createActionRequest(actionRequestCode, new KimPrincipalRecipient(principal), responsibilityDesc, Boolean.TRUE, null);
162 String annotation = generateNotificationAnnotation(reasonActionUser, actionRequestCode, reasonActionCode, request);
163 request.setAnnotation(annotation);
164 return request;
165 }
166
167
168 public List<ActionRequestValue> generateNotifications(List requests, PrincipalContract principal, Recipient delegator,
169 String notificationRequestCode, String actionTakenCode)
170 {
171 String groupName = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE,
172 KRADConstants.DetailTypes.WORKGROUP_DETAIL_TYPE,
173 KewApiConstants.NOTIFICATION_EXCLUDED_USERS_WORKGROUP_NAME_IND);
174
175
176 Group notifyExclusionWorkgroup = null;
177 if(!StringUtils.isBlank(groupName)){
178 notifyExclusionWorkgroup = getGroupService().getGroupByNamespaceCodeAndName(
179 Utilities.parseGroupNamespaceCode(groupName), Utilities.parseGroupName(groupName));
180 }
181
182
183
184 return generateNotifications(null, getActionRequestService().getRootRequests(requests), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup);
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199 private List<ActionRequestValue> generateNotifications(ActionRequestValue parentRequest,
200 List requests, PrincipalContract principal, Recipient delegator, String notificationRequestCode,
201 String actionTakenCode, Group notifyExclusionWorkgroup)
202 {
203 List<ActionRequestValue> notificationRequests = new ArrayList<ActionRequestValue>();
204 for (Iterator iter = requests.iterator(); iter.hasNext();)
205 {
206 ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
207 if (!(actionRequest.isRecipientRoutedRequest(principal.getPrincipalId()) || actionRequest.isRecipientRoutedRequest(delegator)))
208 {
209
210 if ((notifyExclusionWorkgroup != null) &&
211 (isRecipientInGroup(notifyExclusionWorkgroup, actionRequest.getRecipient())))
212 {
213 continue;
214 }
215 ActionRequestValue notificationRequest = createNotificationRequest(actionRequest, principal, notificationRequestCode, actionTakenCode);
216 notificationRequests.add(notificationRequest);
217 if (parentRequest != null)
218 {
219 notificationRequest.setParentActionRequest(parentRequest);
220 parentRequest.getChildrenRequests().add(notificationRequest);
221 }
222 notificationRequests.addAll(generateNotifications(notificationRequest, actionRequest.getChildrenRequests(), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup));
223 }
224 }
225 return notificationRequests;
226 }
227
228 private boolean isRecipientInGroup(Group group, Recipient recipient)
229 {
230 boolean isMember = false;
231
232 if(recipient instanceof KimPrincipalRecipient)
233 {
234 String principalId = ((KimPrincipalRecipient) recipient).getPrincipalId();
235 String groupId = group.getId();
236 isMember = getGroupService().isMemberOfGroup(principalId, groupId);
237 }
238 else if (recipient instanceof KimGroupRecipient)
239 {
240 String kimRecipientId = ((KimGroupRecipient) recipient).getGroup().getId();
241 isMember = getGroupService().isGroupMemberOfGroup(kimRecipientId, group.getId() );
242 }
243 return isMember;
244 }
245
246 private ActionRequestValue createNotificationRequest(ActionRequestValue actionRequest, PrincipalContract reasonPrincipal, String notificationRequestCode, String actionTakenCode) {
247
248 String annotation = generateNotificationAnnotation(reasonPrincipal, notificationRequestCode, actionTakenCode, actionRequest);
249 ActionRequestValue request = createActionRequest(notificationRequestCode, actionRequest.getPriority(), actionRequest.getRecipient(), actionRequest.getResponsibilityDesc(), KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, Boolean.TRUE, annotation);
250
251 request.setDocVersion(actionRequest.getDocVersion());
252 request.setApprovePolicy(actionRequest.getApprovePolicy());
253 request.setRoleName(actionRequest.getRoleName());
254 request.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
255 request.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
256 request.setDelegationType(actionRequest.getDelegationType());
257 return request;
258 }
259
260 private void setDefaultProperties(ActionRequestValue actionRequest) {
261 if (actionRequest.getApprovePolicy() == null) {
262 actionRequest.setApprovePolicy(ActionRequestPolicy.FIRST.getCode());
263 }
264 actionRequest.setCreateDate(new Timestamp(System.currentTimeMillis()));
265 actionRequest.setCurrentIndicator(Boolean.TRUE);
266 if (actionRequest.getForceAction() == null) {
267 actionRequest.setForceAction(Boolean.FALSE);
268 }
269 if (routeNode != null) {
270 actionRequest.setNodeInstance(routeNode);
271 }
272 actionRequest.setJrfVerNbr(new Integer(0));
273 actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode());
274 actionRequest.setRouteHeader(document);
275 actionRequest.setDocumentId(document.getDocumentId());
276 }
277
278 private static void resolveRecipient(ActionRequestValue actionRequest, Recipient recipient) {
279 if (recipient instanceof KimPrincipalRecipient) {
280 actionRequest.setRecipientTypeCd(RecipientType.PRINCIPAL.getCode());
281 actionRequest.setPrincipalId(((KimPrincipalRecipient)recipient).getPrincipal().getPrincipalId());
282 } else if (recipient instanceof KimGroupRecipient) {
283 KimGroupRecipient kimGroupRecipient = (KimGroupRecipient)recipient;
284 actionRequest.setRecipientTypeCd(RecipientType.GROUP.getCode());
285 actionRequest.setGroupId(kimGroupRecipient.getGroup().getId());
286 } else if (recipient instanceof RoleRecipient){
287 RoleRecipient role = (RoleRecipient)recipient;
288 actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode());
289 actionRequest.setRoleName(role.getRoleName());
290 actionRequest.setQualifiedRoleName(role.getQualifiedRoleName());
291 ResolvedQualifiedRole qualifiedRole = role.getResolvedQualifiedRole();
292 if (qualifiedRole != null) {
293 actionRequest.setAnnotation(qualifiedRole.getAnnotation() == null ? "" : qualifiedRole.getAnnotation());
294 actionRequest.setQualifiedRoleNameLabel(qualifiedRole.getQualifiedRoleLabel());
295 }
296 Recipient targetRecipient = role.getTarget();
297 if (role.getTarget() != null) {
298 if (targetRecipient instanceof RoleRecipient) {
299 throw new WorkflowRuntimeException("Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId());
300 }
301 resolveRecipient(actionRequest, role.getTarget());
302 }
303 } else if (recipient instanceof KimRoleResponsibilityRecipient) {
304 KimRoleResponsibilityRecipient roleResponsibilityRecipient = (KimRoleResponsibilityRecipient)recipient;
305 actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode());
306 actionRequest.setRoleName(roleResponsibilityRecipient.getResponsibilities().get(0).getRoleId());
307 actionRequest.setQualifiedRoleName(
308 roleResponsibilityRecipient.getResponsibilities().get(0).getResponsibilityName());
309
310
311 Recipient targetRecipient = roleResponsibilityRecipient.getTarget();
312 if (targetRecipient != null) {
313 if (targetRecipient instanceof RoleRecipient) {
314 throw new WorkflowRuntimeException("Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId());
315 }
316 resolveRecipient(actionRequest, roleResponsibilityRecipient.getTarget());
317 }
318 } else if (recipient instanceof KimRoleRecipient) {
319 KimRoleRecipient roleRecipient = (KimRoleRecipient)recipient;
320 actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode());
321 Role role = roleRecipient.getRole();
322 actionRequest.setRoleName(role.getId());
323 actionRequest.setQualifiedRoleNameLabel(role.getName());
324 Recipient targetRecipient = roleRecipient.getTarget();
325 if (targetRecipient != null) {
326 if (targetRecipient instanceof RoleRecipient) {
327 throw new WorkflowRuntimeException("Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId());
328 }
329 resolveRecipient(actionRequest, targetRecipient);
330 }
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346 public ActionRequestValue addRoleRequest(RoleRecipient role, String actionRequested, String approvePolicy, Integer priority, String responsibilityId, Boolean forceAction, String description, String ruleId) {
347
348 ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
349 if (role != null && role.getResolvedQualifiedRole() != null && role.getResolvedQualifiedRole().getRecipients() != null) {
350 int legitimateTargets = 0;
351 for (Iterator<Id> iter = role.getResolvedQualifiedRole().getRecipients().iterator(); iter.hasNext();) {
352 Id recipientId = (Id) iter.next();
353 if (recipientId.isEmpty())
354 {
355 throw new WorkflowRuntimeException("Failed to resolve id of type " + recipientId.getClass().getName() + " returned from role '" + role.getRoleName() + "'. Id returned contained a null or empty value.");
356 }
357 if (recipientId instanceof UserId)
358 {
359 Principal principal = getIdentityHelperService().getPrincipal((UserId) recipientId);
360 if(ObjectUtils.isNotNull(principal)) {
361 role.setTarget(new KimPrincipalRecipient(principal));
362 }
363 } else if (recipientId instanceof GroupId)
364 {
365 role.setTarget(new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId)));
366 } else
367 {
368 throw new WorkflowRuntimeException("Could not process the given type of id: " + recipientId.getClass());
369 }
370 if (role.getTarget() != null)
371 {
372 legitimateTargets++;
373 ActionRequestValue request = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, null, ruleId, null);
374 request.setParentActionRequest(requestGraph);
375 requestGraph.getChildrenRequests().add(request);
376 }
377 }
378 if (legitimateTargets == 0) {
379 LOG.warn("Role did not yield any legitimate recipients");
380 }
381 } else {
382 LOG.warn("Didn't create action requests for action request description '" + description + "' because of null role or null part of role object graph.");
383 }
384 requestGraphs.add(requestGraph);
385 return requestGraph;
386 }
387
388
389
390
391
392
393 public void addRoleResponsibilityRequest(List<ResponsibilityAction> responsibilities, String approvePolicy) {
394 if (responsibilities == null || responsibilities.isEmpty()) {
395 LOG.warn("Didn't create action requests for action request description because no responsibilities were defined.");
396 return;
397 }
398
399 String actionTypeCode = responsibilities.get(0).getActionTypeCode();
400 Integer priority = responsibilities.get(0).getPriorityNumber();
401 boolean forceAction = responsibilities.get(0).isForceAction();
402 KimRoleResponsibilityRecipient roleResponsibilityRecipient = new KimRoleResponsibilityRecipient(responsibilities);
403
404
405 ActionRequestValue requestGraph = null;
406 StringBuffer parentAnnotation = null;
407
408 Set<String> uniqueChildAnnotations = null;
409 if ( responsibilities.size() > 1 ) {
410 requestGraph = createActionRequest(
411 actionTypeCode,
412 priority, roleResponsibilityRecipient,
413 "",
414 KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID,
415 forceAction,
416 approvePolicy,
417 null,
418 null );
419 requestGraphs.add(requestGraph);
420 parentAnnotation = new StringBuffer();
421 uniqueChildAnnotations = new HashSet<String>( responsibilities.size() );
422 }
423 StringBuffer annotation = new StringBuffer();
424 for (ResponsibilityAction responsibility : responsibilities) {
425 if ( LOG.isDebugEnabled() ) {
426 LOG.debug( "Processing Responsibility for action request: " + responsibility );
427 }
428
429 annotation.setLength( 0 );
430 Role role = getRoleService().getRole(responsibility.getRoleId());
431 annotation.append( role.getNamespaceCode() ).append( ' ' ).append( role.getName() ).append( ' ' );
432 Map<String, String> qualifier = responsibility.getQualifier();
433 if ( qualifier != null ) {
434 for ( String key : qualifier.keySet() ) {
435 annotation.append( qualifier.get( key ) ).append( ' ' );
436 }
437 }
438 if (responsibility.getPrincipalId() != null) {
439 roleResponsibilityRecipient.setTarget(new KimPrincipalRecipient(responsibility.getPrincipalId()));
440 } else if (responsibility.getGroupId() != null) {
441 roleResponsibilityRecipient.setTarget(new KimGroupRecipient(responsibility.getGroupId()));
442 } else {
443 throw new RiceRuntimeException("Failed to identify a group or principal on the given ResponsibilityResolutionInfo:" + responsibility);
444 }
445 String annotationStr = annotation.toString();
446 ActionRequestValue request = createActionRequest(
447 responsibility.getActionTypeCode(),
448 responsibility.getPriorityNumber(), roleResponsibilityRecipient,
449 responsibility.getParallelRoutingGroupingCode(),
450 responsibility.getResponsibilityId(),
451 responsibility.isForceAction(),
452
453
454
455 (responsibilities.size() == 1)?ActionRequestPolicy.FIRST.getCode():approvePolicy,
456 null,
457 annotationStr);
458
459 if ( responsibilities.size() > 1 ) {
460 request.setParentActionRequest(requestGraph);
461 requestGraph.getChildrenRequests().add(request);
462 if ( !uniqueChildAnnotations.contains(annotationStr) ) {
463 parentAnnotation.append( annotationStr ).append( " -- " );
464 uniqueChildAnnotations.add(annotationStr);
465 }
466 } else {
467 requestGraphs.add(request);
468 }
469 generateKimRoleDelegationRequests(responsibility.getDelegates(), request);
470
471 }
472 if ( responsibilities.size() > 1 ) {
473 requestGraph.setAnnotation( StringUtils.chomp( parentAnnotation.toString(), " -- " ) );
474 }
475 }
476
477 private String generateRoleResponsibilityDelegateAnnotation(DelegateMember member, boolean isPrincipal, boolean isGroup, ActionRequestValue parentRequest) {
478 StringBuffer annotation = new StringBuffer( "Delegation of: " );
479 annotation.append( parentRequest.getAnnotation() );
480 annotation.append( " to " );
481 if (isPrincipal) {
482 annotation.append( "principal " );
483 Principal principal = getIdentityService().getPrincipal(member.getMemberId());
484 if ( principal != null ) {
485 annotation.append( principal.getPrincipalName() );
486 } else {
487 annotation.append( member.getMemberId() );
488 }
489 } else if (isGroup) {
490 annotation.append( "group " );
491 Group group = getGroupService().getGroup( member.getMemberId() );
492 if ( group != null ) {
493 annotation.append( group.getNamespaceCode() ).append( '/' ).append( group.getName() );
494 } else {
495 annotation.append( member.getMemberId() );
496 }
497 } else {
498 annotation.append( "?????? '" );
499 annotation.append( member.getMemberId() );
500 annotation.append( "'" );
501 }
502 return annotation.toString();
503 }
504
505 public ActionRequestValue addDelegationRoleRequest(ActionRequestValue parentRequest, String approvePolicy, RoleRecipient role, String responsibilityId, Boolean forceAction, DelegationType delegationType, String description, String ruleId) {
506 Recipient parentRecipient = parentRequest.getRecipient();
507 if (parentRecipient instanceof RoleRecipient) {
508 throw new WorkflowRuntimeException("Cannot delegate on Role Request. It must be a request to a person or workgroup, although that request may be in a role");
509 }
510 if (! relatedToRoot(parentRequest)) {
511 throw new WorkflowRuntimeException("The parent request is not related to any request managed by this factory");
512 }
513 ActionRequestValue delegationRoleRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
514 delegationRoleRequest.setDelegationType(delegationType);
515 int count = 0;
516 for (Iterator<Id> iter = role.getResolvedQualifiedRole().getRecipients().iterator(); iter.hasNext(); count++) {
517
518 Id recipientId = iter.next();
519 if (recipientId.isEmpty()) {
520 throw new WorkflowRuntimeException("Failed to resolve id of type " + recipientId.getClass().getName() + " returned from role '" + role.getRoleName() + "'. Id returned contained a null or empty value.");
521 }
522 if (recipientId instanceof UserId) {
523 role.setTarget(new KimPrincipalRecipient(getIdentityHelperService().getPrincipal((UserId) recipientId)));
524 } else if (recipientId instanceof GroupId) {
525 role.setTarget(new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId)));
526 } else {
527 throw new WorkflowRuntimeException("Could not process the given type of id: " + recipientId.getClass());
528 }
529 ActionRequestValue request = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, null, ruleId, null);
530 request.setDelegationType(delegationType);
531
532 request.setParentActionRequest(delegationRoleRequest);
533 delegationRoleRequest.getChildrenRequests().add(request);
534 }
535
536
537 if (count > 0) {
538 parentRequest.getChildrenRequests().add(delegationRoleRequest);
539 delegationRoleRequest.setParentActionRequest(parentRequest);
540 }
541
542 return delegationRoleRequest;
543 }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 public ActionRequestValue addDelegationRequest(ActionRequestValue parentRequest, Recipient recipient, String responsibilityId, Boolean forceAction, DelegationType delegationType, String actionRequestPolicyCode, String annotation, String ruleId) {
559 if (! relatedToRoot(parentRequest)) {
560 throw new WorkflowRuntimeException("The parent request is not related to any request managed by this factory");
561 }
562 ActionRequestValue delegationRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), recipient, parentRequest.getResponsibilityDesc(), responsibilityId, forceAction, actionRequestPolicyCode, ruleId, annotation);
563 delegationRequest.setDelegationType(delegationType);
564
565 parentRequest.getChildrenRequests().add(delegationRequest);
566 delegationRequest.setParentActionRequest(parentRequest);
567
568 return delegationRequest;
569 }
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585 public ActionRequestValue addDelegationRequest(ActionRequestValue parentRequest, Recipient recipient, String responsibilityId, Boolean forceAction, DelegationType delegationType, String annotation, String ruleId) {
586 return addDelegationRequest(parentRequest, recipient, responsibilityId, forceAction, delegationType, null, annotation, ruleId);
587 }
588
589
590 public ActionRequestValue addRootActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId) {
591 ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
592 requestGraphs.add(requestGraph);
593 return requestGraph;
594 }
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610 public ActionRequestValue addKimRoleRequest(String actionRequestedCode, Integer priority, Role role,
611 List<RoleMembership> memberships, String description, String responsibilityId, boolean forceAction,
612 String actionRequestPolicyCode, String requestLabel) {
613 return addKimRoleRequest(actionRequestedCode, priority, role, memberships, description, responsibilityId,
614 forceAction, actionRequestPolicyCode, requestLabel, false);
615 }
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 public ActionRequestValue addKimRoleRequest(String actionRequestedCode, Integer priority, Role role,
632 List<RoleMembership> memberships, String description, String responsibilityId, boolean forceAction,
633 String actionRequestPolicyCode, String requestLabel, boolean ignoreKimDelegates) {
634
635 ActionRequestValue roleMemberRequest = null;
636
637 if (CollectionUtils.isEmpty(memberships)) {
638 LOG.warn("Didn't create action requests for action request description because no role members were defined for role id " + role.getId());
639 return roleMemberRequest;
640 }
641
642 KimRoleRecipient roleRecipient = new KimRoleRecipient(role);
643
644
645 ActionRequestValue requestGraph = null;
646 if ( memberships.size() > 1 ) {
647 requestGraph = createActionRequest(
648 actionRequestedCode,
649 priority,
650 roleRecipient,
651 "",
652 responsibilityId,
653 forceAction,
654 actionRequestPolicyCode,
655 null,
656 null );
657 requestGraphs.add(requestGraph);
658 }
659
660 for (RoleMembership membership : memberships) {
661 if ( LOG.isDebugEnabled() ) {
662 LOG.debug( "Processing RoleMembership for action request: " + membership );
663 }
664
665 if (MemberType.PRINCIPAL.equals(membership.getType())) {
666 roleRecipient.setTarget(new KimPrincipalRecipient(membership.getMemberId()));
667 } else if (MemberType.GROUP.equals(membership.getType())) {
668 roleRecipient.setTarget(new KimGroupRecipient(membership.getMemberId()));
669 } else {
670 throw new RiceRuntimeException("Failed to identify a group or principal on the given RoleMembership:" + membership);
671 }
672
673 ActionRequestValue request = createActionRequest(
674 actionRequestedCode,
675 priority,
676 roleRecipient,
677 "",
678 responsibilityId,
679 forceAction,
680
681
682
683 (memberships.size() == 1) ? ActionRequestPolicy.FIRST.getCode() : actionRequestPolicyCode,
684 null,
685 null);
686
687
688 if ( memberships.size() > 1 ) {
689 request.setParentActionRequest(requestGraph);
690 requestGraph.getChildrenRequests().add(request);
691
692 if (roleMemberRequest == null) {
693 roleMemberRequest = requestGraph;
694 }
695 } else {
696 roleMemberRequest = request;
697 requestGraphs.add(request);
698 }
699
700 if (!ignoreKimDelegates) {
701 generateKimRoleDelegationRequests(membership.getDelegates(), request);
702 }
703 }
704
705 return roleMemberRequest;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726 public ActionRequestValue addDelegateKimRoleRequest(ActionRequestValue parentRequest, DelegationType delegationType,
727 String actionRequestedCode, Integer priority, Role role, List<RoleMembership> memberships,
728 String description, String responsibilityId, boolean forceAction, String actionRequestPolicyCode,
729 String requestLabel) {
730
731
732
733
734 ActionRequestValue delegateRoleRequest = null;
735
736 if (CollectionUtils.isEmpty(memberships)) {
737 LOG.warn("Didn't create action requests for action request description because no role members were defined for role id " + role.getId());
738 return delegateRoleRequest;
739 }
740
741 KimRoleRecipient roleRecipient = new KimRoleRecipient(role);
742
743
744 ActionRequestValue requestGraph = null;
745 if ( memberships.size() > 1 ) {
746 requestGraph = createActionRequest(
747 actionRequestedCode,
748 priority,
749 roleRecipient,
750 "",
751 responsibilityId,
752 forceAction,
753 actionRequestPolicyCode,
754 null,
755 null );
756 requestGraphs.add(requestGraph);
757 }
758
759 for (RoleMembership membership : memberships) {
760 if ( LOG.isDebugEnabled() ) {
761 LOG.debug( "Processing RoleMembership for action request: " + membership );
762 }
763
764 if (MemberType.PRINCIPAL.equals(membership.getType())) {
765 roleRecipient.setTarget(new KimPrincipalRecipient(membership.getMemberId()));
766 } else if (MemberType.GROUP.equals(membership.getType())) {
767 roleRecipient.setTarget(new KimGroupRecipient(membership.getMemberId()));
768 } else {
769 throw new RiceRuntimeException("Failed to identify a group or principal on the given RoleMembership:" + membership);
770 }
771
772 ActionRequestValue request = createActionRequest(
773 actionRequestedCode,
774 priority,
775 roleRecipient,
776 "",
777 responsibilityId,
778 forceAction,
779
780
781
782 (memberships.size() == 1) ? ActionRequestPolicy.FIRST.getCode() : actionRequestPolicyCode,
783 null,
784 null);
785
786
787 if ( memberships.size() > 1 ) {
788 request.setParentActionRequest(requestGraph);
789 requestGraph.getChildrenRequests().add(request);
790
791 if (delegateRoleRequest == null) {
792 delegateRoleRequest = requestGraph;
793 }
794 } else {
795 delegateRoleRequest = request;
796 }
797 }
798
799 delegateRoleRequest.setDelegationType(delegationType);
800 delegateRoleRequest.setParentActionRequest(parentRequest);
801 parentRequest.getChildrenRequests().add(delegateRoleRequest);
802
803 return delegateRoleRequest;
804 }
805
806 private void generateKimRoleDelegationRequests(List<DelegateType> delegates, ActionRequestValue parentRequest) {
807 for (DelegateType delegate : delegates) {
808 for (DelegateMember member : delegate.getMembers()) {
809 Recipient recipient;
810 boolean isPrincipal = MemberType.PRINCIPAL.equals(member.getType());
811 boolean isGroup = MemberType.GROUP.equals(member.getType());
812 if (isPrincipal) {
813 recipient = new KimPrincipalRecipient(member.getMemberId());
814 } else if (isGroup) {
815 recipient = new KimGroupRecipient(member.getMemberId());
816 } else {
817 throw new RiceRuntimeException("Invalid DelegateInfo memberTypeCode encountered, was '" + member.getType() + "'");
818 }
819 String delegationAnnotation = generateRoleResponsibilityDelegateAnnotation(member, isPrincipal, isGroup, parentRequest);
820 addDelegationRequest(parentRequest, recipient, delegate.getDelegationId(), parentRequest.getForceAction(), delegate.getDelegationType(), delegationAnnotation, null);
821 }
822 }
823 }
824
825
826 public boolean relatedToRoot(ActionRequestValue request) {
827 int i = 0;
828 while(i < 3) {
829 if (requestGraphs.contains(request)) {
830 return true;
831 } else if (request == null) {
832 return false;
833 }
834 i++;
835 request = request.getParentActionRequest();
836 }
837 return false;
838 }
839
840 public List<ActionRequestValue> getRequestGraphs() {
841
842 requestGraphs.removeAll(cleanUpChildren(requestGraphs));
843 return requestGraphs;
844 }
845
846 private Collection<ActionRequestValue> cleanUpChildren(Collection<ActionRequestValue> children) {
847 Collection<ActionRequestValue> requestsToRemove = new ArrayList<ActionRequestValue>();
848 for (ActionRequestValue aChildren : children)
849 {
850
851 if (aChildren.isRoleRequest())
852 {
853 if (aChildren.getChildrenRequests().isEmpty())
854 {
855 requestsToRemove.add(aChildren);
856 } else
857 {
858 Collection<ActionRequestValue> childRequestsToRemove = cleanUpChildren(aChildren.getChildrenRequests());
859 aChildren.getChildrenRequests().removeAll(childRequestsToRemove);
860 }
861 }
862 }
863 return requestsToRemove;
864 }
865
866 private String generateNotificationAnnotation(PrincipalContract principal, String notificationRequestCode, String actionTakenCode, ActionRequestValue request) {
867 String notification = "Action " + CodeTranslator.getActionRequestLabel(notificationRequestCode) + " generated by Workflow because " + principal.getPrincipalName() + " took action "
868 + CodeTranslator.getActionTakenLabel(actionTakenCode);
869
870
871
872 if (request.getResponsibilityId() != null && !KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(request.getResponsibilityId())) {
873 notification += " Responsibility " + request.getResponsibilityId();
874 }
875 if (request.getRuleBaseValuesId() != null) {
876 notification += " Rule Id " + request.getRuleBaseValuesId();
877 }
878 if (request.getAnnotation() != null && request.getAnnotation().length()!=0){
879 notification += " " + request.getAnnotation();
880 }
881 return notification;
882 }
883
884 protected static ActionRequestService getActionRequestService() {
885 if ( actionRequestService == null ) {
886 actionRequestService = KEWServiceLocator.getActionRequestService();
887 }
888 return actionRequestService;
889 }
890
891
892
893
894 protected static RoleService getRoleService() {
895 if ( roleService == null ) {
896 roleService = KimApiServiceLocator.getRoleService();
897 }
898 return roleService;
899 }
900
901
902
903
904 protected static IdentityHelperService getIdentityHelperService() {
905 if ( identityHelperService == null ) {
906 identityHelperService = KEWServiceLocator.getIdentityHelperService();
907 }
908 return identityHelperService;
909 }
910
911
912
913
914 protected static IdentityService getIdentityService() {
915 if ( identityService == null ) {
916 identityService = KimApiServiceLocator.getIdentityService();
917 }
918 return identityService;
919 }
920
921 protected static GroupService getGroupService() {
922 if ( groupService == null ) {
923 groupService = KimApiServiceLocator.getGroupService();
924 }
925 return groupService;
926 }
927 }