001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kew.actionrequest.service.impl; 017 018 import java.util.ArrayList; 019 import java.util.Collection; 020 import java.util.Collections; 021 import java.util.HashMap; 022 import java.util.HashSet; 023 import java.util.Iterator; 024 import java.util.List; 025 import java.util.Map; 026 import java.util.Set; 027 028 import org.apache.commons.lang.ObjectUtils; 029 import org.apache.commons.lang.StringUtils; 030 import org.apache.log4j.Logger; 031 import org.kuali.rice.core.api.config.CoreConfigHelper; 032 import org.kuali.rice.core.api.exception.RiceRuntimeException; 033 import org.kuali.rice.core.api.config.property.ConfigContext; 034 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; 035 import org.kuali.rice.kew.actionitem.ActionItem; 036 import org.kuali.rice.kew.actionlist.service.ActionListService; 037 import org.kuali.rice.kew.actionrequest.ActionRequestValue; 038 import org.kuali.rice.kew.actionrequest.Recipient; 039 import org.kuali.rice.kew.actionrequest.dao.ActionRequestDAO; 040 import org.kuali.rice.kew.actionrequest.service.ActionRequestService; 041 import org.kuali.rice.kew.api.document.DocumentRefreshQueue; 042 import org.kuali.rice.kew.actiontaken.ActionTakenValue; 043 import org.kuali.rice.kew.actiontaken.service.ActionTakenService; 044 import org.kuali.rice.kew.api.action.ActionRequestPolicy; 045 import org.kuali.rice.kew.api.action.ActionRequestStatus; 046 import org.kuali.rice.kew.api.action.RecipientType; 047 import org.kuali.rice.kew.doctype.bo.DocumentType; 048 import org.kuali.rice.kew.engine.ActivationContext; 049 import org.kuali.rice.kew.engine.node.RouteNodeInstance; 050 import org.kuali.rice.kew.exception.WorkflowServiceErrorException; 051 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl; 052 import org.kuali.rice.kew.messaging.MessageServiceNames; 053 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; 054 import org.kuali.rice.kew.routeheader.service.RouteHeaderService; 055 import org.kuali.rice.kew.routemodule.RouteModule; 056 import org.kuali.rice.kew.service.KEWServiceLocator; 057 import org.kuali.rice.kew.util.FutureRequestDocumentStateManager; 058 import org.kuali.rice.kew.api.KewApiConstants; 059 import org.kuali.rice.kew.util.PerformanceLogger; 060 import org.kuali.rice.kew.util.ResponsibleParty; 061 import org.kuali.rice.kim.api.identity.principal.Principal; 062 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 063 import org.kuali.rice.krad.util.KRADConstants; 064 065 066 /** 067 * Default implementation of the {@link ActionRequestService}. 068 * 069 * @author Kuali Rice Team (rice.collab@kuali.org) 070 */ 071 public class ActionRequestServiceImpl implements ActionRequestService { 072 private static final Logger LOG = Logger.getLogger(ActionRequestServiceImpl.class); 073 074 private ActionRequestDAO actionRequestDAO; 075 076 public ActionRequestValue findByActionRequestId(String actionRequestId) { 077 return getActionRequestDAO().getActionRequestByActionRequestId(actionRequestId); 078 } 079 080 public Map<String, String> getActionsRequested(DocumentRouteHeaderValue routeHeader, String principalId, boolean completeAndApproveTheSame) { 081 return getActionsRequested(principalId, routeHeader.getActionRequests(), completeAndApproveTheSame); 082 } 083 084 /** 085 * Returns a Map of actions that are requested for the given principalId in the given list of action requests. 086 * @param principalId 087 * @param actionRequests 088 * @param completeAndApproveTheSame 089 * @return 090 */ 091 protected Map<String, String> getActionsRequested(String principalId, List<ActionRequestValue> actionRequests, boolean completeAndApproveTheSame) { 092 Map<String, String> actionsRequested = new HashMap<String, String>(); 093 actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false"); 094 actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false"); 095 actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "false"); 096 actionsRequested.put(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, "false"); 097 String topActionRequested = KewApiConstants.ACTION_REQUEST_FYI_REQ; 098 for (ActionRequestValue actionRequest : actionRequests) { 099 // we are getting the full list of requests here, so no need to look at role requests, if we did this then 100 // we could get a "false positive" for "all approve" roles where only part of the request graph is marked 101 // as "done" 102 if (!RecipientType.ROLE.getCode().equals(actionRequest.getRecipientTypeCd()) && 103 actionRequest.isRecipientRoutedRequest(principalId) && actionRequest.isActive()) { 104 int actionRequestComparison = ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), topActionRequested, completeAndApproveTheSame); 105 if (actionRequest.isFYIRequest() && actionRequestComparison >= 0) { 106 actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "true"); 107 } else if (actionRequest.isAcknowledgeRequest() && actionRequestComparison >= 0) { 108 actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "true"); 109 actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false"); 110 topActionRequested = actionRequest.getActionRequested(); 111 } else if (actionRequest.isApproveRequest() && actionRequestComparison >= 0) { 112 actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "true"); 113 actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false"); 114 actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false"); 115 topActionRequested = actionRequest.getActionRequested(); 116 } else if (actionRequest.isCompleteRequst() && actionRequestComparison >= 0) { 117 actionsRequested.put(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, "true"); 118 actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "false"); 119 actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false"); 120 actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false"); 121 if (completeAndApproveTheSame) { 122 actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "true"); 123 } 124 topActionRequested = actionRequest.getActionRequested(); 125 } 126 } 127 } 128 return actionsRequested; 129 } 130 131 public ActionRequestValue initializeActionRequestGraph(ActionRequestValue actionRequest, 132 DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) { 133 if (actionRequest.getParentActionRequest() != null) { 134 LOG.warn("-->A non parent action request from doc " + document.getDocumentId()); 135 actionRequest = KEWServiceLocator.getActionRequestService().getRoot(actionRequest); 136 } 137 propagatePropertiesToRequestGraph(actionRequest, document, nodeInstance); 138 return actionRequest; 139 } 140 141 private void propagatePropertiesToRequestGraph(ActionRequestValue actionRequest, DocumentRouteHeaderValue document, 142 RouteNodeInstance nodeInstance) { 143 setPropertiesToRequest(actionRequest, document, nodeInstance); 144 for (ActionRequestValue actionRequestValue : actionRequest.getChildrenRequests()) 145 { 146 propagatePropertiesToRequestGraph(actionRequestValue, document, nodeInstance); 147 } 148 } 149 150 private void setPropertiesToRequest(ActionRequestValue actionRequest, DocumentRouteHeaderValue document, 151 RouteNodeInstance nodeInstance) { 152 actionRequest.setDocumentId(document.getDocumentId()); 153 actionRequest.setDocVersion(document.getDocVersion()); 154 actionRequest.setRouteLevel(document.getDocRouteLevel()); 155 actionRequest.setNodeInstance(nodeInstance); 156 actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode()); 157 } 158 159 160 161 public void activateRequests(Collection actionRequests) { 162 activateRequests(actionRequests, new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION)); 163 } 164 165 public void activateRequests(Collection actionRequests, boolean simulate) { 166 activateRequests(actionRequests, new ActivationContext(simulate)); 167 } 168 169 public void activateRequests(Collection actionRequests, ActivationContext activationContext) { 170 if (actionRequests == null) { 171 return; 172 } 173 PerformanceLogger performanceLogger = null; 174 if ( LOG.isInfoEnabled() ) { 175 performanceLogger = new PerformanceLogger(); 176 } 177 activationContext.setGeneratedActionItems(new ArrayList<ActionItem>()); 178 activateRequestsInternal(actionRequests, activationContext); 179 if (!activationContext.isSimulation()) { 180 KEWServiceLocator.getNotificationService().notify(ActionItem.to(activationContext.getGeneratedActionItems())); 181 } 182 if ( LOG.isInfoEnabled() ) { 183 performanceLogger.log("Time to " + (activationContext.isSimulation() ? "simulate activation of " : "activate ") 184 + actionRequests.size() + " action requests."); 185 } 186 if ( LOG.isDebugEnabled() ) { 187 LOG.debug("Generated " + activationContext.getGeneratedActionItems().size() + " action items."); 188 } 189 } 190 191 public void activateRequest(ActionRequestValue actionRequest) { 192 activateRequests(Collections.singletonList(actionRequest), new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION)); 193 } 194 195 public void activateRequest(ActionRequestValue actionRequest, boolean simulate) { 196 activateRequests(Collections.singletonList(actionRequest), new ActivationContext(simulate)); 197 } 198 199 public void activateRequest(ActionRequestValue actionRequest, ActivationContext activationContext) { 200 activateRequests(Collections.singletonList(actionRequest), activationContext); 201 } 202 203 public List activateRequestNoNotification(ActionRequestValue actionRequest, boolean simulate) { 204 return activateRequestNoNotification(actionRequest, new ActivationContext(simulate)); 205 } 206 207 public List activateRequestNoNotification(ActionRequestValue actionRequest, ActivationContext activationContext) { 208 activationContext.setGeneratedActionItems(new ArrayList<ActionItem>()); 209 activateRequestInternal(actionRequest, activationContext); 210 return activationContext.getGeneratedActionItems(); 211 } 212 213 /** 214 * Internal helper method for activating a Collection of action requests and their children. Maintains an accumulator 215 * for generated action items. 216 * @param actionRequests 217 * @param activationContext 218 */ 219 private void activateRequestsInternal(Collection actionRequests, ActivationContext activationContext) { 220 if (actionRequests == null) { 221 return; 222 } 223 List<?> actionRequestList = new ArrayList<Object>(actionRequests); 224 for (int i = 0; i < actionRequestList.size(); i++) { 225 activateRequestInternal((ActionRequestValue) actionRequestList.get(i), activationContext); 226 } 227 } 228 229 /** 230 * Internal helper method for activating a single action requests and it's children. Maintains an accumulator for 231 * generated action items. 232 */ 233 private void activateRequestInternal(ActionRequestValue actionRequest, ActivationContext activationContext) { 234 PerformanceLogger performanceLogger = null; 235 if ( LOG.isInfoEnabled() ) { 236 performanceLogger = new PerformanceLogger(); 237 } 238 if (actionRequest == null || actionRequest.isActive() || actionRequest.isDeactivated()) { 239 return; 240 } 241 processResponsibilityId(actionRequest); 242 if (deactivateOnActionAlreadyTaken(actionRequest, activationContext)) { 243 return; 244 } 245 if (deactivateOnInactiveGroup(actionRequest, activationContext)) { 246 return; 247 } 248 if (deactivateOnEmptyGroup(actionRequest, activationContext)) { 249 return; 250 } 251 actionRequest.setStatus(ActionRequestStatus.ACTIVATED.getCode()); 252 if (!activationContext.isSimulation()) { 253 saveActionRequest(actionRequest); 254 activationContext.getGeneratedActionItems().addAll(generateActionItems(actionRequest, activationContext)); 255 } 256 activateRequestsInternal(actionRequest.getChildrenRequests(), activationContext); 257 activateRequestInternal(actionRequest.getParentActionRequest(), activationContext); 258 if ( LOG.isInfoEnabled() ) { 259 if (activationContext.isSimulation()) { 260 performanceLogger.log("Time to simulate activation of request."); 261 } else { 262 performanceLogger.log("Time to activate action request with id " + actionRequest.getActionRequestId()); 263 } 264 } 265 } 266 267 /** 268 * Generates ActionItems for the given ActionRequest and returns the List of generated Action Items. 269 * 270 * @param actionRequest 271 * @param activationContext 272 * @return the List of generated ActionItems 273 */ 274 private List<ActionItem> generateActionItems(ActionRequestValue actionRequest, ActivationContext activationContext) { 275 if ( LOG.isDebugEnabled() ) { 276 LOG.debug("generating the action items for request " + actionRequest.getActionRequestId()); 277 } 278 List<ActionItem> actionItems = new ArrayList<ActionItem>(); 279 if (!actionRequest.isPrimaryDelegator()) { 280 if (actionRequest.isGroupRequest()) { 281 List<String> principalIds = KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId()); 282 actionItems.addAll(createActionItemsForPrincipals(actionRequest, principalIds)); 283 } else if (actionRequest.isUserRequest()) { 284 ActionItem actionItem = getActionListService().createActionItemForActionRequest(actionRequest); 285 actionItems.add(actionItem); 286 } 287 } 288 if (!activationContext.isSimulation()) { 289 for (ActionItem actionItem: actionItems) { 290 if ( LOG.isDebugEnabled() ) { 291 LOG.debug("Saving action item: " + actionItems); 292 } 293 getActionListService().saveActionItem(actionItem); 294 } 295 } else { 296 actionRequest.getSimulatedActionItems().addAll(actionItems); 297 } 298 return actionItems; 299 } 300 301 private List<ActionItem> createActionItemsForPrincipals(ActionRequestValue actionRequest, List<String> principalIds) { 302 List<ActionItem> actionItems = new ArrayList<ActionItem>(); 303 for (String principalId: principalIds) { 304 305 ActionItem actionItem = getActionListService().createActionItemForActionRequest(actionRequest); 306 actionItem.setPrincipalId(principalId); 307 actionItem.setRoleName(actionRequest.getQualifiedRoleName()); 308 309 //KULRICE-3307 Prevent workflow from attempting to activate requests for null principals 310 String ignoreUnknownPrincipalIdsValue = ConfigContext.getCurrentContextConfig().getProperty(KewApiConstants.WORKFLOW_ACTION_IGNORE_UNKOWN_PRINCIPAL_IDS); 311 boolean ignoreUnknownPrincipalIds = Boolean.parseBoolean(ignoreUnknownPrincipalIdsValue); 312 313 if(principalId==null && ignoreUnknownPrincipalIds) 314 { 315 LOG.warn("Ignoring action item with actionRequestID of " + actionRequest.getActionRequestId() + " due to null principalId."); 316 } 317 else 318 { 319 if(principalId==null) 320 { 321 IllegalArgumentException e = new IllegalArgumentException("Exception thrown when trying to add action item with null principalId"); 322 LOG.error(e); 323 throw e; 324 } 325 else 326 { 327 actionItems.add(actionItem); 328 } 329 } 330 } 331 return actionItems; 332 } 333 334 private void processResponsibilityId(ActionRequestValue actionRequest) { 335 if (actionRequest.getResolveResponsibility()) { 336 String responsibilityId = actionRequest.getResponsibilityId(); 337 try { 338 RouteModule routeModule = KEWServiceLocator.getRouteModuleService().findRouteModule(actionRequest); 339 if (responsibilityId != null && actionRequest.isRouteModuleRequest()) { 340 if ( LOG.isDebugEnabled() ) { 341 LOG.debug("Resolving responsibility id for action request id=" + actionRequest.getActionRequestId() 342 + " and responsibility id=" + actionRequest.getResponsibilityId()); 343 } 344 ResponsibleParty responsibleParty = routeModule.resolveResponsibilityId(actionRequest.getResponsibilityId()); 345 if (responsibleParty == null) { 346 return; 347 } 348 if (responsibleParty.getPrincipalId() != null) { 349 Principal user = KimApiServiceLocator.getIdentityService() 350 .getPrincipal(responsibleParty.getPrincipalId()); 351 actionRequest.setPrincipalId(user.getPrincipalId()); 352 } else if (responsibleParty.getGroupId() != null) { 353 actionRequest.setGroupId(responsibleParty.getGroupId()); 354 } else if (responsibleParty.getRoleName() != null) { 355 actionRequest.setRoleName(responsibleParty.getRoleName()); 356 } 357 } 358 } catch (Exception e) { 359 LOG.error("Exception thrown when trying to resolve responsibility id " + responsibilityId, e); 360 throw new RuntimeException(e); 361 } 362 } 363 } 364 365 protected boolean deactivateOnActionAlreadyTaken(ActionRequestValue actionRequestToActivate, 366 ActivationContext activationContext) { 367 368 FutureRequestDocumentStateManager futureRequestStateMngr = null; 369 370 if (actionRequestToActivate.isGroupRequest()) { 371 futureRequestStateMngr = new FutureRequestDocumentStateManager(actionRequestToActivate.getRouteHeader(), actionRequestToActivate.getGroup()); 372 } else if (actionRequestToActivate.isUserRequest()) { 373 futureRequestStateMngr = new FutureRequestDocumentStateManager(actionRequestToActivate.getRouteHeader(), actionRequestToActivate.getPrincipalId()); 374 } else { 375 return false; 376 } 377 378 if (futureRequestStateMngr.isReceiveFutureRequests()) { 379 return false; 380 } 381 if (!actionRequestToActivate.getForceAction() || futureRequestStateMngr.isDoNotReceiveFutureRequests()) { 382 ActionTakenValue previousActionTaken = null; 383 if (!activationContext.isSimulation()) { 384 previousActionTaken = getActionTakenService().getPreviousAction(actionRequestToActivate); 385 } else { 386 previousActionTaken = getActionTakenService().getPreviousAction(actionRequestToActivate, 387 activationContext.getSimulatedActionsTaken()); 388 } 389 if (previousActionTaken != null) { 390 if ( LOG.isDebugEnabled() ) { 391 LOG.debug("found a satisfying action taken so setting this request done. Action Request Id " 392 + actionRequestToActivate.getActionRequestId()); 393 } 394 // set up the delegation for an action taken if this is a delegate request and the delegate has 395 // already taken action. 396 if (!previousActionTaken.isForDelegator() && actionRequestToActivate.getParentActionRequest() != null) { 397 previousActionTaken.setDelegator(actionRequestToActivate.getParentActionRequest().getRecipient()); 398 if (!activationContext.isSimulation()) { 399 getActionTakenService().saveActionTaken(previousActionTaken); 400 } 401 } 402 deactivateRequest(previousActionTaken, actionRequestToActivate, null, activationContext); 403 return true; 404 } 405 } 406 if ( LOG.isDebugEnabled() ) { 407 LOG.debug("Forcing action for action request " + actionRequestToActivate.getActionRequestId()); 408 } 409 return false; 410 } 411 412 /** 413 * Checks if the action request which is being activated has a group with no members. If this is the case then it will immediately 414 * initiate de-activation on the request since a group with no members will result in no action items being generated so should be 415 * effectively skipped. 416 */ 417 protected boolean deactivateOnEmptyGroup(ActionRequestValue actionRequestToActivate, ActivationContext activationContext) { 418 if (actionRequestToActivate.isGroupRequest()) { 419 if (KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequestToActivate.getGroup().getId()).isEmpty()) { 420 deactivateRequest(null, actionRequestToActivate, null, activationContext); 421 return true; 422 } 423 } 424 return false; 425 } 426 427 /** 428 * Checks if the action request which is being activated is being assigned to an inactive group. If this is the case and if the FailOnInactiveGroup 429 * policy is set to false then it will immediately initiate de-activation on the request 430 */ 431 protected boolean deactivateOnInactiveGroup(ActionRequestValue actionRequestToActivate, ActivationContext activationContext) { 432 if (actionRequestToActivate.isGroupRequest()) { 433 if (!actionRequestToActivate.getGroup().isActive() && !actionRequestToActivate.getRouteHeader().getDocumentType().getFailOnInactiveGroup().getPolicyValue()) { 434 deactivateRequest(null, actionRequestToActivate, null, activationContext); 435 return true; 436 } 437 } 438 return false; 439 } 440 441 public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest) { 442 deactivateRequest(actionTaken, actionRequest, null, new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION)); 443 } 444 445 public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest, boolean simulate) { 446 deactivateRequest(actionTaken, actionRequest, null, new ActivationContext(simulate)); 447 } 448 449 public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest, 450 ActivationContext activationContext) { 451 deactivateRequest(actionTaken, actionRequest, null, activationContext); 452 } 453 454 public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests) { 455 deactivateRequests(actionTaken, actionRequests, null, 456 new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION)); 457 } 458 459 public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests, boolean simulate) { 460 deactivateRequests(actionTaken, actionRequests, null, new ActivationContext(simulate)); 461 } 462 463 public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests, ActivationContext activationContext) { 464 deactivateRequests(actionTaken, actionRequests, null, activationContext); 465 } 466 467 private void deactivateRequests(ActionTakenValue actionTaken, Collection actionRequests, 468 ActionRequestValue deactivationRequester, ActivationContext activationContext) { 469 if (actionRequests == null) { 470 return; 471 } 472 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) { 473 ActionRequestValue actionRequest = (ActionRequestValue) iterator.next(); 474 deactivateRequest(actionTaken, actionRequest, deactivationRequester, activationContext); 475 } 476 } 477 478 private void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest, 479 ActionRequestValue deactivationRequester, ActivationContext activationContext) { 480 if (actionRequest == null || actionRequest.isDeactivated() 481 || haltForAllApprove(actionRequest, deactivationRequester)) { 482 return; 483 } 484 actionRequest.setStatus(ActionRequestStatus.DONE.getCode()); 485 actionRequest.setActionTaken(actionTaken); 486 if (actionTaken != null) { 487 actionTaken.getActionRequests().add(actionRequest); 488 } 489 if (!activationContext.isSimulation()) { 490 getActionRequestDAO().saveActionRequest(actionRequest); 491 deleteActionItems(actionRequest); 492 } 493 deactivateRequests(actionTaken, actionRequest.getChildrenRequests(), actionRequest, activationContext); 494 deactivateRequest(actionTaken, actionRequest.getParentActionRequest(), actionRequest, activationContext); 495 } 496 497 /** 498 * Returns true if we are dealing with an 'All Approve' request, the requester of the deactivation is a child of the 499 * 'All Approve' request, and all of the children have not been deactivated. If all of the children are already 500 * deactivated or a non-child request initiated deactivation, then this method returns false. false otherwise. 501 * @param actionRequest 502 * @param deactivationRequester 503 * @return 504 */ 505 private boolean haltForAllApprove(ActionRequestValue actionRequest, ActionRequestValue deactivationRequester) { 506 if (ActionRequestPolicy.ALL.getCode().equals(actionRequest.getApprovePolicy()) 507 && actionRequest.hasChild(deactivationRequester)) { 508 boolean allDeactivated = true; 509 for (ActionRequestValue childRequest : actionRequest.getChildrenRequests()) 510 { 511 if (!(allDeactivated = childRequest.isDeactivated())) 512 { 513 return true; 514 } 515 } 516 } 517 return false; 518 } 519 520 public List<ActionRequestValue> getRootRequests(Collection<ActionRequestValue> actionRequests) { 521 Set<ActionRequestValue> unsavedRequests = new HashSet<ActionRequestValue>(); 522 Map<String, ActionRequestValue> requestMap = new HashMap<String, ActionRequestValue>(); 523 for (ActionRequestValue actionRequest1 : actionRequests) 524 { 525 ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1; 526 ActionRequestValue rootRequest = getRoot(actionRequest); 527 if (rootRequest.getActionRequestId() != null) 528 { 529 requestMap.put(rootRequest.getActionRequestId(), rootRequest); 530 } else 531 { 532 unsavedRequests.add(rootRequest); 533 } 534 } 535 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>(); 536 requests.addAll(requestMap.values()); 537 requests.addAll(unsavedRequests); 538 return requests; 539 } 540 541 public ActionRequestValue getRoot(ActionRequestValue actionRequest) { 542 if (actionRequest == null) { 543 return null; 544 } 545 if (actionRequest.getParentActionRequest() != null) { 546 return getRoot(actionRequest.getParentActionRequest()); 547 } 548 return actionRequest; 549 } 550 551 /** 552 * Returns all pending requests for a given routing identity 553 * @param documentId the id of the document header being routed 554 * @return a List of all pending ActionRequestValues for the document 555 */ 556 public List<ActionRequestValue> findAllPendingRequests(String documentId) { 557 ActionRequestDAO arDAO = getActionRequestDAO(); 558 List<ActionRequestValue> pendingArs = arDAO.findByStatusAndDocId(ActionRequestStatus.ACTIVATED.getCode(), documentId); 559 return pendingArs; 560 } 561 562 public List findAllValidRequests(String principalId, String documentId, String requestCode) { 563 ActionRequestDAO arDAO = getActionRequestDAO(); 564 Collection pendingArs = arDAO.findByStatusAndDocId(ActionRequestStatus.ACTIVATED.getCode(), documentId); 565 return findAllValidRequests(principalId, pendingArs, requestCode); 566 } 567 568 public List findAllValidRequests(String principalId, Collection actionRequests, String requestCode) { 569 List matchedArs = new ArrayList(); 570 List<String> arGroups = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId); 571 return filterActionRequestsByCode((List<ActionRequestValue>)actionRequests, principalId, arGroups, requestCode); 572 } 573 574 /** 575 * Filters action requests based on if they occur after the given requestCode, and if they relate to 576 * the given principal 577 * @param actionRequests the List of ActionRequestValues to filter 578 * @param principalId the id of the principal to find active requests for 579 * @param principalGroupIds List of group ids that the principal belongs to 580 * @param requestCode the request code for all ActionRequestValues to be after 581 * @return the filtered List of ActionRequestValues 582 */ 583 public List<ActionRequestValue> filterActionRequestsByCode(List<ActionRequestValue> actionRequests, String principalId, List<String> principalGroupIds, String requestCode) { 584 List<ActionRequestValue> filteredActionRequests = new ArrayList<ActionRequestValue>(); 585 586 List<String> arGroups = null; 587 for (ActionRequestValue ar : actionRequests) { 588 if (ActionRequestValue.compareActionCode(ar.getActionRequested(), requestCode, true) > 0) { 589 continue; 590 } 591 if (ar.isUserRequest() && principalId.equals(ar.getPrincipalId())) { 592 filteredActionRequests.add(ar); 593 } else if (ar.isGroupRequest() && principalGroupIds != null && !principalGroupIds.isEmpty()) { 594 for (String groupId : principalGroupIds) { 595 if (groupId.equals(ar.getGroupId())) { 596 filteredActionRequests.add(ar); 597 } 598 } 599 } 600 } 601 602 return filteredActionRequests; 603 } 604 605 public void updateActionRequestsForResponsibilityChange(Set<String> responsibilityIds) { 606 PerformanceLogger performanceLogger = null; 607 if ( LOG.isInfoEnabled() ) { 608 performanceLogger = new PerformanceLogger(); 609 } 610 Collection documentsAffected = getRouteHeaderService().findPendingByResponsibilityIds(responsibilityIds); 611 String cacheWaitValue = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_CACHE_REQUEUE_DELAY); 612 Long cacheWait = KewApiConstants.DEFAULT_CACHE_REQUEUE_WAIT_TIME; 613 if (!org.apache.commons.lang.StringUtils.isEmpty(cacheWaitValue)) { 614 try { 615 cacheWait = Long.valueOf(cacheWaitValue); 616 } catch (NumberFormatException e) { 617 LOG.warn("Cache wait time is not a valid number: " + cacheWaitValue); 618 } 619 } 620 if ( LOG.isInfoEnabled() ) { 621 LOG.info("Scheduling requeue of " + documentsAffected.size() + " documents, affected by " + responsibilityIds.size() 622 + " responsibility changes. Installing a processing wait time of " + cacheWait 623 + " milliseconds to avoid stale rule cache."); 624 } 625 for (Object aDocumentsAffected : documentsAffected) 626 { 627 String documentId = (String) aDocumentsAffected; 628 629 String applicationId = null; 630 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByDocumentId(documentId); 631 632 if (documentType != null) { 633 applicationId = documentType.getApplicationId(); 634 } 635 636 if (applicationId == null) 637 { 638 applicationId = CoreConfigHelper.getApplicationId(); 639 } 640 if(documentType.getRegenerateActionRequestsOnChange().getPolicyValue()) { 641 DocumentRefreshQueue documentRequeuer = MessageServiceNames.getDocumentRequeuerService(applicationId, 642 documentId, cacheWait); 643 documentRequeuer.refreshDocument(documentId); 644 } 645 } 646 if ( LOG.isInfoEnabled() ) { 647 performanceLogger.log("Time to updateActionRequestsForResponsibilityChange"); 648 } 649 } 650 651 /** 652 * Deletes an action request and all of its action items following the graph down through the action request's 653 * children. This method should be invoked on a top-level action request. 654 */ 655 public void deleteActionRequestGraph(ActionRequestValue actionRequest) { 656 deleteActionItems(actionRequest); 657 if (actionRequest.getActionTakenId() != null) { 658 ActionTakenValue actionTaken = getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId()); 659 660 if(actionTaken != null){//iu patch 661 getActionTakenService().delete(actionTaken); 662 }//iu patch 663 664 } 665 getActionRequestDAO().delete(actionRequest.getActionRequestId()); 666 for (ActionRequestValue child: actionRequest.getChildrenRequests()) { 667 deleteActionRequestGraph(child); 668 } 669 } 670 671 /** 672 * Deletes the action items for the action request 673 * @param actionRequest the action request whose action items to delete 674 */ 675 private void deleteActionItems(ActionRequestValue actionRequest) { 676 List<ActionItem> actionItems = actionRequest.getActionItems(); 677 if ( LOG.isDebugEnabled() ) { 678 LOG.debug("deleting " + actionItems.size() + " action items for action request: " + actionRequest); 679 } 680 for (ActionItem actionItem: actionItems) { 681 if ( LOG.isDebugEnabled() ) { 682 LOG.debug("deleting action item: " + actionItem); 683 } 684 getActionListService().deleteActionItem(actionItem); 685 } 686 } 687 688 689 public List<ActionRequestValue> findByDocumentIdIgnoreCurrentInd(String documentId) { 690 return getActionRequestDAO().findByDocumentIdIgnoreCurrentInd(documentId); 691 } 692 693 public List<ActionRequestValue> findAllActionRequestsByDocumentId(String documentId) { 694 return getActionRequestDAO().findAllByDocId(documentId); 695 } 696 697 public List<ActionRequestValue> findAllRootActionRequestsByDocumentId(String documentId) { 698 return getActionRequestDAO().findAllRootByDocId(documentId); 699 } 700 701 public List<ActionRequestValue> findPendingByActionRequestedAndDocId(String actionRequestedCd, String documentId) { 702 return getActionRequestDAO().findPendingByActionRequestedAndDocId(actionRequestedCd, documentId); 703 } 704 705 /** 706 * @see org.kuali.rice.kew.actionrequest.service.ActionRequestService#getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(java.lang.String, java.lang.String) 707 */ 708 public List<String> getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(String actionRequestedCd, String documentId) { 709 List<String> principalIds = new ArrayList<String>(); 710 List<ActionRequestValue> actionRequests = findPendingByActionRequestedAndDocId(actionRequestedCd, documentId); 711 for(ActionRequestValue actionRequest: actionRequests){ 712 if(actionRequest.isUserRequest()){ 713 principalIds.add(actionRequest.getPrincipalId()); 714 } else if(actionRequest.isGroupRequest()){ 715 principalIds.addAll( 716 KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId())); 717 } 718 } 719 return principalIds; 720 } 721 722 public List<ActionRequestValue> findPendingByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) { 723 return getActionRequestDAO().findPendingByDocIdAtOrBelowRouteLevel(documentId, routeLevel); 724 } 725 726 public List<ActionRequestValue> findPendingRootRequestsByDocId(String documentId) { 727 return getRootRequests(findPendingByDoc(documentId)); 728 } 729 730 public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) { 731 return getActionRequestDAO().findPendingRootRequestsByDocIdAtRouteNode(documentId, nodeInstanceId); 732 } 733 734 public List<ActionRequestValue> findRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) { 735 return getActionRequestDAO().findRootRequestsByDocIdAtRouteNode(documentId, nodeInstanceId); 736 } 737 738 public List<ActionRequestValue> findPendingRootRequestsByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) { 739 return getActionRequestDAO().findPendingRootRequestsByDocIdAtOrBelowRouteLevel(documentId, routeLevel); 740 } 741 742 public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteLevel(String documentId, Integer routeLevel) { 743 return getActionRequestDAO().findPendingRootRequestsByDocIdAtRouteLevel(documentId, routeLevel); 744 } 745 746 public List<ActionRequestValue> findPendingRootRequestsByDocumentType(String documentTypeId) { 747 return getActionRequestDAO().findPendingRootRequestsByDocumentType(documentTypeId); 748 } 749 750 public void saveActionRequest(ActionRequestValue actionRequest) { 751 if (actionRequest.isGroupRequest()) { 752 if (!actionRequest.getGroup().isActive() && actionRequest.getRouteHeader().getDocumentType().getFailOnInactiveGroup().getPolicyValue()) { 753 throw new RiceRuntimeException("Attempted to save an action request with an inactive group."); 754 } 755 } 756 getActionRequestDAO().saveActionRequest(actionRequest); 757 } 758 759 public List<ActionRequestValue> findPendingByDoc(String documentId) { 760 return getActionRequestDAO().findAllPendingByDocId(documentId); 761 } 762 763 public List<ActionRequestValue> findPendingByDocRequestCdRouteLevel(String documentId, String requestCode, Integer routeLevel) { 764 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>(); 765 for (Object object : getActionRequestDAO().findAllPendingByDocId(documentId)) 766 { 767 ActionRequestValue actionRequest = (ActionRequestValue) object; 768 if (ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), requestCode, true) > 0) 769 { 770 continue; 771 } 772 if (actionRequest.getRouteLevel().intValue() == routeLevel.intValue()) 773 { 774 requests.add(actionRequest); 775 } 776 } 777 return requests; 778 } 779 780 public List<ActionRequestValue> findPendingByDocRequestCdNodeName(String documentId, String requestCode, String nodeName) { 781 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>(); 782 for (Object object : getActionRequestDAO().findAllPendingByDocId(documentId)) 783 { 784 ActionRequestValue actionRequest = (ActionRequestValue) object; 785 if (ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), requestCode, true) > 0) 786 { 787 continue; 788 } 789 if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getName().equals(nodeName)) 790 { 791 requests.add(actionRequest); 792 } 793 } 794 return requests; 795 } 796 797 public List findActivatedByGroup(String groupId) { 798 return getActionRequestDAO().findActivatedByGroup(groupId); 799 } 800 801 private ActionListService getActionListService() { 802 return (ActionListService) KEWServiceLocator.getActionListService(); 803 } 804 805 private ActionTakenService getActionTakenService() { 806 return (ActionTakenService) KEWServiceLocator.getActionTakenService(); 807 } 808 809 public ActionRequestDAO getActionRequestDAO() { 810 return actionRequestDAO; 811 } 812 813 public void setActionRequestDAO(ActionRequestDAO actionRequestDAO) { 814 this.actionRequestDAO = actionRequestDAO; 815 } 816 817 private RouteHeaderService getRouteHeaderService() { 818 return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV); 819 } 820 821 public List<ActionRequestValue> findByStatusAndDocId(String statusCd, String documentId) { 822 return getActionRequestDAO().findByStatusAndDocId(statusCd, documentId); 823 } 824 825 public void alterActionRequested(List actionRequests, String actionRequestCd) { 826 for (Object actionRequest1 : actionRequests) 827 { 828 ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1; 829 830 actionRequest.setActionRequested(actionRequestCd); 831 for (ActionItem item : actionRequest.getActionItems()) 832 { 833 item.setActionRequestCd(actionRequestCd); 834 } 835 836 saveActionRequest(actionRequest); 837 } 838 } 839 840 // TODO this still won't work in certain cases when checking from the root 841 public boolean isDuplicateRequest(ActionRequestValue actionRequest) { 842 List<ActionRequestValue> requests = findAllRootActionRequestsByDocumentId(actionRequest.getDocumentId()); 843 for (ActionRequestValue existingRequest : requests) { 844 if (existingRequest.getStatus().equals(ActionRequestStatus.DONE.getCode()) 845 && existingRequest.getRouteLevel().equals(actionRequest.getRouteLevel()) 846 && ObjectUtils.equals(existingRequest.getPrincipalId(), actionRequest.getPrincipalId()) 847 && ObjectUtils.equals(existingRequest.getGroupId(), actionRequest.getGroupId()) 848 && ObjectUtils.equals(existingRequest.getRoleName(), actionRequest.getRoleName()) 849 && ObjectUtils.equals(existingRequest.getQualifiedRoleName(), actionRequest.getQualifiedRoleName()) 850 && existingRequest.getActionRequested().equals(actionRequest.getActionRequested())) { 851 return true; 852 } 853 } 854 return false; 855 } 856 857 public Recipient findDelegator(List actionRequests) { 858 Recipient delegator = null; 859 String requestCode = KewApiConstants.ACTION_REQUEST_FYI_REQ; 860 for (Object actionRequest1 : actionRequests) 861 { 862 ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1; 863 ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest); 864 if (delegatorRequest != null) 865 { 866 if (ActionRequestValue.compareActionCode(delegatorRequest.getActionRequested(), requestCode, true) >= 0) 867 { 868 delegator = delegatorRequest.getRecipient(); 869 requestCode = delegatorRequest.getActionRequested(); 870 } 871 } 872 } 873 return delegator; 874 } 875 876 public Recipient findDelegator(ActionRequestValue actionRequest) { 877 ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest); 878 Recipient delegator = null; 879 if (delegatorRequest != null) { 880 delegator = delegatorRequest.getRecipient(); 881 } 882 return delegator; 883 } 884 885 public ActionRequestValue findDelegatorRequest(ActionRequestValue actionRequest) { 886 ActionRequestValue parentRequest = actionRequest.getParentActionRequest(); 887 if (parentRequest != null && !(parentRequest.isUserRequest() || parentRequest.isGroupRequest())) { 888 parentRequest = findDelegatorRequest(parentRequest); 889 } 890 return parentRequest; 891 } 892 893 public void deleteByDocumentId(String documentId) { 894 actionRequestDAO.deleteByDocumentId(documentId); 895 } 896 897 public void deleteByActionRequestId(String actionRequestId) { 898 actionRequestDAO.delete(actionRequestId); 899 } 900 901 public void validateActionRequest(ActionRequestValue actionRequest) { 902 LOG.debug("Enter validateActionRequest(..)"); 903 List<WorkflowServiceErrorImpl> errors = new ArrayList<WorkflowServiceErrorImpl>(); 904 905 String actionRequestCd = actionRequest.getActionRequested(); 906 if (actionRequestCd == null || actionRequestCd.trim().equals("")) { 907 errors.add(new WorkflowServiceErrorImpl("ActionRequest cd null.", "actionrequest.actionrequestcd.empty", 908 actionRequest.getActionRequestId().toString())); 909 } else if (!KewApiConstants.ACTION_REQUEST_CD.containsKey(actionRequestCd)) { 910 errors.add(new WorkflowServiceErrorImpl("ActionRequest cd invalid.", "actionrequest.actionrequestcd.invalid", 911 actionRequest.getActionRequestId().toString())); 912 } 913 914 String documentId = actionRequest.getDocumentId(); 915 if (documentId == null || StringUtils.isEmpty(documentId)) { 916 errors.add(new WorkflowServiceErrorImpl("ActionRequest Document id empty.", "actionrequest.documentid.empty", 917 actionRequest.getActionRequestId().toString())); 918 } else if (getRouteHeaderService().getRouteHeader(documentId) == null) { 919 errors.add(new WorkflowServiceErrorImpl("ActionRequest Document id invalid.", 920 "actionrequest.documentid.invalid", actionRequest.getActionRequestId().toString())); 921 } 922 923 String actionRequestStatus = actionRequest.getStatus(); 924 if (actionRequestStatus == null || actionRequestStatus.trim().equals("")) { 925 errors.add(new WorkflowServiceErrorImpl("ActionRequest status null.", "actionrequest.actionrequeststatus.empty", 926 actionRequest.getActionRequestId().toString())); 927 } else if (ActionRequestStatus.fromCode(actionRequestStatus) == null) { 928 errors.add(new WorkflowServiceErrorImpl("ActionRequest status invalid.", 929 "actionrequest.actionrequeststatus.invalid", actionRequest.getActionRequestId().toString())); 930 } 931 932 if (actionRequest.getResponsibilityId() == null) { 933 errors.add(new WorkflowServiceErrorImpl("ActionRequest responsibility id null.", 934 "actionrequest.responsibilityid.empty", actionRequest.getActionRequestId().toString())); 935 } 936 937 Integer priority = actionRequest.getPriority(); 938 if (priority == null) { 939 errors.add(new WorkflowServiceErrorImpl("ActionRequest priority null.", "actionrequest.priority.empty", 940 actionRequest.getActionRequestId().toString())); 941 } 942 943 // if(actionRequest.getRouteMethodName() == null || actionRequest.getRouteMethodName().trim().equals("")){ 944 // errors.add(new WorkflowServiceErrorImpl("ActionRequest route method name null.", 945 // "actionrequest.routemethodname.empty", actionRequest.getActionRequestId().toString())); 946 // } 947 948 Integer routeLevel = actionRequest.getRouteLevel(); 949 if (routeLevel == null) { 950 errors.add(new WorkflowServiceErrorImpl("ActionRequest route level null.", "actionrequest.routelevel.empty", 951 actionRequest.getActionRequestId().toString())); 952 } else if (routeLevel < -1) { 953 errors.add(new WorkflowServiceErrorImpl("ActionRequest route level invalid.", 954 "actionrequest.routelevel.invalid", actionRequest.getActionRequestId().toString())); 955 } 956 957 Integer version = actionRequest.getDocVersion(); 958 if (version == null) { 959 errors.add(new WorkflowServiceErrorImpl("ActionRequest doc version null.", "actionrequest.docversion.empty", 960 actionRequest.getActionRequestId().toString())); 961 } 962 963 if (actionRequest.getCreateDate() == null) { 964 errors.add(new WorkflowServiceErrorImpl("ActionRequest create date null.", "actionrequest.createdate.empty", 965 actionRequest.getActionRequestId().toString())); 966 } 967 968 String recipientType = actionRequest.getRecipientTypeCd(); 969 if (recipientType != null && !recipientType.trim().equals("")) { 970 if (recipientType.equals(KewApiConstants.WORKGROUP)) { 971 String workgroupId = actionRequest.getGroupId(); 972 if (workgroupId == null) { 973 errors.add(new WorkflowServiceErrorImpl("ActionRequest workgroup null.", 974 "actionrequest.workgroup.empty", actionRequest.getActionRequestId().toString())); 975 } else if (KimApiServiceLocator.getGroupService().getGroup(workgroupId) == null) { 976 errors.add(new WorkflowServiceErrorImpl("ActionRequest workgroup invalid.", 977 "actionrequest.workgroup.invalid", actionRequest.getActionRequestId().toString())); 978 } 979 980 } 981 if (recipientType.equals(KewApiConstants.PERSON)) { 982 String principalId = actionRequest.getPrincipalId(); 983 if (principalId == null || principalId.trim().equals("")) { 984 errors.add(new WorkflowServiceErrorImpl("ActionRequest person id null.", "actionrequest.persosn.empty", 985 actionRequest.getActionRequestId().toString())); 986 } else { 987 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId); 988 if (principal == null) { 989 errors.add(new WorkflowServiceErrorImpl("ActionRequest person id invalid.", 990 "actionrequest.personid.invalid", actionRequest.getActionRequestId().toString())); 991 } 992 } 993 994 if (recipientType.equals(KewApiConstants.ROLE) 995 && (actionRequest.getRoleName() == null || actionRequest.getRoleName().trim().equals(""))) { 996 errors.add(new WorkflowServiceErrorImpl("ActionRequest role name null.", "actionrequest.rolename.null", 997 actionRequest.getActionRequestId().toString())); 998 } 999 } 1000 LOG.debug("Exit validateActionRequest(..) "); 1001 if (!errors.isEmpty()) { 1002 throw new WorkflowServiceErrorException("ActionRequest Validation Error", errors); 1003 } 1004 } 1005 } 1006 1007 public List getDelegateRequests(ActionRequestValue actionRequest) { 1008 List<ActionRequestValue> delegateRequests = new ArrayList<ActionRequestValue>(); 1009 List requests = getTopLevelRequests(actionRequest); 1010 for (Object request : requests) 1011 { 1012 ActionRequestValue parentActionRequest = (ActionRequestValue) request; 1013 delegateRequests.addAll(parentActionRequest.getChildrenRequests()); 1014 } 1015 return delegateRequests; 1016 } 1017 1018 public List getTopLevelRequests(ActionRequestValue actionRequest) { 1019 List<ActionRequestValue> topLevelRequests = new ArrayList<ActionRequestValue>(); 1020 if (actionRequest.isRoleRequest()) { 1021 topLevelRequests.addAll(actionRequest.getChildrenRequests()); 1022 } else { 1023 topLevelRequests.add(actionRequest); 1024 } 1025 return topLevelRequests; 1026 } 1027 1028 public boolean isValidActionRequestCode(String actionRequestCode) { 1029 return actionRequestCode != null && KewApiConstants.ACTION_REQUEST_CODES.containsKey(actionRequestCode); 1030 } 1031 1032 public boolean doesPrincipalHaveRequest(String principalId, String documentId) { 1033 if (getActionRequestDAO().doesDocumentHaveUserRequest(principalId, documentId)) { 1034 return true; 1035 } 1036 // TODO since we only store the workgroup id for workgroup requests, if the user is in a workgroup that has a request 1037 // than we need get all the requests with workgroup ids and see if our user is in that group 1038 List<String> groupIds = getActionRequestDAO().getRequestGroupIds(documentId); 1039 for (String groupId : groupIds) { 1040 if (KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, groupId)) { 1041 return true; 1042 } 1043 } 1044 return false; 1045 } 1046 1047 }