Coverage Report - org.kuali.rice.kew.actionrequest.ActionRequestFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionRequestFactory
0%
0/304
0%
0/150
3.967
 
 1  
 /*
 2  
  * Copyright 2006-2011 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  
 
 17  
 package org.kuali.rice.kew.actionrequest;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.log4j.Logger;
 21  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 22  
 import org.kuali.rice.core.api.mo.common.Attributes;
 23  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 24  
 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
 25  
 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
 26  
 import org.kuali.rice.kew.exception.WorkflowRuntimeException;
 27  
 import org.kuali.rice.kew.identity.Id;
 28  
 import org.kuali.rice.kew.identity.service.IdentityHelperService;
 29  
 import org.kuali.rice.kew.role.KimRoleRecipient;
 30  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 31  
 import org.kuali.rice.kew.rule.ResolvedQualifiedRole;
 32  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 33  
 import org.kuali.rice.kew.user.RoleRecipient;
 34  
 import org.kuali.rice.kew.user.UserId;
 35  
 import org.kuali.rice.kew.util.CodeTranslator;
 36  
 import org.kuali.rice.kew.util.KEWConstants;
 37  
 import org.kuali.rice.kew.util.Utilities;
 38  
 import org.kuali.rice.kew.workgroup.GroupId;
 39  
 import org.kuali.rice.kim.api.common.delegate.Delegate;
 40  
 import org.kuali.rice.kim.api.entity.principal.Principal;
 41  
 import org.kuali.rice.kim.api.entity.principal.PrincipalContract;
 42  
 import org.kuali.rice.kim.api.group.Group;
 43  
 import org.kuali.rice.kim.api.responsibility.ResponsibilityAction;
 44  
 import org.kuali.rice.kim.api.services.IdentityManagementService;
 45  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 46  
 import org.kuali.rice.kim.bo.Role;
 47  
 import org.kuali.rice.kim.bo.role.dto.KimRoleInfo;
 48  
 import org.kuali.rice.kim.service.RoleManagementService;
 49  
 import org.kuali.rice.kns.util.KNSConstants;
 50  
 
 51  
 import java.sql.Timestamp;
 52  
 import java.util.ArrayList;
 53  
 import java.util.Collection;
 54  
 import java.util.HashSet;
 55  
 import java.util.Iterator;
 56  
 import java.util.List;
 57  
 import java.util.Set;
 58  
 
 59  
 
 60  
 /**
 61  
  * A factory to aid in creating the ever-so-gnarly ActionRequestValue object.
 62  
  *
 63  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 64  
  */
 65  
 public class ActionRequestFactory {
 66  
 
 67  0
         private static final Logger LOG = Logger.getLogger(ActionRequestFactory.class);
 68  
 
 69  
         private static RoleManagementService roleManagementService;
 70  
         private static IdentityHelperService identityHelperService;
 71  
         private static IdentityManagementService identityManagementService;
 72  
         private static ActionRequestService actionRequestService;
 73  
         
 74  
         private DocumentRouteHeaderValue document;
 75  
         private RouteNodeInstance routeNode;
 76  0
         private List<ActionRequestValue> requestGraphs = new ArrayList<ActionRequestValue>();
 77  
 
 78  0
         public ActionRequestFactory() {
 79  0
         }
 80  
 
 81  0
         public ActionRequestFactory(DocumentRouteHeaderValue document) {
 82  0
                 this.document = document;
 83  0
         }
 84  
 
 85  0
         public ActionRequestFactory(DocumentRouteHeaderValue document, RouteNodeInstance routeNode) {
 86  0
                 this.document = document;
 87  0
                 this.routeNode = routeNode;
 88  0
         }
 89  
 
 90  
         /**
 91  
          * Constructs ActionRequestValue using default priority and 0 as responsibility
 92  
          *
 93  
          * @param actionRequested
 94  
          * @param recipient
 95  
          * @param description
 96  
          * @param forceAction
 97  
          * @param annotation
 98  
      * @return ActionRequestValue
 99  
          */
 100  
         public ActionRequestValue createActionRequest(String actionRequested, Recipient recipient, String description, Boolean forceAction, String annotation) {
 101  0
                 return createActionRequest(actionRequested, 0, recipient, description, KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, forceAction, annotation);
 102  
         }
 103  
 
 104  
         public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, Long responsibilityId, Boolean forceAction, String annotation) {
 105  0
             return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, null, null, annotation);
 106  
     }
 107  
 
 108  
         public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, Long responsibilityId, Boolean forceAction, String approvePolicy, Long ruleId, String annotation) {
 109  0
                 return createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, annotation, null);
 110  
         }
 111  
 
 112  
         public ActionRequestValue createActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, Long responsibilityId, Boolean forceAction, String approvePolicy, Long ruleId, String annotation, String requestLabel) {
 113  0
                 ActionRequestValue actionRequest = new ActionRequestValue();
 114  0
         actionRequest.setActionRequested(actionRequested);
 115  0
         actionRequest.setDocVersion(document.getDocVersion());
 116  0
         actionRequest.setPriority(priority);
 117  0
         actionRequest.setRouteHeader(document);
 118  0
         actionRequest.setDocumentId(document.getDocumentId());
 119  0
         actionRequest.setRouteLevel(document.getDocRouteLevel());
 120  0
             actionRequest.setNodeInstance(routeNode);
 121  0
             actionRequest.setResponsibilityId(responsibilityId);
 122  0
             actionRequest.setResponsibilityDesc(description);
 123  0
             actionRequest.setApprovePolicy(approvePolicy);
 124  0
             actionRequest.setForceAction(forceAction);
 125  0
             actionRequest.setRuleBaseValuesId(ruleId);
 126  0
             actionRequest.setAnnotation(annotation);
 127  0
             actionRequest.setRequestLabel(requestLabel);
 128  0
             setDefaultProperties(actionRequest);
 129  0
             resolveRecipient(actionRequest, recipient);
 130  
 
 131  0
         return actionRequest;
 132  
         }
 133  
 
 134  
         public ActionRequestValue createBlankActionRequest() {
 135  0
                 ActionRequestValue request = new ActionRequestValue();
 136  0
                 request.setRouteHeader(document);
 137  0
                 if (document != null) {
 138  0
                         request.setDocumentId(document.getDocumentId());
 139  
                 }
 140  0
                 request.setNodeInstance(routeNode);
 141  0
                 return request;
 142  
         }
 143  
 
 144  
 
 145  
     public ActionRequestValue createNotificationRequest(String actionRequestCode, PrincipalContract principal, String reasonActionCode, PrincipalContract reasonActionUser, String responsibilityDesc) {
 146  0
             ActionRequestValue request = createActionRequest(actionRequestCode, new KimPrincipalRecipient(principal), responsibilityDesc, Boolean.TRUE, null);
 147  0
             String annotation = generateNotificationAnnotation(reasonActionUser, actionRequestCode, reasonActionCode, request);
 148  0
             request.setAnnotation(annotation);
 149  0
             return request;
 150  
     }
 151  
 
 152  
     //unify these 2 methods if possible
 153  
     public List<ActionRequestValue> generateNotifications(List requests, PrincipalContract principal, Recipient delegator,
 154  
             String notificationRequestCode, String actionTakenCode)
 155  
     {
 156  0
         String groupName =  CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KEWConstants.KEW_NAMESPACE,
 157  
                 KNSConstants.DetailTypes.WORKGROUP_DETAIL_TYPE,
 158  
                 KEWConstants.NOTIFICATION_EXCLUDED_USERS_WORKGROUP_NAME_IND);
 159  
         
 160  
         
 161  0
         Group notifyExclusionWorkgroup = null;
 162  0
         if(!StringUtils.isBlank(groupName)){
 163  0
                 notifyExclusionWorkgroup = getIdentityManagementService().getGroupByName(Utilities.parseGroupNamespaceCode(groupName), Utilities.parseGroupName(groupName));
 164  
         }
 165  
         
 166  
  
 167  
         
 168  0
         return generateNotifications(null, getActionRequestService().getRootRequests(requests), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup);
 169  
     }
 170  
 
 171  
     private List<ActionRequestValue> generateNotifications(ActionRequestValue parentRequest,
 172  
             List requests, PrincipalContract principal, Recipient delegator, String notificationRequestCode,
 173  
             String actionTakenCode, Group notifyExclusionWorkgroup)
 174  
     {
 175  0
         List<ActionRequestValue> notificationRequests = new ArrayList<ActionRequestValue>();
 176  0
         for (Object request : requests)
 177  
         {
 178  0
             ActionRequestValue actionRequest = (ActionRequestValue) request;
 179  0
             if (!(actionRequest.isRecipientRoutedRequest(principal.getPrincipalId()) || actionRequest.isRecipientRoutedRequest(delegator)))
 180  
             {
 181  
                 // skip user requests to system users
 182  0
                 if ((notifyExclusionWorkgroup != null) &&
 183  
                         (isRecipientInGroup(notifyExclusionWorkgroup, actionRequest.getRecipient())))
 184  
                 {
 185  0
                     continue;
 186  
                 }
 187  0
                 ActionRequestValue notificationRequest = createNotificationRequest(actionRequest, principal, notificationRequestCode, actionTakenCode);
 188  0
                 notificationRequests.add(notificationRequest);
 189  0
                 if (parentRequest != null)
 190  
                 {
 191  0
                     notificationRequest.setParentActionRequest(parentRequest);
 192  0
                     parentRequest.getChildrenRequests().add(notificationRequest);
 193  
                 }
 194  0
                 notificationRequests.addAll(generateNotifications(notificationRequest, actionRequest.getChildrenRequests(), principal, delegator, notificationRequestCode, actionTakenCode, notifyExclusionWorkgroup));
 195  
             }
 196  0
         }
 197  0
         return notificationRequests;
 198  
     }
 199  
 
 200  
     private boolean isRecipientInGroup(Group group, Recipient recipient)
 201  
     {
 202  0
         boolean isMember = false;
 203  
 
 204  0
         if(recipient instanceof KimPrincipalRecipient)
 205  
         {
 206  0
             String principalId = ((KimPrincipalRecipient) recipient).getPrincipalId();
 207  0
             String groupId = group.getId();
 208  0
             isMember = getIdentityManagementService().isMemberOfGroup(principalId, groupId);
 209  0
         }
 210  0
         else if (recipient instanceof KimGroupRecipient)
 211  
         {
 212  0
             String kimRecipientId = ((KimGroupRecipient) recipient).getGroup().getId();
 213  0
             isMember = getIdentityManagementService().isGroupMemberOfGroup(kimRecipientId, group.getId() );
 214  
         }
 215  0
         return isMember;
 216  
     }
 217  
 
 218  
     private ActionRequestValue createNotificationRequest(ActionRequestValue actionRequest, PrincipalContract reasonPrincipal, String notificationRequestCode, String actionTakenCode) {
 219  
 
 220  0
             String annotation = generateNotificationAnnotation(reasonPrincipal, notificationRequestCode, actionTakenCode, actionRequest);
 221  0
         ActionRequestValue request = createActionRequest(notificationRequestCode, actionRequest.getPriority(), actionRequest.getRecipient(), actionRequest.getResponsibilityDesc(), KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, Boolean.TRUE, annotation);
 222  
 
 223  0
         request.setDocVersion(actionRequest.getDocVersion());
 224  0
         request.setApprovePolicy(actionRequest.getApprovePolicy());
 225  0
         request.setRoleName(actionRequest.getRoleName());
 226  0
         request.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
 227  0
         request.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
 228  0
         request.setDelegationType(actionRequest.getDelegationType());
 229  0
         return request;
 230  
     }
 231  
 
 232  
     private void setDefaultProperties(ActionRequestValue actionRequest) {
 233  0
             if (actionRequest.getApprovePolicy() == null) {
 234  0
                     actionRequest.setApprovePolicy(KEWConstants.APPROVE_POLICY_FIRST_APPROVE);
 235  
             }
 236  0
         actionRequest.setCreateDate(new Timestamp(System.currentTimeMillis()));
 237  0
         actionRequest.setCurrentIndicator(Boolean.TRUE);
 238  0
         if (actionRequest.getForceAction() == null) {
 239  0
                 actionRequest.setForceAction(Boolean.FALSE);
 240  
         }
 241  0
         if (routeNode != null) {
 242  0
                 actionRequest.setNodeInstance(routeNode);
 243  
         }
 244  0
         actionRequest.setJrfVerNbr(0);
 245  0
         actionRequest.setStatus(KEWConstants.ACTION_REQUEST_INITIALIZED);
 246  0
         actionRequest.setRouteHeader(document);
 247  0
         actionRequest.setDocumentId(document.getDocumentId());
 248  0
     }
 249  
 
 250  
     private static void resolveRecipient(ActionRequestValue actionRequest, Recipient recipient) {
 251  0
             if (recipient instanceof KimPrincipalRecipient) {
 252  0
                     actionRequest.setRecipientTypeCd(KEWConstants.ACTION_REQUEST_USER_RECIPIENT_CD);
 253  0
                     actionRequest.setPrincipalId(((KimPrincipalRecipient)recipient).getPrincipal().getPrincipalId());
 254  0
             }  else if (recipient instanceof KimGroupRecipient) {
 255  0
                     KimGroupRecipient kimGroupRecipient = (KimGroupRecipient)recipient;
 256  0
                     actionRequest.setRecipientTypeCd(KEWConstants.ACTION_REQUEST_GROUP_RECIPIENT_CD);
 257  0
                     actionRequest.setGroupId(kimGroupRecipient.getGroup().getId());
 258  0
             } else if (recipient instanceof RoleRecipient){
 259  0
                     RoleRecipient role = (RoleRecipient)recipient;
 260  0
                     actionRequest.setRecipientTypeCd(KEWConstants.ACTION_REQUEST_ROLE_RECIPIENT_CD);
 261  0
                     actionRequest.setRoleName(role.getRoleName());
 262  0
                     actionRequest.setQualifiedRoleName(role.getQualifiedRoleName());
 263  0
                     ResolvedQualifiedRole qualifiedRole = role.getResolvedQualifiedRole();
 264  0
                     if (qualifiedRole != null) {
 265  0
                             actionRequest.setAnnotation(qualifiedRole.getAnnotation() == null ? "" : qualifiedRole.getAnnotation());
 266  0
                             actionRequest.setQualifiedRoleNameLabel(qualifiedRole.getQualifiedRoleLabel());
 267  
                     }
 268  0
                     Recipient targetRecipient = role.getTarget();
 269  0
                     if (role.getTarget() != null) {
 270  0
                             if (targetRecipient instanceof RoleRecipient) {
 271  0
                                     throw new WorkflowRuntimeException("Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId());
 272  
                             }
 273  0
                             resolveRecipient(actionRequest, role.getTarget());
 274  
                     }
 275  0
             } else if (recipient instanceof KimRoleRecipient) {
 276  0
                     KimRoleRecipient roleRecipient = (KimRoleRecipient)recipient;
 277  0
                     actionRequest.setRecipientTypeCd(KEWConstants.ACTION_REQUEST_ROLE_RECIPIENT_CD);
 278  0
                     actionRequest.setRoleName(roleRecipient.getResponsibilities().get(0).getRoleId());
 279  0
                     actionRequest.setQualifiedRoleName(roleRecipient.getResponsibilities().get(0).getResponsibilityName());
 280  
                     // what about qualified role name label?
 281  
 //                    actionRequest.setAnnotation(roleRecipient.getResponsibilities().get(0).getResponsibilityName());
 282  0
                     Recipient targetRecipient = roleRecipient.getTarget();
 283  0
                     if (targetRecipient != null) {
 284  0
                             if (targetRecipient instanceof RoleRecipient) {
 285  0
                                     throw new WorkflowRuntimeException("Role Cannot Target a role problem activating request for document " + actionRequest.getDocumentId());
 286  
                             }
 287  0
                             resolveRecipient(actionRequest, roleRecipient.getTarget());
 288  
                     }
 289  
             }
 290  0
     }
 291  
 
 292  
     /**
 293  
      * Creates a root Role Request
 294  
      * @param role
 295  
      * @param actionRequested
 296  
      * @param approvePolicy
 297  
      * @param priority
 298  
      * @param responsibilityId
 299  
      * @param forceAction
 300  
      * @param description
 301  
      * @param ruleId
 302  
      * @return the created root role request
 303  
      */
 304  
     public ActionRequestValue addRoleRequest(RoleRecipient role, String actionRequested, String approvePolicy, Integer priority, Long responsibilityId, Boolean forceAction, String description, Long ruleId) {
 305  
 
 306  0
             ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
 307  0
             if (role != null && role.getResolvedQualifiedRole() != null && role.getResolvedQualifiedRole().getRecipients() != null) {
 308  0
                 int legitimateTargets = 0;
 309  0
             for (Id recipientId : role.getResolvedQualifiedRole().getRecipients())
 310  
             {
 311  0
                 if (recipientId.isEmpty())
 312  
                 {
 313  0
                     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.");
 314  
                 }
 315  0
                 if (recipientId instanceof UserId)
 316  
                 {
 317  0
                     Principal principal = getIdentityHelperService().getPrincipal((UserId) recipientId);
 318  0
                     role.setTarget(new KimPrincipalRecipient(principal));
 319  0
                 } else if (recipientId instanceof GroupId)
 320  
                 {
 321  0
                     role.setTarget(new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId)));
 322  
                 } else
 323  
                 {
 324  0
                     throw new WorkflowRuntimeException("Could not process the given type of id: " + recipientId.getClass());
 325  
                 }
 326  0
                 if (role.getTarget() != null)
 327  
                 {
 328  0
                     legitimateTargets++;
 329  0
                     ActionRequestValue request = createActionRequest(actionRequested, priority, role, description, responsibilityId, forceAction, null, ruleId, null);
 330  0
                     request.setParentActionRequest(requestGraph);
 331  0
                     requestGraph.getChildrenRequests().add(request);
 332  0
                 }
 333  
             }
 334  0
             if (legitimateTargets == 0) {
 335  0
             LOG.warn("Role did not yield any legitimate recipients");
 336  
         }
 337  0
             } else {
 338  0
                     LOG.warn("Didn't create action requests for action request description '" + description + "' because of null role or null part of role object graph.");
 339  
             }
 340  0
             requestGraphs.add(requestGraph);
 341  0
             return requestGraph;
 342  
     }
 343  
 
 344  
     /**
 345  
      * Generates an ActionRequest graph for the given KIM Responsibilities.  This graph includes any associated delegations.
 346  
      * @param responsibilities
 347  
      * @param approvePolicy
 348  
      */
 349  
     public void addRoleResponsibilityRequest(List<ResponsibilityAction> responsibilities, String approvePolicy) {
 350  0
             if (responsibilities == null || responsibilities.isEmpty()) {
 351  0
                     LOG.warn("Didn't create action requests for action request description because no responsibilities were defined.");
 352  0
                     return;
 353  
             }
 354  
             // it's assumed the that all in the list have the same action type code, priority number, etc.
 355  0
             String actionTypeCode = responsibilities.get(0).getActionTypeCode();
 356  0
             Integer priority = responsibilities.get(0).getPriorityNumber();
 357  0
             boolean forceAction = responsibilities.get(0).isForceAction();
 358  0
             KimRoleRecipient roleRecipient = new KimRoleRecipient(responsibilities);
 359  
 
 360  
             // Creation of a parent graph entry for ????
 361  0
             ActionRequestValue requestGraph = null;
 362  0
             StringBuffer parentAnnotation = null;
 363  
             // set to allow for suppression of duplicate annotations on the parent action request
 364  0
             Set<String> uniqueChildAnnotations = null;
 365  0
             if ( responsibilities.size() > 1 ) {
 366  0
                     requestGraph = createActionRequest(
 367  
                             actionTypeCode, 
 368  
                             priority, 
 369  
                             roleRecipient, 
 370  
                             "", // description 
 371  
                             KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, 
 372  
                             forceAction, 
 373  
                             approvePolicy, 
 374  
                             null, // ruleId
 375  
                             null );// annotation
 376  0
                     requestGraphs.add(requestGraph);
 377  0
                     parentAnnotation = new StringBuffer();
 378  0
                     uniqueChildAnnotations = new HashSet<String>( responsibilities.size() );
 379  
             }
 380  0
             StringBuffer annotation = new StringBuffer();
 381  0
             for (ResponsibilityAction responsibility : responsibilities) {
 382  0
                     if ( LOG.isDebugEnabled() ) {
 383  0
                             LOG.debug( "Processing Responsibility for action request: " + responsibility );
 384  
                     }
 385  
                 // KFSMI-2381 - pull information from KIM to populate annotation
 386  0
                     annotation.setLength( 0 );
 387  0
                     KimRoleInfo role = getRoleManagementService().getRole(responsibility.getRoleId());
 388  0
                     annotation.append( role.getNamespaceCode() ).append( ' ' ).append( role.getRoleName() ).append( ' ' );
 389  0
                     Attributes qualifier = responsibility.getQualifier();
 390  0
                     if ( qualifier != null ) {
 391  0
                             for ( String key : qualifier.toMap().keySet() ) {
 392  0
                                 annotation.append( qualifier.get( key ) ).append( ' ' );
 393  
                             }
 394  
                     }
 395  0
                         if (responsibility.getPrincipalId() != null) {
 396  0
                                 roleRecipient.setTarget(new KimPrincipalRecipient(responsibility.getPrincipalId()));
 397  0
                         } else if (responsibility.getGroupId() != null) {
 398  0
                                 roleRecipient.setTarget(new KimGroupRecipient(responsibility.getGroupId()));
 399  
                         } else {
 400  0
                                 throw new RiceRuntimeException("Failed to identify a group or principal on the given ResponsibilityResolutionInfo:" + responsibility);
 401  
                         }
 402  0
                         String annotationStr = annotation.toString();
 403  0
                         ActionRequestValue request = createActionRequest(
 404  
                                 responsibility.getActionTypeCode(), 
 405  
                                 responsibility.getPriorityNumber(), 
 406  
                                 roleRecipient, 
 407  
                                 responsibility.getParallelRoutingGroupingCode(), // description
 408  
                                 new Long(responsibility.getResponsibilityId()), 
 409  
                                 responsibility.isForceAction(), 
 410  
                                 // If not nested in a parent action request, ensure that the request
 411  
                                 // is first approve so delegations of this request do not require 
 412  
                                 // ALL_APPROVE as well
 413  
                                 (responsibilities.size() == 1)?KEWConstants.APPROVE_POLICY_FIRST_APPROVE:approvePolicy, 
 414  
                                 null, // ruleId
 415  
                                 annotationStr);
 416  
                         // if there is only a single request, don't create the nesting structure
 417  0
                         if ( responsibilities.size() > 1 ) {
 418  0
                                 request.setParentActionRequest(requestGraph);
 419  0
                                 requestGraph.getChildrenRequests().add(request);
 420  0
                                 generateRoleResponsibilityDelegationRequests(responsibility, request);
 421  0
                                 if ( !uniqueChildAnnotations.contains(annotationStr) ) {
 422  0
                                         parentAnnotation.append( annotationStr ).append( " -- " );
 423  0
                                         uniqueChildAnnotations.add(annotationStr);
 424  
                                 }
 425  
                         } else {
 426  0
                                 requestGraphs.add(request);
 427  0
                                 generateRoleResponsibilityDelegationRequests(responsibility, request);
 428  
                         }
 429  0
             }
 430  0
             if ( responsibilities.size() > 1 ) {
 431  0
                     requestGraph.setAnnotation( StringUtils.chomp( parentAnnotation.toString(), " -- " ) );
 432  
             }
 433  0
     }
 434  
 
 435  
     private void generateRoleResponsibilityDelegationRequests(ResponsibilityAction responsibility, ActionRequestValue parentRequest) {
 436  0
             List<Delegate> delegates = responsibility.getDelegates();
 437  0
             for (Delegate delegate : delegates) {
 438  0
                     Recipient recipient = null;
 439  0
                     boolean isPrincipal = delegate.getMemberTypeCode().equals(Role.PRINCIPAL_MEMBER_TYPE);
 440  0
             boolean isGroup = delegate.getMemberTypeCode().equals(Role.GROUP_MEMBER_TYPE);
 441  0
                     if (isPrincipal) {
 442  0
                             recipient = new KimPrincipalRecipient(delegate.getMemberId());
 443  0
                     } else if (isGroup) {
 444  0
                             recipient = new KimGroupRecipient(delegate.getMemberId());
 445  
                     } else {
 446  0
                             throw new RiceRuntimeException("Invalid DelegateInfo memberTypeCode encountered, was '" + delegate.getMemberTypeCode() + "'");
 447  
                     }
 448  0
                     String delegationAnnotation = generateRoleResponsibilityDelegateAnnotation(delegate, isPrincipal, isGroup, parentRequest);
 449  0
                     addDelegationRequest(parentRequest, recipient, new Long(delegate.getDelegationId()), parentRequest.getForceAction(), delegate.getDelegationTypeCode(), delegationAnnotation, null);
 450  0
             }
 451  0
     }
 452  
 
 453  
     private String generateRoleResponsibilityDelegateAnnotation(Delegate delegate, boolean isPrincipal, boolean isGroup, ActionRequestValue parentRequest) {
 454  0
             StringBuffer annotation = new StringBuffer( "Delegation of: " );
 455  0
             annotation.append( parentRequest.getAnnotation() );
 456  0
             annotation.append( " to " );
 457  0
             if (isPrincipal) {
 458  0
                     annotation.append( "principal " );
 459  0
                     Principal principal = getIdentityManagementService().getPrincipal( delegate.getMemberId() );
 460  0
                     if ( principal != null ) {
 461  0
                             annotation.append( principal.getPrincipalName() );
 462  
                     } else {
 463  0
                             annotation.append( delegate.getMemberId() );
 464  
                     }
 465  0
             } else if (isGroup) {
 466  0
                     annotation.append( "group " );
 467  0
                     Group group = getIdentityManagementService().getGroup( delegate.getMemberId() );
 468  0
                     if ( group != null ) {
 469  0
                             annotation.append( group.getNamespaceCode() ).append( '/' ).append( group.getName() );
 470  
                     } else {
 471  0
                             annotation.append( delegate.getMemberId() );
 472  
                     }
 473  0
             } else {
 474  0
                     annotation.append( "?????? '" );
 475  0
                         annotation.append( delegate.getMemberId() );
 476  0
                     annotation.append( "'" );
 477  
             }
 478  0
             return annotation.toString();
 479  
     }
 480  
 
 481  
     public ActionRequestValue addDelegationRoleRequest(ActionRequestValue parentRequest, String approvePolicy, RoleRecipient role, Long responsibilityId, Boolean forceAction, String delegationType, String description, Long ruleId) {
 482  0
             Recipient parentRecipient = parentRequest.getRecipient();
 483  0
             if (parentRecipient instanceof RoleRecipient) {
 484  0
                     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");
 485  
             }
 486  0
             if (! relatedToRoot(parentRequest)) {
 487  0
                     throw new WorkflowRuntimeException("The parent request is not related to any request managed by this factory");
 488  
             }
 489  0
             ActionRequestValue delegationRoleRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
 490  0
             delegationRoleRequest.setDelegationType(delegationType);
 491  0
             int count = 0;
 492  0
             for (Iterator<Id> iter = role.getResolvedQualifiedRole().getRecipients().iterator(); iter.hasNext(); count++) {
 493  
                     //repeat of createRoleRequest code
 494  0
                     Id recipientId = iter.next();
 495  0
                     if (recipientId.isEmpty()) {
 496  0
                                 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.");
 497  
                         }
 498  0
                         if (recipientId instanceof UserId) {
 499  0
                                 role.setTarget(new KimPrincipalRecipient(getIdentityHelperService().getPrincipal((UserId) recipientId)));
 500  0
                         } else if (recipientId instanceof GroupId) {
 501  0
                             role.setTarget(new KimGroupRecipient(getIdentityHelperService().getGroup((GroupId) recipientId)));
 502  
                         } else {
 503  0
                                 throw new WorkflowRuntimeException("Could not process the given type of id: " + recipientId.getClass());
 504  
                         }
 505  0
                         ActionRequestValue request = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), role, description, responsibilityId, forceAction, null, ruleId, null);
 506  0
                         request.setDelegationType(delegationType);
 507  
                         //end repeat
 508  0
                         request.setParentActionRequest(delegationRoleRequest);
 509  0
                         delegationRoleRequest.getChildrenRequests().add(request);
 510  
             }
 511  
 
 512  
             //put this mini graph in the larger graph
 513  0
             if (count > 0) {
 514  0
                     parentRequest.getChildrenRequests().add(delegationRoleRequest);
 515  0
                     delegationRoleRequest.setParentActionRequest(parentRequest);
 516  
             }
 517  
 
 518  0
             return delegationRoleRequest;
 519  
     }
 520  
 
 521  
     public ActionRequestValue addDelegationRequest(ActionRequestValue parentRequest, Recipient recipient, Long responsibilityId, Boolean forceAction, String delegationType, String annotation, Long ruleId) {
 522  0
             if (! relatedToRoot(parentRequest)) {
 523  0
                     throw new WorkflowRuntimeException("The parent request is not related to any request managed by this factory");
 524  
             }
 525  0
             ActionRequestValue delegationRequest = createActionRequest(parentRequest.getActionRequested(), parentRequest.getPriority(), recipient, parentRequest.getResponsibilityDesc(), responsibilityId, forceAction, null, ruleId, annotation);
 526  0
             delegationRequest.setDelegationType(delegationType);
 527  
             
 528  0
         parentRequest.getChildrenRequests().add(delegationRequest); 
 529  0
         delegationRequest.setParentActionRequest(parentRequest);
 530  
 
 531  0
             return delegationRequest;
 532  
     }
 533  
 
 534  
     //could probably base behavior off of recipient type
 535  
     public ActionRequestValue addRootActionRequest(String actionRequested, Integer priority, Recipient recipient, String description, Long responsibilityId, Boolean forceAction, String approvePolicy, Long ruleId) {
 536  0
             ActionRequestValue requestGraph = createActionRequest(actionRequested, priority, recipient, description, responsibilityId, forceAction, approvePolicy, ruleId, null);
 537  0
             requestGraphs.add(requestGraph);
 538  0
             return requestGraph;
 539  
     }
 540  
 
 541  
 
 542  
 
 543  
     //return true if requestGraph (root) is in this requests' parents
 544  
     public boolean relatedToRoot(ActionRequestValue request) {
 545  0
             int i = 0;
 546  0
             while(i < 3) {
 547  0
                     if (requestGraphs.contains(request)) {
 548  0
                             return true;
 549  0
                     } else if (request == null) {
 550  0
                             return false;
 551  
                     }
 552  0
                     i++;
 553  0
                     request = request.getParentActionRequest();
 554  
             }
 555  0
             return false;
 556  
     }
 557  
 
 558  
         public List<ActionRequestValue> getRequestGraphs() {
 559  
                 //clean up all the trailing role requests with no children -
 560  0
                 requestGraphs.removeAll(cleanUpChildren(requestGraphs));
 561  0
                 return requestGraphs;
 562  
         }
 563  
 
 564  
         private Collection<ActionRequestValue> cleanUpChildren(Collection<ActionRequestValue> children) {
 565  0
                 Collection<ActionRequestValue> requestsToRemove = new ArrayList<ActionRequestValue>();
 566  0
         for (ActionRequestValue aChildren : children)
 567  
         {
 568  
 
 569  0
             if (aChildren.isRoleRequest())
 570  
             {
 571  0
                 if (aChildren.getChildrenRequests().isEmpty())
 572  
                 {
 573  0
                     requestsToRemove.add(aChildren);
 574  
                 } else
 575  
                 {
 576  0
                     Collection<ActionRequestValue> childRequestsToRemove = cleanUpChildren(aChildren.getChildrenRequests());
 577  0
                     aChildren.getChildrenRequests().removeAll(childRequestsToRemove);
 578  0
                                 }
 579  
                         }                                                                                 
 580  
                 }
 581  0
                 return requestsToRemove;
 582  
         }
 583  
 
 584  
     private String generateNotificationAnnotation(PrincipalContract principal, String notificationRequestCode, String actionTakenCode, ActionRequestValue request) {
 585  0
             String notification = "Action " + CodeTranslator.getActionRequestLabel(notificationRequestCode) + " generated by Workflow because " + principal.getPrincipalName() + " took action "
 586  
                                 + CodeTranslator.getActionTakenLabel(actionTakenCode);
 587  0
             if (request.getResponsibilityId() != null && request.getResponsibilityId() != 0) {
 588  0
                     notification += " Responsibility " + request.getResponsibilityId();
 589  
             }
 590  0
             if (request.getRuleBaseValuesId() != null) {
 591  0
                     notification += " Rule Id " + request.getRuleBaseValuesId();
 592  
             }
 593  0
             if (request.getAnnotation() != null && request.getAnnotation().length()!=0){
 594  0
                     notification += " " + request.getAnnotation();
 595  
             }
 596  0
             return notification;
 597  
         }
 598  
 
 599  
     protected static ActionRequestService getActionRequestService() {
 600  0
                 if ( actionRequestService == null ) {
 601  0
                         actionRequestService = KEWServiceLocator.getActionRequestService();
 602  
                 }
 603  0
                 return actionRequestService;
 604  
     }
 605  
 
 606  
         /**
 607  
          * @return the roleManagementService
 608  
          */
 609  
     protected static RoleManagementService getRoleManagementService() {
 610  0
                 if ( roleManagementService == null ) {
 611  0
                         roleManagementService = KimApiServiceLocator.getRoleManagementService();
 612  
                 }
 613  0
                 return roleManagementService;
 614  
         }
 615  
 
 616  
         /**
 617  
          * @return the identityHelperService
 618  
          */
 619  
     protected static IdentityHelperService getIdentityHelperService() {
 620  0
                 if ( identityHelperService == null ) {
 621  0
                         identityHelperService = KEWServiceLocator.getIdentityHelperService();
 622  
                 }
 623  0
                 return identityHelperService;
 624  
         }
 625  
 
 626  
         /**
 627  
          * @return the identityManagementService
 628  
          */
 629  
     protected static IdentityManagementService getIdentityManagementService() {
 630  0
                 if ( identityManagementService == null ) {
 631  0
                         identityManagementService = KimApiServiceLocator.getIdentityManagementService();
 632  
                 }
 633  0
                 return identityManagementService;
 634  
         }
 635  
 
 636  
 }