Java tutorial
/** * Copyright 2005-2014 The Kuali Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ecl2.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kuali.rice.kew.actionrequest; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.kuali.rice.core.api.delegation.DelegationType; import org.kuali.rice.core.api.exception.RiceRuntimeException; import org.kuali.rice.core.api.membership.MemberType; import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; import org.kuali.rice.kew.actionrequest.service.ActionRequestService; import org.kuali.rice.kew.api.KewApiConstants; import org.kuali.rice.kew.api.WorkflowRuntimeException; import org.kuali.rice.kew.api.action.ActionRequestPolicy; import org.kuali.rice.kew.api.action.ActionRequestStatus; import org.kuali.rice.kew.api.action.RecipientType; import org.kuali.rice.kew.api.identity.Id; import org.kuali.rice.kew.api.user.UserId; import org.kuali.rice.kew.api.util.CodeTranslator; import org.kuali.rice.kew.engine.RouteContext; import org.kuali.rice.kew.engine.node.RouteNodeInstance; import org.kuali.rice.kew.identity.service.IdentityHelperService; import org.kuali.rice.kew.role.KimRoleRecipient; import org.kuali.rice.kew.role.KimRoleResponsibilityRecipient; import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; import org.kuali.rice.kew.rule.ResolvedQualifiedRole; import org.kuali.rice.kew.service.KEWServiceLocator; import org.kuali.rice.kew.user.RoleRecipient; import org.kuali.rice.kew.util.Utilities; import org.kuali.rice.kew.workgroup.GroupId; import org.kuali.rice.kim.api.common.delegate.DelegateMember; import org.kuali.rice.kim.api.common.delegate.DelegateType; import org.kuali.rice.kim.api.group.Group; import org.kuali.rice.kim.api.group.GroupService; import org.kuali.rice.kim.api.identity.IdentityService; import org.kuali.rice.kim.api.identity.principal.Principal; import org.kuali.rice.kim.api.identity.principal.PrincipalContract; import org.kuali.rice.kim.api.responsibility.ResponsibilityAction; import org.kuali.rice.kim.api.role.Role; import org.kuali.rice.kim.api.role.RoleMembership; import org.kuali.rice.kim.api.role.RoleService; import org.kuali.rice.kim.api.services.KimApiServiceLocator; import org.kuali.rice.krad.util.KRADConstants; import org.kuali.rice.krad.util.KRADUtils; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * A factory to aid in creating the ever-so-gnarly ActionRequestValue object. * * @author Kuali Rice Team (rice.collab@kuali.org) */ public class ActionRequestFactory { private static final Logger LOG = Logger.getLogger(ActionRequestFactory.class); private static RoleService roleService; private static IdentityHelperService identityHelperService; private static IdentityService identityService; private static GroupService groupService; private static ActionRequestService actionRequestService; private DocumentRouteHeaderValue document; private RouteNodeInstance routeNode; private List<ActionRequestValue> requestGraphs = new ArrayList<ActionRequestValue>(); public ActionRequestFactory() { } public ActionRequestFactory(DocumentRouteHeaderValue document) { this.document = document; } public ActionRequestFactory(DocumentRouteHeaderValue document, RouteNodeInstance routeNode) { this.document = document; this.routeNode = routeNode; } public ActionRequestFactory(RouteContext routeContext) { this(routeContext.getDocument(), routeContext.getNodeInstance()); } /** * Constructs ActionRequestValue using default priority and 0 as responsibility * * @param actionRequested * @param recipient * @param description * @param forceAction * @param annotation * @return ActionRequestValue */ public ActionRequestValue createActionRequest(String actionRequested, Recipient recipient, String description, Boolean forceAction, String annotation) { return createActionRequest(actionRequested, new Integer(0), recipient, description, KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, forceAction, annotation); } public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String annotation) { return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, null, null, annotation); } public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId, String annotation) { return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, annotation, null); } public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId, String annotation, String requestLabel) { ActionRequestValue actionRequest = new ActionRequestValue(); actionRequest.setActionRequested(actionRequested); actionRequest.setDocVersion(document.getDocVersion()); actionRequest.setPriority(priority); actionRequest.setRouteHeader(document); actionRequest.setDocumentId(document.getDocumentId()); actionRequest.setRouteLevel(document.getDocRouteLevel()); actionRequest.setNodeInstance(routeNode); actionRequest.setResponsibilityId(responsibilityId); actionRequest.setResponsibilityDesc(description); actionRequest.setApprovePolicy(approvePolicy); actionRequest.setForceAction(forceAction); actionRequest.setRuleBaseValuesId(ruleId); actionRequest.setAnnotation(annotation); actionRequest.setRequestLabel(requestLabel); setDefaultProperties(actionRequest); resolveRecipient(actionRequest, recipient); return actionRequest; } public ActionRequestValue createBlankActionRequest() { ActionRequestValue request = new ActionRequestValue(); request.setRouteHeader(document); if (document != null) { request.setDocumentId(document.getDocumentId()); } request.setNodeInstance(routeNode); return request; } public ActionRequestValue createNotificationRequest(String actionRequestCode, PrincipalContract principal, String reasonActionCode, PrincipalContract reasonActionUser, String responsibilityDesc) { ActionRequestValue request = createActionRequest(actionRequestCode, new KimPrincipalRecipient(principal), responsibilityDesc, Boolean.TRUE, null); String annotation = generateNotificationAnnotation(reasonActionUser, actionRequestCode, reasonActionCode, request); request.setAnnotation(annotation); return request; } //unify these 2 methods if possible public List<ActionRequestValue> generateNotifications(List requests, PrincipalContract principal, Recipient delegator, String notificationRequestCode, String actionTakenCode) { String groupName = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString( KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.WORKGROUP_DETAIL_TYPE, KewApiConstants.NOTIFICATION_EXCLUDED_USERS_WORKGROUP_NAME_IND); Group notifyExclusionWorkgroup = null; if (!StringUtils.isBlank(groupName)) { notifyExclusionWorkgroup = getGroupService().getGroupByNamespaceCodeAndName( Utilities.parseGroupNamespaceCode(groupName), Utilities.parseGroupName(groupName)); } return generateNotifications(null, getActionRequestService().getRootRequests(requests), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup); } /** * Generates a notification request for each action request specified, filtering out the specified principal * and delegator, and exclusion workgroup members from notification list. This method only returns requests that are * "root" requests. * * @param parentRequest if non-null, attaches generated notification requests to this parent action request * @param requests list of ActionRequestValues for which to generate corresponding notification requests * @param principal principal to exclude from notifications * @param delegator delegator to exclude from notifications * @param notificationRequestCode the actionrequest code of generated notifications * @param actionTakenCode the actiontaken code to display as the cause of the notification generation * @param notifyExclusionWorkgroup workgroup whose members should not be sent notifications * @return a list of generated notification requests */ private List<ActionRequestValue> generateNotifications(ActionRequestValue parentRequest, List<ActionRequestValue> requests, PrincipalContract principal, Recipient delegator, String notificationRequestCode, String actionTakenCode, Group notifyExclusionWorkgroup) { List<ActionRequestValue> notificationRequests = new ArrayList<ActionRequestValue>(); for (ActionRequestValue actionRequest : requests) { if (!(actionRequest.isRecipientRoutedRequest(principal.getPrincipalId()) || actionRequest.isRecipientRoutedRequest(delegator))) { // skip user requests to system users if ((notifyExclusionWorkgroup != null) && (isRecipientInGroup(notifyExclusionWorkgroup, actionRequest.getRecipient()))) { continue; } ActionRequestValue notificationRequest = createNotificationRequest(actionRequest, principal, notificationRequestCode, actionTakenCode); if (parentRequest == null) { // we'll only add the request to the returned list if it's a root request since we always save from // the root request and cascade down notificationRequests.add(notificationRequest); } else { notificationRequest.setParentActionRequest(parentRequest); parentRequest.getChildrenRequests().add(notificationRequest); } generateNotifications(notificationRequest, actionRequest.getChildrenRequests(), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup); } } return notificationRequests; } private boolean isRecipientInGroup(Group group, Recipient recipient) { boolean isMember = false; if (recipient instanceof KimPrincipalRecipient) { String principalId = ((KimPrincipalRecipient) recipient).getPrincipalId(); String groupId = group.getId(); isMember = getGroupService().isMemberOfGroup(principalId, groupId); } else if (recipient instanceof KimGroupRecipient) { String kimRecipientId = ((KimGroupRecipient) recipient).getGroup().getId(); isMember = getGroupService().isGroupMemberOfGroup(kimRecipientId, group.getId()); } return isMember; } private ActionRequestValue createNotificationRequest(ActionRequestValue actionRequest, PrincipalContract reasonPrincipal, String notificationRequestCode, String actionTakenCode) { String annotation = generateNotificationAnnotation(reasonPrincipal, notificationRequestCode, actionTakenCode, actionRequest); ActionRequestValue request = createActionRequest(notificationRequestCode, actionRequest.getPriority(), actionRequest.getRecipient(), actionRequest.getResponsibilityDesc(), KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, Boolean.TRUE, annotation); request.setDocVersion(actionRequest.getDocVersion()); request.setApprovePolicy(actionRequest.getApprovePolicy()); request.setRoleName(actionRequest.getRoleName()); request.setQualifiedRoleName(actionRequest.getQualifiedRoleName()); request.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel()); request.setDelegationType(actionRequest.getDelegationType()); return request; } private void setDefaultProperties(ActionRequestValue actionRequest) { if (actionRequest.getApprovePolicy() == null) { actionRequest.setApprovePolicy(ActionRequestPolicy.FIRST.getCode()); } actionRequest.setCreateDate(new Timestamp(System.currentTimeMillis())); actionRequest.setCurrentIndicator(Boolean.TRUE); if (actionRequest.getForceAction() == null) { actionRequest.setForceAction(Boolean.FALSE); } if (routeNode != null) { actionRequest.setNodeInstance(routeNode); } actionRequest.setJrfVerNbr(new Integer(0)); actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode()); actionRequest.setRouteHeader(document); actionRequest.setDocumentId(document.getDocumentId()); } private static void resolveRecipient(ActionRequestValue actionRequest, Recipient recipient) { if (recipient instanceof KimPrincipalRecipient) { actionRequest.setRecipientTypeCd(RecipientType.PRINCIPAL.getCode()); actionRequest.setPrincipalId(((KimPrincipalRecipient) recipient).getPrincipal().getPrincipalId()); } else if (recipient instanceof KimGroupRecipient) { KimGroupRecipient kimGroupRecipient = (KimGroupRecipient) recipient; actionRequest.setRecipientTypeCd(RecipientType.GROUP.getCode()); actionRequest.setGroupId(kimGroupRecipient.getGroup().getId()); } else if (recipient instanceof RoleRecipient) { RoleRecipient role = (RoleRecipient) recipient; actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode()); actionRequest.setRoleName(role.getRoleName()); actionRequest.setQualifiedRoleName(role.getQualifiedRoleName()); ResolvedQualifiedRole qualifiedRole = role.getResolvedQualifiedRole(); if (qualifiedRole != null) { actionRequest .setAnnotation(qualifiedRole.getAnnotation() == null ? "" : qualifiedRole.getAnnotation()); actionRequest.setQualifiedRoleNameLabel(qualifiedRole.getQualifiedRoleLabel()); } Recipient targetRecipient = role.getTarget(); if (role.getTarget() != null) { if (targetRecipient instanceof RoleRecipient) { throw new WorkflowRuntimeException( "Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId()); } resolveRecipient(actionRequest, role.getTarget()); } } else if (recipient instanceof KimRoleResponsibilityRecipient) { KimRoleResponsibilityRecipient roleResponsibilityRecipient = (KimRoleResponsibilityRecipient) recipient; actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode()); actionRequest.setRoleName(roleResponsibilityRecipient.getResponsibilities().get(0).getRoleId()); actionRequest.setQualifiedRoleName( roleResponsibilityRecipient.getResponsibilities().get(0).getResponsibilityName()); // what about qualified role name label? // actionRequest.setAnnotation(roleRecipient.getResponsibilities().get(0).getResponsibilityName()); Recipient targetRecipient = roleResponsibilityRecipient.getTarget(); if (targetRecipient != null) { if (targetRecipient instanceof RoleRecipient) { throw new WorkflowRuntimeException( "Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId()); } resolveRecipient(actionRequest, roleResponsibilityRecipient.getTarget()); } } else if (recipient instanceof KimRoleRecipient) { KimRoleRecipient roleRecipient = (KimRoleRecipient) recipient; actionRequest.setRecipientTypeCd(RecipientType.ROLE.getCode()); Role role = roleRecipient.getRole(); actionRequest.setRoleName(role.getId()); actionRequest.setQualifiedRoleNameLabel(role.getName()); Recipient targetRecipient = roleRecipient.getTarget(); if (targetRecipient != null) { if (targetRecipient instanceof RoleRecipient) { throw new WorkflowRuntimeException( "Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId()); } resolveRecipient(actionRequest, targetRecipient); } } } /** * Creates a root Role Request * @param role * @param actionRequested * @param approvePolicy * @param priority * @param responsibilityId * @param forceAction * @param description * @param ruleId * @return the created root role request */ public ActionRequestValue addRoleRequest(RoleRecipient role, String actionRequested, String approvePolicy, Integer priority, String responsibilityId, Boolean forceAction, String description, String ruleId) { ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, approvePolicy, ruleId, null); if (role != null && role.getResolvedQualifiedRole() != null && role.getResolvedQualifiedRole().getRecipients() != null) { int legitimateTargets = 0; for (Iterator<Id> iter = role.getResolvedQualifiedRole().getRecipients().iterator(); iter.hasNext();) { Id recipientId = (Id) iter.next(); if (recipientId.isEmpty()) { 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."); } if (recipientId instanceof UserId) { Principal principal = getIdentityHelperService().getPrincipal((UserId) recipientId); if (KRADUtils.isNotNull(principal)) { role.setTarget(new KimPrincipalRecipient(principal)); } } else if (recipientId instanceof GroupId) { role.setTarget( new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId))); } else { throw new WorkflowRuntimeException( "Could not process the given type of id: " + recipientId.getClass()); } if (role.getTarget() != null) { legitimateTargets++; ActionRequestValue request = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, null, ruleId, null); request.setParentActionRequest(requestGraph); requestGraph.getChildrenRequests().add(request); } } if (legitimateTargets == 0) { LOG.warn("Role did not yield any legitimate recipients"); } } else { LOG.warn("Didn't create action requests for action request description '" + description + "' because of null role or null part of role object graph."); } requestGraphs.add(requestGraph); return requestGraph; } /** * Generates an ActionRequest graph for the given KIM Responsibilities. This graph includes any associated delegations. * @param responsibilities * @param approvePolicy */ public void addRoleResponsibilityRequest(List<ResponsibilityAction> responsibilities, String approvePolicy) { if (responsibilities == null || responsibilities.isEmpty()) { LOG.warn( "Didn't create action requests for action request description because no responsibilities were defined."); return; } // it's assumed the that all in the list have the same action type code, priority number, etc. String actionTypeCode = responsibilities.get(0).getActionTypeCode(); Integer priority = responsibilities.get(0).getPriorityNumber(); boolean forceAction = responsibilities.get(0).isForceAction(); KimRoleResponsibilityRecipient roleResponsibilityRecipient = new KimRoleResponsibilityRecipient( responsibilities); // Creation of a parent graph entry for ???? ActionRequestValue requestGraph = null; StringBuffer parentAnnotation = null; // set to allow for suppression of duplicate annotations on the parent action request Set<String> uniqueChildAnnotations = null; if (responsibilities.size() > 1) { requestGraph = createActionRequest(actionTypeCode, priority, roleResponsibilityRecipient, "", // description KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, forceAction, approvePolicy, null, // ruleId null);// annotation requestGraphs.add(requestGraph); parentAnnotation = new StringBuffer(); uniqueChildAnnotations = new HashSet<String>(responsibilities.size()); } StringBuffer annotation = new StringBuffer(); for (ResponsibilityAction responsibility : responsibilities) { if (LOG.isDebugEnabled()) { LOG.debug("Processing Responsibility for action request: " + responsibility); } // KFSMI-2381 - pull information from KIM to populate annotation annotation.setLength(0); Role role = getRoleService().getRole(responsibility.getRoleId()); annotation.append(role.getNamespaceCode()).append(' ').append(role.getName()).append(' '); Map<String, String> qualifier = responsibility.getQualifier(); if (qualifier != null) { for (String key : qualifier.keySet()) { annotation.append(qualifier.get(key)).append(' '); } } if (responsibility.getPrincipalId() != null) { roleResponsibilityRecipient.setTarget(new KimPrincipalRecipient(responsibility.getPrincipalId())); } else if (responsibility.getGroupId() != null) { roleResponsibilityRecipient.setTarget(new KimGroupRecipient(responsibility.getGroupId())); } else { throw new RiceRuntimeException( "Failed to identify a group or principal on the given ResponsibilityResolutionInfo:" + responsibility); } String annotationStr = annotation.toString(); ActionRequestValue request = createActionRequest(responsibility.getActionTypeCode(), responsibility.getPriorityNumber(), roleResponsibilityRecipient, responsibility.getParallelRoutingGroupingCode(), // description responsibility.getResponsibilityId(), responsibility.isForceAction(), // If not nested in a parent action request, ensure that the request // is first approve so delegations of this request do not require // ALL_APPROVE as well (responsibilities.size() == 1) ? ActionRequestPolicy.FIRST.getCode() : approvePolicy, null, // ruleId annotationStr); // if there is only a single request, don't create the nesting structure if (responsibilities.size() > 1) { request.setParentActionRequest(requestGraph); requestGraph.getChildrenRequests().add(request); if (!uniqueChildAnnotations.contains(annotationStr)) { parentAnnotation.append(annotationStr).append(" -- "); uniqueChildAnnotations.add(annotationStr); } } else { requestGraphs.add(request); } generateKimRoleDelegationRequests(responsibility.getDelegates(), request); } if (responsibilities.size() > 1) { requestGraph.setAnnotation(StringUtils.chomp(parentAnnotation.toString(), " -- ")); } } private String generateRoleResponsibilityDelegateAnnotation(DelegateMember member, boolean isPrincipal, boolean isGroup, ActionRequestValue parentRequest) { StringBuffer annotation = new StringBuffer("Delegation of: "); annotation.append(parentRequest.getAnnotation()); annotation.append(" to "); if (isPrincipal) { annotation.append("principal "); Principal principal = getIdentityService().getPrincipal(member.getMemberId()); if (principal != null) { annotation.append(principal.getPrincipalName()); } else { annotation.append(member.getMemberId()); } } else if (isGroup) { annotation.append("group "); Group group = getGroupService().getGroup(member.getMemberId()); if (group != null) { annotation.append(group.getNamespaceCode()).append('/').append(group.getName()); } else { annotation.append(member.getMemberId()); } } else { annotation.append("?????? '"); annotation.append(member.getMemberId()); annotation.append("'"); } return annotation.toString(); } public ActionRequestValue addDelegationRoleRequest(ActionRequestValue parentRequest, String approvePolicy, RoleRecipient role, String responsibilityId, Boolean forceAction, DelegationType delegationType, String description, String ruleId) { Recipient parentRecipient = parentRequest.getRecipient(); if (parentRecipient instanceof RoleRecipient) { 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"); } if (!relatedToRoot(parentRequest)) { throw new WorkflowRuntimeException( "The parent request is not related to any request managed by this factory"); } ActionRequestValue delegationRoleRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, approvePolicy, ruleId, null); delegationRoleRequest.setDelegationType(delegationType); int count = 0; for (Iterator<Id> iter = role.getResolvedQualifiedRole().getRecipients().iterator(); iter .hasNext(); count++) { //repeat of createRoleRequest code Id recipientId = iter.next(); if (recipientId.isEmpty()) { 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."); } if (recipientId instanceof UserId) { role.setTarget( new KimPrincipalRecipient(getIdentityHelperService().getPrincipal((UserId) recipientId))); } else if (recipientId instanceof GroupId) { role.setTarget(new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId))); } else { throw new WorkflowRuntimeException( "Could not process the given type of id: " + recipientId.getClass()); } ActionRequestValue request = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, null, ruleId, null); request.setDelegationType(delegationType); //end repeat request.setParentActionRequest(delegationRoleRequest); delegationRoleRequest.getChildrenRequests().add(request); } //put this mini graph in the larger graph if (count > 0) { parentRequest.getChildrenRequests().add(delegationRoleRequest); delegationRoleRequest.setParentActionRequest(parentRequest); } return delegationRoleRequest; } /** * Add a delegation request to the given parent action request. * * @param parentRequest the parent request to add it to * @param recipient the recipient to send the delegation request to * @param responsibilityId * @param forceAction * @param delegationType primary or secondary? * @param actionRequestPolicyCode the action request policy code specifying when the action requests are considered to be completed * @param annotation the annotation to put on the delegation request * @param ruleId * @return the delegation request that was added */ public ActionRequestValue addDelegationRequest(ActionRequestValue parentRequest, Recipient recipient, String responsibilityId, Boolean forceAction, DelegationType delegationType, String actionRequestPolicyCode, String annotation, String ruleId) { if (!relatedToRoot(parentRequest)) { throw new WorkflowRuntimeException( "The parent request is not related to any request managed by this factory"); } ActionRequestValue delegationRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), recipient, parentRequest.getResponsibilityDesc(), responsibilityId, forceAction, actionRequestPolicyCode, ruleId, annotation); delegationRequest.setDelegationType(delegationType); parentRequest.getChildrenRequests().add(delegationRequest); delegationRequest.setParentActionRequest(parentRequest); return delegationRequest; } /** * Add a delegation request to the given parent action request. * * <p>no action type policy code will be specified.</p> * * @param parentRequest the parent request to add it to * @param recipient the recipient to send the delegation request to * @param responsibilityId * @param forceAction * @param delegationType primary or secondary? * @param annotation the annotation to put on the delegation request * @param ruleId * @return the delegation request that was added */ public ActionRequestValue addDelegationRequest(ActionRequestValue parentRequest, Recipient recipient, String responsibilityId, Boolean forceAction, DelegationType delegationType, String annotation, String ruleId) { return addDelegationRequest(parentRequest, recipient, responsibilityId, forceAction, delegationType, null, annotation, ruleId); } //could probably base behavior off of recipient type public ActionRequestValue addRootActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, String responsibilityId, Boolean forceAction, String approvePolicy, String ruleId) { ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, null); requestGraphs.add(requestGraph); return requestGraph; } /** * Generates an ActionRequest graph for the given KIM Responsibilities. This graph includes any associated delegations. * * @param actionRequestedCode the type of action requested * @param priority * @param role the role that the members belong to * @param memberships the role members to generate child requests to * @param description * @param responsibilityId * @param forceAction * @param actionRequestPolicyCode the action request policy code specifying when the action requests are considered to be completed * @param requestLabel * @return the request generated for the role members */ public ActionRequestValue addKimRoleRequest(String actionRequestedCode, Integer priority, Role role, List<RoleMembership> memberships, String description, String responsibilityId, boolean forceAction, String actionRequestPolicyCode, String requestLabel) { return addKimRoleRequest(actionRequestedCode, priority, role, memberships, description, responsibilityId, forceAction, actionRequestPolicyCode, requestLabel, /* ignoreKimDelegates = */ false); } /** * Generates an ActionRequest graph for the given KIM Responsibilities. This graph includes any associated delegations. * * @param actionRequestedCode the type of action requested * @param priority * @param role the role that the members belong to * @param memberships the role members to generate child requests to * @param description * @param responsibilityId * @param forceAction * @param actionRequestPolicyCode the action request policy code specifying when the action requests are considered to be completed * @param requestLabel * @param ignoreKimDelegates should kim delegates be ignored when generating requests * @return the request generated for the role members */ public ActionRequestValue addKimRoleRequest(String actionRequestedCode, Integer priority, Role role, List<RoleMembership> memberships, String description, String responsibilityId, boolean forceAction, String actionRequestPolicyCode, String requestLabel, boolean ignoreKimDelegates) { ActionRequestValue roleMemberRequest = null; if (CollectionUtils.isEmpty(memberships)) { LOG.warn( "Didn't create action requests for action request description because no role members were defined for role id " + role.getId()); return roleMemberRequest; } KimRoleRecipient roleRecipient = new KimRoleRecipient(role); // Creation of a parent graph entry for ???? ActionRequestValue requestGraph = null; if (memberships.size() > 1) { requestGraph = createActionRequest(actionRequestedCode, priority, roleRecipient, "", // description responsibilityId, forceAction, actionRequestPolicyCode, null, // ruleId null);// annotation requestGraphs.add(requestGraph); } for (RoleMembership membership : memberships) { if (LOG.isDebugEnabled()) { LOG.debug("Processing RoleMembership for action request: " + membership); } if (MemberType.PRINCIPAL.equals(membership.getType())) { roleRecipient.setTarget(new KimPrincipalRecipient(membership.getMemberId())); } else if (MemberType.GROUP.equals(membership.getType())) { roleRecipient.setTarget(new KimGroupRecipient(membership.getMemberId())); } else { throw new RiceRuntimeException( "Failed to identify a group or principal on the given RoleMembership:" + membership); } ActionRequestValue request = createActionRequest(actionRequestedCode, priority, roleRecipient, "", // description responsibilityId, forceAction, // If not nested in a parent action request, ensure that the request // is first approve so delegations of this request do not require // ALL_APPROVE as well (memberships.size() == 1) ? ActionRequestPolicy.FIRST.getCode() : actionRequestPolicyCode, null, // ruleId null); // annotation // if there is only a single request, don't create the nesting structure if (memberships.size() > 1) { request.setParentActionRequest(requestGraph); requestGraph.getChildrenRequests().add(request); if (roleMemberRequest == null) { roleMemberRequest = requestGraph; } } else { roleMemberRequest = request; requestGraphs.add(request); } if (!ignoreKimDelegates) { generateKimRoleDelegationRequests(membership.getDelegates(), request); } } return roleMemberRequest; } /** * Generates a delegate request to a KIM role. * * <p>In other words, the Role is the delegate. Since delegates in KEW are limited to 1 level, this will ignore * any KIM delegations on the given role.</p> * * @param parentRequest the parent request that the delegate request will be added to * @param actionRequestedCode the type of action requested * @param priority * @param role the role that is being delegated to * @param memberships the role members to generate child requests to * @param description * @param responsibilityId * @param forceAction * @param actionRequestPolicyCode the action request policy code specifying when the action requests are considered to be completed * @param requestLabel * @return the delegate request generated for the role members */ public ActionRequestValue addDelegateKimRoleRequest(ActionRequestValue parentRequest, DelegationType delegationType, String actionRequestedCode, Integer priority, Role role, List<RoleMembership> memberships, String description, String responsibilityId, boolean forceAction, String actionRequestPolicyCode, String requestLabel) { // This is a modified version of addKimRoleRequest. The methods could probably be combined, // but the signature would be even more out of hand and the usage even more confusing. ActionRequestValue delegateRoleRequest = null; if (CollectionUtils.isEmpty(memberships)) { LOG.warn( "Didn't create action requests for action request description because no role members were defined for role id " + role.getId()); return delegateRoleRequest; } KimRoleRecipient roleRecipient = new KimRoleRecipient(role); // Creation of a parent graph entry for ???? ActionRequestValue requestGraph = null; if (memberships.size() > 1) { requestGraph = createActionRequest(actionRequestedCode, priority, roleRecipient, "", // description responsibilityId, forceAction, actionRequestPolicyCode, null, // ruleId null);// annotation requestGraphs.add(requestGraph); } for (RoleMembership membership : memberships) { if (LOG.isDebugEnabled()) { LOG.debug("Processing RoleMembership for action request: " + membership); } if (MemberType.PRINCIPAL.equals(membership.getType())) { roleRecipient.setTarget(new KimPrincipalRecipient(membership.getMemberId())); } else if (MemberType.GROUP.equals(membership.getType())) { roleRecipient.setTarget(new KimGroupRecipient(membership.getMemberId())); } else { throw new RiceRuntimeException( "Failed to identify a group or principal on the given RoleMembership:" + membership); } ActionRequestValue request = createActionRequest(actionRequestedCode, priority, roleRecipient, "", // description responsibilityId, forceAction, // If not nested in a parent action request, ensure that the request // is first approve so delegations of this request do not require // ALL_APPROVE as well (memberships.size() == 1) ? ActionRequestPolicy.FIRST.getCode() : actionRequestPolicyCode, null, // ruleId null); // annotation // if there is only a single request, don't create the nesting structure if (memberships.size() > 1) { request.setParentActionRequest(requestGraph); requestGraph.getChildrenRequests().add(request); if (delegateRoleRequest == null) { delegateRoleRequest = requestGraph; } } else { delegateRoleRequest = request; } } delegateRoleRequest.setDelegationType(delegationType); delegateRoleRequest.setParentActionRequest(parentRequest); parentRequest.getChildrenRequests().add(delegateRoleRequest); return delegateRoleRequest; } private void generateKimRoleDelegationRequests(List<DelegateType> delegates, ActionRequestValue parentRequest) { for (DelegateType delegate : delegates) { for (DelegateMember member : delegate.getMembers()) { Recipient recipient; boolean isPrincipal = MemberType.PRINCIPAL.equals(member.getType()); boolean isGroup = MemberType.GROUP.equals(member.getType()); if (isPrincipal) { recipient = new KimPrincipalRecipient(member.getMemberId()); } else if (isGroup) { recipient = new KimGroupRecipient(member.getMemberId()); } else { throw new RiceRuntimeException( "Invalid DelegateInfo memberTypeCode encountered, was '" + member.getType() + "'"); } String delegationAnnotation = generateRoleResponsibilityDelegateAnnotation(member, isPrincipal, isGroup, parentRequest); addDelegationRequest(parentRequest, recipient, delegate.getDelegationId(), parentRequest.getForceAction(), delegate.getDelegationType(), delegationAnnotation, null); } } } //return true if requestGraph (root) is in this requests' parents public boolean relatedToRoot(ActionRequestValue request) { int i = 0; while (i < 3) { if (requestGraphs.contains(request)) { return true; } else if (request == null) { return false; } i++; request = request.getParentActionRequest(); } return false; } public List<ActionRequestValue> getRequestGraphs() { //clean up all the trailing role requests with no children - requestGraphs.removeAll(cleanUpChildren(requestGraphs)); return requestGraphs; } private Collection<ActionRequestValue> cleanUpChildren(Collection<ActionRequestValue> children) { Collection<ActionRequestValue> requestsToRemove = new ArrayList<ActionRequestValue>(); for (ActionRequestValue aChildren : children) { if (aChildren.isRoleRequest()) { if (aChildren.getChildrenRequests().isEmpty()) { requestsToRemove.add(aChildren); } else { Collection<ActionRequestValue> childRequestsToRemove = cleanUpChildren( aChildren.getChildrenRequests()); aChildren.getChildrenRequests().removeAll(childRequestsToRemove); } } } return requestsToRemove; } private String generateNotificationAnnotation(PrincipalContract principal, String notificationRequestCode, String actionTakenCode, ActionRequestValue request) { String notification = "Action " + CodeTranslator.getActionRequestLabel(notificationRequestCode) + " generated by Workflow because " + principal.getPrincipalName() + " took action " + CodeTranslator.getActionTakenLabel(actionTakenCode); // FIXME: KULRICE-5201 switched rsp_id to a varchar, so the comparison below is no longer valid // if (request.getResponsibilityId() != null && request.getResponsibilityId() != 0) { // TODO: KULRICE-5329 Verify that this code below makes sense and is sufficient if (request.getResponsibilityId() != null && !KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(request.getResponsibilityId())) { notification += " Responsibility " + request.getResponsibilityId(); } if (request.getRuleBaseValuesId() != null) { notification += " Rule Id " + request.getRuleBaseValuesId(); } if (request.getAnnotation() != null && request.getAnnotation().length() != 0) { notification += " " + request.getAnnotation(); } return notification; } protected static ActionRequestService getActionRequestService() { if (actionRequestService == null) { actionRequestService = KEWServiceLocator.getActionRequestService(); } return actionRequestService; } /** * @return the roleService */ protected static RoleService getRoleService() { if (roleService == null) { roleService = KimApiServiceLocator.getRoleService(); } return roleService; } /** * @return the identityHelperService */ protected static IdentityHelperService getIdentityHelperService() { if (identityHelperService == null) { identityHelperService = KEWServiceLocator.getIdentityHelperService(); } return identityHelperService; } /** * @return the identityService */ protected static IdentityService getIdentityService() { if (identityService == null) { identityService = KimApiServiceLocator.getIdentityService(); } return identityService; } protected static GroupService getGroupService() { if (groupService == null) { groupService = KimApiServiceLocator.getGroupService(); } return groupService; } }