0001: /*
0002: * Copyright 2005-2006 The Kuali Foundation.
0003: *
0004: *
0005: * Licensed under the Educational Community License, Version 1.0 (the "License");
0006: * you may not use this file except in compliance with the License.
0007: * You may obtain a copy of the License at
0008: *
0009: * http://www.opensource.org/licenses/ecl1.php
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package edu.iu.uis.eden.actionrequests;
0018:
0019: import java.util.ArrayList;
0020: import java.util.Collection;
0021: import java.util.HashMap;
0022: import java.util.HashSet;
0023: import java.util.Iterator;
0024: import java.util.List;
0025: import java.util.Map;
0026: import java.util.Set;
0027:
0028: import org.apache.commons.lang.ObjectUtils;
0029: import org.kuali.rice.core.Core;
0030:
0031: import edu.iu.uis.eden.EdenConstants;
0032: import edu.iu.uis.eden.KEWServiceLocator;
0033: import edu.iu.uis.eden.WorkflowServiceErrorException;
0034: import edu.iu.uis.eden.WorkflowServiceErrorImpl;
0035: import edu.iu.uis.eden.actionitem.ActionItem;
0036: import edu.iu.uis.eden.actionlist.ActionListService;
0037: import edu.iu.uis.eden.actionrequests.dao.ActionRequestDAO;
0038: import edu.iu.uis.eden.actiontaken.ActionTakenService;
0039: import edu.iu.uis.eden.actiontaken.ActionTakenValue;
0040: import edu.iu.uis.eden.engine.ActivationContext;
0041: import edu.iu.uis.eden.engine.node.RouteNodeInstance;
0042: import edu.iu.uis.eden.exception.EdenUserNotFoundException;
0043: import edu.iu.uis.eden.messaging.MessageQueueService;
0044: import edu.iu.uis.eden.messaging.MessageServiceNames;
0045: import edu.iu.uis.eden.routeheader.DocumentRouteHeaderValue;
0046: import edu.iu.uis.eden.routeheader.RouteHeaderService;
0047: import edu.iu.uis.eden.routemodule.RouteModule;
0048: import edu.iu.uis.eden.user.Recipient;
0049: import edu.iu.uis.eden.user.UserService;
0050: import edu.iu.uis.eden.user.WorkflowUser;
0051: import edu.iu.uis.eden.user.WorkflowUserId;
0052: import edu.iu.uis.eden.util.PerformanceLogger;
0053: import edu.iu.uis.eden.util.ResponsibleParty;
0054: import edu.iu.uis.eden.util.Utilities;
0055: import edu.iu.uis.eden.workgroup.WorkflowGroupId;
0056: import edu.iu.uis.eden.workgroup.Workgroup;
0057: import edu.iu.uis.eden.workgroup.WorkgroupService;
0058:
0059: /**
0060: * Default implementation of the {@link ActionRequestService}.
0061: *
0062: * @author ewestfal
0063: * @author rkirkend
0064: */
0065: public class ActionRequestServiceImpl implements ActionRequestService {
0066:
0067: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
0068: .getLogger(ActionRequestServiceImpl.class);
0069:
0070: private ActionRequestDAO actionRequestDAO;
0071:
0072: public ActionRequestValue findByActionRequestId(Long actionRequestId) {
0073: return getActionRequestDAO().getActionRequestByActionRequestId(
0074: actionRequestId);
0075: }
0076:
0077: public ActionRequestValue initializeActionRequestGraph(
0078: ActionRequestValue actionRequest,
0079: DocumentRouteHeaderValue document,
0080: RouteNodeInstance nodeInstance) {
0081: if (actionRequest.getParentActionRequest() != null) {
0082: LOG.warn("-->A non parent action request from doc "
0083: + document.getRouteHeaderId());
0084: actionRequest = KEWServiceLocator.getActionRequestService()
0085: .getRoot(actionRequest);
0086: }
0087: propagatePropertiesToRequestGraph(actionRequest, document,
0088: nodeInstance);
0089: return actionRequest;
0090: }
0091:
0092: private void propagatePropertiesToRequestGraph(
0093: ActionRequestValue actionRequest,
0094: DocumentRouteHeaderValue document,
0095: RouteNodeInstance nodeInstance) {
0096: setPropertiesToRequest(actionRequest, document, nodeInstance);
0097: for (Iterator iterator = actionRequest.getChildrenRequests()
0098: .iterator(); iterator.hasNext();) {
0099: propagatePropertiesToRequestGraph(
0100: (ActionRequestValue) iterator.next(), document,
0101: nodeInstance);
0102: }
0103: }
0104:
0105: private void setPropertiesToRequest(
0106: ActionRequestValue actionRequest,
0107: DocumentRouteHeaderValue document,
0108: RouteNodeInstance nodeInstance) {
0109: actionRequest.setRouteHeaderId(document.getRouteHeaderId());
0110: actionRequest.setDocVersion(document.getDocVersion());
0111: actionRequest.setRouteLevel(document.getDocRouteLevel());
0112: actionRequest.setNodeInstance(nodeInstance);
0113: actionRequest
0114: .setStatus(EdenConstants.ACTION_REQUEST_INITIALIZED);
0115: }
0116:
0117: public void activateRequests(Collection actionRequests)
0118: throws EdenUserNotFoundException {
0119: activateRequests(actionRequests, new ActivationContext(
0120: !ActivationContext.CONTEXT_IS_SIMULATION));
0121: }
0122:
0123: public void activateRequests(Collection actionRequests,
0124: boolean simulate) throws EdenUserNotFoundException {
0125: activateRequests(actionRequests,
0126: new ActivationContext(simulate));
0127: }
0128:
0129: public void activateRequests(Collection actionRequests,
0130: ActivationContext activationContext)
0131: throws EdenUserNotFoundException {
0132: if (actionRequests == null) {
0133: return;
0134: }
0135: PerformanceLogger performanceLogger = new PerformanceLogger();
0136: activationContext.setGeneratedActionItems(new ArrayList());
0137: activateRequestsInternal(actionRequests, activationContext);
0138: if (!activationContext.isSimulation()) {
0139: KEWServiceLocator.getNotificationService().notify(
0140: activationContext.getGeneratedActionItems());
0141: }
0142: performanceLogger
0143: .log("Time to "
0144: + (activationContext.isSimulation() ? "simulate activation of "
0145: : "activate ") + actionRequests.size()
0146: + " action requests.");
0147: LOG.debug("Generated "
0148: + activationContext.getGeneratedActionItems().size()
0149: + " action items.");
0150: }
0151:
0152: public void activateRequest(ActionRequestValue actionRequest)
0153: throws EdenUserNotFoundException {
0154: activateRequests(Utilities.asList(actionRequest),
0155: new ActivationContext(
0156: !ActivationContext.CONTEXT_IS_SIMULATION));
0157: }
0158:
0159: public void activateRequest(ActionRequestValue actionRequest,
0160: boolean simulate) throws EdenUserNotFoundException {
0161: activateRequests(Utilities.asList(actionRequest),
0162: new ActivationContext(simulate));
0163: }
0164:
0165: public void activateRequest(ActionRequestValue actionRequest,
0166: ActivationContext activationContext)
0167: throws EdenUserNotFoundException {
0168: activateRequests(Utilities.asList(actionRequest),
0169: activationContext);
0170: }
0171:
0172: public List activateRequestNoNotification(
0173: ActionRequestValue actionRequest, boolean simulate)
0174: throws EdenUserNotFoundException {
0175: return activateRequestNoNotification(actionRequest,
0176: new ActivationContext(simulate));
0177: }
0178:
0179: public List activateRequestNoNotification(
0180: ActionRequestValue actionRequest,
0181: ActivationContext activationContext)
0182: throws EdenUserNotFoundException {
0183: activationContext.setGeneratedActionItems(new ArrayList());
0184: activateRequestInternal(actionRequest, activationContext);
0185: return activationContext.getGeneratedActionItems();
0186: }
0187:
0188: /**
0189: * Internal helper method for activating a Collection of action requests and their children.
0190: * Maintains an accumulator for generated action items.
0191: */
0192: private void activateRequestsInternal(Collection actionRequests,
0193: ActivationContext activationContext)
0194: throws EdenUserNotFoundException {
0195: if (actionRequests == null) {
0196: return;
0197: }
0198: for (Iterator iterator = actionRequests.iterator(); iterator
0199: .hasNext();) {
0200: ActionRequestValue actionRequest = (ActionRequestValue) iterator
0201: .next();
0202: activateRequestInternal(actionRequest, activationContext);
0203: }
0204: }
0205:
0206: /**
0207: * Internal helper method for activating a single action requests and it's children.
0208: * Maintains an accumulator for generated action items.
0209: */
0210: private void activateRequestInternal(
0211: ActionRequestValue actionRequest,
0212: ActivationContext activationContext)
0213: throws EdenUserNotFoundException {
0214: PerformanceLogger performanceLogger = new PerformanceLogger();
0215: if (actionRequest == null || actionRequest.isActive()
0216: || actionRequest.isDeactivated()) {
0217: return;
0218: }
0219: processResponsibilityId(actionRequest);
0220: if (deactivateOnActionAlreadyTaken(actionRequest,
0221: activationContext)) {
0222: return;
0223: }
0224: actionRequest.setStatus(EdenConstants.ACTION_REQUEST_ACTIVATED);
0225: if (!activationContext.isSimulation()) {
0226: saveActionRequest(actionRequest);
0227: activationContext.getGeneratedActionItems().addAll(
0228: getActionListService().generateActionItems(
0229: actionRequest,
0230: activationContext.isSimulation()));
0231: }
0232: activateRequestsInternal(actionRequest.getChildrenRequests(),
0233: activationContext);
0234: activateRequestInternal(actionRequest.getParentActionRequest(),
0235: activationContext);
0236: if (activationContext.isSimulation()) {
0237: performanceLogger
0238: .log("Time to simulate activation of request.");
0239: } else {
0240: performanceLogger
0241: .log("Time to activate action request with id "
0242: + actionRequest.getActionRequestId());
0243: }
0244: }
0245:
0246: private void processResponsibilityId(
0247: ActionRequestValue actionRequest) {
0248: Long responsibilityId = actionRequest.getResponsibilityId();
0249: try {
0250: RouteModule routeModule = KEWServiceLocator
0251: .getRouteModuleService().findRouteModule(
0252: actionRequest);
0253: if (responsibilityId != null
0254: && actionRequest.isRouteModuleRequest()) {
0255: LOG
0256: .debug("Resolving responsibility id for action request id="
0257: + actionRequest.getActionRequestId()
0258: + " and responsibility id="
0259: + actionRequest.getResponsibilityId());
0260: ResponsibleParty responsibleParty = routeModule
0261: .resolveResponsibilityId(actionRequest
0262: .getResponsibilityId());
0263: if (responsibleParty == null) {
0264: return;
0265: }
0266: if (responsibleParty.getUserId() != null) {
0267: WorkflowUser user = getUserService()
0268: .getWorkflowUser(
0269: responsibleParty.getUserId());
0270: actionRequest.setWorkflowId(user
0271: .getWorkflowUserId().getWorkflowId());
0272: } else if (responsibleParty.getGroupId() != null) {
0273: Workgroup workgroup = getWorkgroupService()
0274: .getWorkgroup(responsibleParty.getGroupId());
0275: actionRequest.setWorkgroupId(workgroup
0276: .getWorkflowGroupId().getGroupId());
0277: } else if (responsibleParty.getRoleName() != null) {
0278: actionRequest.setRoleName(responsibleParty
0279: .getRoleName());
0280: }
0281: }
0282: } catch (Exception e) {
0283: LOG.error(
0284: "Exception thrown when trying to resolve responsibility id "
0285: + responsibilityId, e);
0286: throw new RuntimeException(e);
0287: }
0288: }
0289:
0290: private boolean deactivateOnActionAlreadyTaken(
0291: ActionRequestValue actionRequestToActivate,
0292: ActivationContext activationContext)
0293: throws EdenUserNotFoundException {
0294: if (!actionRequestToActivate.getIgnorePrevAction()
0295: .booleanValue()) {
0296: ActionTakenValue previousActionTaken = null;
0297: if (!activationContext.isSimulation()) {
0298: previousActionTaken = getActionTakenService()
0299: .getPreviousAction(actionRequestToActivate);
0300: } else {
0301: previousActionTaken = getActionTakenService()
0302: .getPreviousAction(
0303: actionRequestToActivate,
0304: activationContext
0305: .getSimulatedActionsTaken());
0306: }
0307: if (previousActionTaken != null) {
0308: LOG
0309: .debug("found a satisfying action taken so setting this request done. Action Request Id "
0310: + actionRequestToActivate
0311: .getActionRequestId());
0312: //set up the delegation for an action taken if this is a delegate request and the delegate has
0313: //already taken action.
0314: if (!previousActionTaken.isForDelegator()
0315: && actionRequestToActivate
0316: .getParentActionRequest() != null) {
0317: previousActionTaken
0318: .setDelegator(actionRequestToActivate
0319: .getParentActionRequest()
0320: .getRecipient());
0321: if (!activationContext.isSimulation()) {
0322: getActionTakenService().saveActionTaken(
0323: previousActionTaken);
0324: }
0325: }
0326: deactivateRequest(previousActionTaken,
0327: actionRequestToActivate, null,
0328: activationContext);
0329: return true;
0330: }
0331: }
0332: LOG.debug("Ignoring previous for action request "
0333: + actionRequestToActivate.getActionRequestId());
0334: return false;
0335: }
0336:
0337: public void deactivateRequest(ActionTakenValue actionTaken,
0338: ActionRequestValue actionRequest) {
0339: deactivateRequest(actionTaken, actionRequest, null,
0340: new ActivationContext(
0341: !ActivationContext.CONTEXT_IS_SIMULATION));
0342: }
0343:
0344: public void deactivateRequest(ActionTakenValue actionTaken,
0345: ActionRequestValue actionRequest, boolean simulate) {
0346: deactivateRequest(actionTaken, actionRequest, null,
0347: new ActivationContext(simulate));
0348: }
0349:
0350: public void deactivateRequest(ActionTakenValue actionTaken,
0351: ActionRequestValue actionRequest,
0352: ActivationContext activationContext) {
0353: deactivateRequest(actionTaken, actionRequest, null,
0354: activationContext);
0355: }
0356:
0357: public void deactivateRequests(ActionTakenValue actionTaken,
0358: List actionRequests) {
0359: deactivateRequests(actionTaken, actionRequests, null,
0360: new ActivationContext(
0361: !ActivationContext.CONTEXT_IS_SIMULATION));
0362: }
0363:
0364: public void deactivateRequests(ActionTakenValue actionTaken,
0365: List actionRequests, boolean simulate) {
0366: deactivateRequests(actionTaken, actionRequests, null,
0367: new ActivationContext(simulate));
0368: }
0369:
0370: public void deactivateRequests(ActionTakenValue actionTaken,
0371: List actionRequests, ActivationContext activationContext) {
0372: deactivateRequests(actionTaken, actionRequests, null,
0373: activationContext);
0374: }
0375:
0376: private void deactivateRequests(ActionTakenValue actionTaken,
0377: Collection actionRequests,
0378: ActionRequestValue deactivationRequester,
0379: ActivationContext activationContext) {
0380: if (actionRequests == null) {
0381: return;
0382: }
0383: for (Iterator iterator = actionRequests.iterator(); iterator
0384: .hasNext();) {
0385: ActionRequestValue actionRequest = (ActionRequestValue) iterator
0386: .next();
0387: deactivateRequest(actionTaken, actionRequest,
0388: deactivationRequester, activationContext);
0389: }
0390: }
0391:
0392: private void deactivateRequest(ActionTakenValue actionTaken,
0393: ActionRequestValue actionRequest,
0394: ActionRequestValue deactivationRequester,
0395: ActivationContext activationContext) {
0396: if (actionRequest == null
0397: || actionRequest.isDeactivated()
0398: || haltForAllApprove(actionRequest,
0399: deactivationRequester)) {
0400: return;
0401: }
0402: actionRequest
0403: .setStatus(EdenConstants.ACTION_REQUEST_DONE_STATE);
0404: actionRequest.setActionTaken(actionTaken);
0405: if (actionTaken != null) {
0406: actionTaken.getActionRequests().add(actionRequest);
0407: }
0408: if (!activationContext.isSimulation()) {
0409: getActionRequestDAO().saveActionRequest(actionRequest);
0410: getActionListService().deleteActionItems(
0411: actionRequest.getActionRequestId());
0412: }
0413: deactivateRequests(actionTaken, actionRequest
0414: .getChildrenRequests(), actionRequest,
0415: activationContext);
0416: deactivateRequest(actionTaken, actionRequest
0417: .getParentActionRequest(), actionRequest,
0418: activationContext);
0419: }
0420:
0421: /**
0422: * this method is a hack that is in response to bug http://fms.dfa.cornell.edu:8080/browse/KULWF-428
0423: * the solution is to have multiple action items although the solution seemed best suited here...
0424: *
0425: * basically in certain scenarios we can be left we active workgroup action requests
0426: * that have no action items and this method seeks to repair that. It is evil
0427: */
0428: /*private void activateAnyAbandonedWorkgroupActionRequests(Long documentId) throws EdenUserNotFoundException {
0429: List activeRequests = findByStatusAndDocId(EdenConstants.ACTION_REQUEST_ACTIVATED, documentId);
0430: List requestsGoneBad = new ArrayList();
0431: for (Iterator iter = activeRequests.iterator(); iter.hasNext();) {
0432: ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
0433: if (actionRequest.isWorkgroupRequest() && actionRequest.getActionItems().size() != actionRequest.getWorkgroup().getMembers().size() &&
0434: actionRequest.getParentActionRequest() == null) {
0435: //set to pending to evade activation logic
0436: actionRequest.setStatus(EdenConstants.ACTION_REQUEST_INITIALIZED);
0437: requestsGoneBad.add(actionRequest);
0438: }
0439: }
0440: activateRequests(requestsGoneBad);
0441: }*/
0442:
0443: /**
0444: * Returns true if we are dealing with an 'All Approve' request, the requester of the deactivation is a child of the 'All Approve' request, and all of the children have not been deactivated. If all of the children are already deactivated or a non-child request initiated deactivation, then this method returns false. false otherwise.
0445: */
0446: private boolean haltForAllApprove(ActionRequestValue actionRequest,
0447: ActionRequestValue deactivationRequester) {
0448: if (EdenConstants.APPROVE_POLICY_ALL_APPROVE
0449: .equals(actionRequest.getApprovePolicy())
0450: && actionRequest.hasChild(deactivationRequester)) {
0451: boolean allDeactivated = true;
0452: for (Iterator iterator = actionRequest
0453: .getChildrenRequests().iterator(); iterator
0454: .hasNext();) {
0455: ActionRequestValue childRequest = (ActionRequestValue) iterator
0456: .next();
0457: if (!(allDeactivated = allDeactivated
0458: && childRequest.isDeactivated())) {
0459: return true;
0460: }
0461: }
0462: }
0463: return false;
0464: }
0465:
0466: public List getRootRequests(Collection actionRequests) {
0467: Set unsavedRequests = new HashSet();
0468: Map requestMap = new HashMap();
0469: for (Iterator iterator = actionRequests.iterator(); iterator
0470: .hasNext();) {
0471: ActionRequestValue actionRequest = (ActionRequestValue) iterator
0472: .next();
0473: ActionRequestValue rootRequest = getRoot(actionRequest);
0474: if (rootRequest.getActionRequestId() != null) {
0475: requestMap.put(rootRequest.getActionRequestId(),
0476: rootRequest);
0477: } else {
0478: unsavedRequests.add(rootRequest);
0479: }
0480: }
0481: List requests = new ArrayList();
0482: requests.addAll(requestMap.values());
0483: requests.addAll(unsavedRequests);
0484: return requests;
0485: }
0486:
0487: public ActionRequestValue getRoot(ActionRequestValue actionRequest) {
0488: if (actionRequest == null) {
0489: return null;
0490: }
0491: if (actionRequest.getParentActionRequest() != null) {
0492: return getRoot(actionRequest.getParentActionRequest());
0493: }
0494: return actionRequest;
0495: }
0496:
0497: public List findAllValidRequests(WorkflowUser user,
0498: Long routeHeaderId, String requestCode)
0499: throws EdenUserNotFoundException {
0500: ActionRequestDAO arDAO = getActionRequestDAO();
0501: Collection pendingArs = arDAO
0502: .findAllPendingByDocId(routeHeaderId);
0503: return findAllValidRequests(user, pendingArs, requestCode);
0504: }
0505:
0506: public List findAllValidRequests(WorkflowUser user,
0507: Collection actionRequests, String requestCode)
0508: throws EdenUserNotFoundException {
0509: List matchedArs = new ArrayList();
0510: for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
0511: ActionRequestValue ar = (ActionRequestValue) iter.next();
0512: if (ActionRequestValue.compareActionCode(ar
0513: .getActionRequested(), requestCode) > 0) {
0514: continue;
0515: }
0516: if (ar.isUserRequest()
0517: && user.getWorkflowUserId().getWorkflowId().equals(
0518: ar.getWorkflowId())) {
0519: matchedArs.add(ar);
0520: } else if (ar.isWorkgroupRequest()) {
0521: Workgroup workgroup = getWorkgroupService()
0522: .getWorkgroup(
0523: new WorkflowGroupId(ar.getWorkgroupId()));
0524: if (workgroup.hasMember(user)) {
0525: matchedArs.add(ar);
0526: }
0527: }
0528: }
0529: return matchedArs;
0530: }
0531:
0532: public void updateActionRequestsForResponsibilityChange(
0533: Set responsibilityIds) {
0534: PerformanceLogger performanceLogger = new PerformanceLogger();
0535: Collection documentsAffected = getRouteHeaderService()
0536: .findPendingByResponsibilityIds(responsibilityIds);
0537: String cacheWaitValue = Utilities
0538: .getApplicationConstant(EdenConstants.RULE_CACHE_REQUEUE_WAIT_TIME_KEY);
0539: Long cacheWait = new Long(
0540: EdenConstants.DEFAULT_CACHE_REQUEUE_WAIT_TIME);
0541: if (!Utilities.isEmpty(cacheWaitValue)) {
0542: try {
0543: cacheWait = Long.valueOf(cacheWaitValue);
0544: } catch (NumberFormatException e) {
0545: LOG.warn("Cache wait time is not a valid number: "
0546: + cacheWaitValue);
0547: }
0548: }
0549: LOG
0550: .info("Scheduling requeue of "
0551: + documentsAffected.size()
0552: + " documents, affected by "
0553: + responsibilityIds.size()
0554: + " responsibility changes. Installing a processing wait time of "
0555: + cacheWait.longValue()
0556: + " milliseconds to avoid stale rule cache.");
0557: for (Iterator iterator = documentsAffected.iterator(); iterator
0558: .hasNext();) {
0559: Long routeHeaderId = (Long) iterator.next();
0560: String messageEntity = KEWServiceLocator
0561: .getRouteHeaderService()
0562: .getMessageEntityByDocumentId(routeHeaderId);
0563: if (messageEntity == null) {
0564: messageEntity = Core.getCurrentContextConfig()
0565: .getMessageEntity();
0566: }
0567: DocumentRequeuerService documentRequeuer = MessageServiceNames
0568: .getDocumentRequeuerService(messageEntity,
0569: routeHeaderId, cacheWait);
0570: documentRequeuer.requeueDocument(routeHeaderId);
0571: }
0572: performanceLogger
0573: .log("Time to updateActionRequestsForResponsibilityChange");
0574: }
0575:
0576: /**
0577: * Deletes an action request and all of its action items following the graph down through the action request's children. This method should be invoked on a top-level action request.
0578: */
0579: public void deleteActionRequestGraph(
0580: ActionRequestValue actionRequest) {
0581: for (Iterator iterator = actionRequest.getActionItems()
0582: .iterator(); iterator.hasNext();) {
0583: getActionListService().deleteActionItem(
0584: (ActionItem) iterator.next());
0585: }
0586: getActionRequestDAO()
0587: .delete(actionRequest.getActionRequestId());
0588: for (Iterator iterator = actionRequest.getChildrenRequests()
0589: .iterator(); iterator.hasNext();) {
0590: deleteActionRequestGraph((ActionRequestValue) iterator
0591: .next());
0592: }
0593: }
0594:
0595: public List findByRouteHeaderIdIgnoreCurrentInd(Long routeHeaderId) {
0596: return getActionRequestDAO()
0597: .findByRouteHeaderIdIgnoreCurrentInd(routeHeaderId);
0598: }
0599:
0600: public List findAllActionRequestsByRouteHeaderId(Long routeHeaderId) {
0601: return getActionRequestDAO().findAllByDocId(routeHeaderId);
0602: }
0603:
0604: public List findAllRootActionRequestsByRouteHeaderId(
0605: Long routeHeaderId) {
0606: return getActionRequestDAO().findAllRootByDocId(routeHeaderId);
0607: }
0608:
0609: public List findPendingByActionRequestedAndDocId(
0610: String actionRequestedCd, Long routeHeaderId) {
0611: return getActionRequestDAO()
0612: .findPendingByActionRequestedAndDocId(
0613: actionRequestedCd, routeHeaderId);
0614: }
0615:
0616: public List findPendingByDocIdAtOrBelowRouteLevel(
0617: Long routeHeaderId, Integer routeLevel) {
0618: return getActionRequestDAO()
0619: .findPendingByDocIdAtOrBelowRouteLevel(routeHeaderId,
0620: routeLevel);
0621: }
0622:
0623: public List findPendingRootRequestsByDocId(Long routeHeaderId) {
0624: return getRootRequests(findPendingByDoc(routeHeaderId));
0625: }
0626:
0627: public List findPendingRootRequestsByDocIdAtRouteNode(
0628: Long routeHeaderId, Long nodeInstanceId) {
0629: return getActionRequestDAO()
0630: .findPendingRootRequestsByDocIdAtRouteNode(
0631: routeHeaderId, nodeInstanceId);
0632: }
0633:
0634: public List findRootRequestsByDocIdAtRouteNode(Long documentId,
0635: Long nodeInstanceId) {
0636: return getActionRequestDAO()
0637: .findRootRequestsByDocIdAtRouteNode(documentId,
0638: nodeInstanceId);
0639: }
0640:
0641: public List findPendingRootRequestsByDocIdAtOrBelowRouteLevel(
0642: Long routeHeaderId, Integer routeLevel) {
0643: return getActionRequestDAO()
0644: .findPendingRootRequestsByDocIdAtOrBelowRouteLevel(
0645: routeHeaderId, routeLevel);
0646: }
0647:
0648: public List findPendingRootRequestsByDocIdAtRouteLevel(
0649: Long routeHeaderId, Integer routeLevel) {
0650: return getActionRequestDAO()
0651: .findPendingRootRequestsByDocIdAtRouteLevel(
0652: routeHeaderId, routeLevel);
0653: }
0654:
0655: public List findPendingRootRequestsByDocumentType(
0656: Long documentTypeId) {
0657: return getActionRequestDAO()
0658: .findPendingRootRequestsByDocumentType(documentTypeId);
0659: }
0660:
0661: public void saveActionRequest(ActionRequestValue actionRequest)
0662: throws EdenUserNotFoundException {
0663:
0664: if (actionRequest.isWorkgroupRequest()
0665: && !actionRequest.getWorkgroup().getActiveInd()
0666: .booleanValue()) {
0667: throw new RuntimeException(
0668: "Routing to inactive workgroup. Putting document in exception routing.");
0669: }
0670: getActionRequestDAO().saveActionRequest(actionRequest);
0671: }
0672:
0673: public List findPendingByDoc(Long routeHeaderId) {
0674: return getActionRequestDAO().findAllPendingByDocId(
0675: routeHeaderId);
0676: }
0677:
0678: public List findPendingByDocRequestCdRouteLevel(Long routeHeaderId,
0679: String requestCode, Integer routeLevel) {
0680: List requests = new ArrayList();
0681: for (Iterator iter = getActionRequestDAO()
0682: .findAllPendingByDocId(routeHeaderId).iterator(); iter
0683: .hasNext();) {
0684: ActionRequestValue actionRequest = (ActionRequestValue) iter
0685: .next();
0686: if (ActionRequestValue.compareActionCode(actionRequest
0687: .getActionRequested(), requestCode) > 0) {
0688: continue;
0689: }
0690: if (actionRequest.getRouteLevel().intValue() == routeLevel
0691: .intValue()) {
0692: requests.add(actionRequest);
0693: }
0694: }
0695: return requests;
0696: }
0697:
0698: public List findPendingByDocRequestCdNodeName(Long routeHeaderId,
0699: String requestCode, String nodeName) {
0700: List requests = new ArrayList();
0701: for (Iterator iter = getActionRequestDAO()
0702: .findAllPendingByDocId(routeHeaderId).iterator(); iter
0703: .hasNext();) {
0704: ActionRequestValue actionRequest = (ActionRequestValue) iter
0705: .next();
0706: if (ActionRequestValue.compareActionCode(actionRequest
0707: .getActionRequested(), requestCode) > 0) {
0708: continue;
0709: }
0710: if (actionRequest.getNodeInstance() != null
0711: && actionRequest.getNodeInstance().getName()
0712: .equals(nodeName)) {
0713: requests.add(actionRequest);
0714: }
0715: }
0716: return requests;
0717: }
0718:
0719: public List findActivatedByWorkgroup(Workgroup workgroup) {
0720: return getActionRequestDAO()
0721: .findActivatedByWorkgroup(workgroup);
0722: }
0723:
0724: private WorkgroupService getWorkgroupService() {
0725: return (WorkgroupService) KEWServiceLocator
0726: .getWorkgroupService();
0727: }
0728:
0729: private ActionListService getActionListService() {
0730: return (ActionListService) KEWServiceLocator
0731: .getActionListService();
0732: }
0733:
0734: private ActionTakenService getActionTakenService() {
0735: return (ActionTakenService) KEWServiceLocator
0736: .getActionTakenService();
0737: }
0738:
0739: private UserService getUserService() {
0740: return (UserService) KEWServiceLocator.getUserService();
0741: }
0742:
0743: public ActionRequestDAO getActionRequestDAO() {
0744: return actionRequestDAO;
0745: }
0746:
0747: public void setActionRequestDAO(ActionRequestDAO actionRequestDAO) {
0748: this .actionRequestDAO = actionRequestDAO;
0749: }
0750:
0751: private RouteHeaderService getRouteHeaderService() {
0752: return (RouteHeaderService) KEWServiceLocator
0753: .getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
0754: }
0755:
0756: public List findByStatusAndDocId(String statusCd, Long routeHeaderId) {
0757: return getActionRequestDAO().findByStatusAndDocId(statusCd,
0758: routeHeaderId);
0759: }
0760:
0761: public void alterActionRequested(List actionRequests,
0762: String actionRequestCd) throws EdenUserNotFoundException {
0763: for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
0764: ActionRequestValue actionRequest = (ActionRequestValue) iter
0765: .next();
0766:
0767: actionRequest.setActionRequested(actionRequestCd);
0768: for (Iterator iterator = actionRequest.getActionItems()
0769: .iterator(); iterator.hasNext();) {
0770: ActionItem item = (ActionItem) iterator.next();
0771: item.setActionRequestCd(actionRequestCd);
0772: }
0773:
0774: saveActionRequest(actionRequest);
0775: }
0776: }
0777:
0778: // TODO this still won't work in certain cases when checking from the root
0779: public boolean isDuplicateRequest(ActionRequestValue actionRequest) {
0780: List requests = findAllRootActionRequestsByRouteHeaderId(actionRequest
0781: .getRouteHeader().getRouteHeaderId());
0782: for (Iterator iterator = requests.iterator(); iterator
0783: .hasNext();) {
0784: ActionRequestValue existingRequest = (ActionRequestValue) iterator
0785: .next();
0786: if (existingRequest.getStatus().equals(
0787: EdenConstants.ACTION_REQUEST_DONE_STATE)
0788: && existingRequest.getRouteLevel().equals(
0789: actionRequest.getRouteHeader()
0790: .getDocRouteLevel())
0791: && ObjectUtils.equals(existingRequest
0792: .getWorkflowId(), actionRequest
0793: .getWorkflowId())
0794: && ObjectUtils.equals(existingRequest
0795: .getWorkgroupId(), actionRequest
0796: .getWorkgroupId())
0797: && ObjectUtils.equals(
0798: existingRequest.getRoleName(),
0799: actionRequest.getRoleName())
0800: && ObjectUtils.equals(existingRequest
0801: .getQualifiedRoleName(), actionRequest
0802: .getQualifiedRoleName())
0803: && existingRequest.getActionRequested().equals(
0804: actionRequest.getActionRequested())) {
0805: return true;
0806: }
0807: }
0808: return false;
0809: }
0810:
0811: public Recipient findDelegator(List actionRequests)
0812: throws EdenUserNotFoundException {
0813: Recipient delegator = null;
0814: String requestCode = EdenConstants.ACTION_REQUEST_FYI_REQ;
0815: for (Iterator iterator = actionRequests.iterator(); iterator
0816: .hasNext();) {
0817: ActionRequestValue actionRequest = (ActionRequestValue) iterator
0818: .next();
0819: ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest);
0820: if (delegatorRequest != null) {
0821: if (ActionRequestValue.compareActionCode(
0822: delegatorRequest.getActionRequested(),
0823: requestCode) >= 0) {
0824: delegator = delegatorRequest.getRecipient();
0825: requestCode = delegatorRequest.getActionRequested();
0826: }
0827: }
0828: }
0829: return delegator;
0830: }
0831:
0832: public Recipient findDelegator(ActionRequestValue actionRequest)
0833: throws EdenUserNotFoundException {
0834: ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest);
0835: Recipient delegator = null;
0836: if (delegatorRequest != null) {
0837: delegator = delegatorRequest.getRecipient();
0838: }
0839: return delegator;
0840: }
0841:
0842: public ActionRequestValue findDelegatorRequest(
0843: ActionRequestValue actionRequest) {
0844: ActionRequestValue parentRequest = actionRequest
0845: .getParentActionRequest();
0846: if (parentRequest != null
0847: && !(parentRequest.isUserRequest() || parentRequest
0848: .isWorkgroupRequest())) {
0849: parentRequest = findDelegatorRequest(parentRequest);
0850: }
0851: return parentRequest;
0852: }
0853:
0854: private MessageQueueService getRouteQueueService() {
0855: return (MessageQueueService) KEWServiceLocator
0856: .getService(KEWServiceLocator.ROUTE_QUEUE_SRV);
0857: }
0858:
0859: public void deleteByRouteHeaderId(Long routeHeaderId) {
0860: actionRequestDAO.deleteByRouteHeaderId(routeHeaderId);
0861: }
0862:
0863: public void deleteByActionRequestId(Long actionRequestId) {
0864: actionRequestDAO.delete(actionRequestId);
0865: }
0866:
0867: public void validateActionRequest(ActionRequestValue actionRequest) {
0868: LOG.debug("Enter validateActionRequest(..)");
0869: List errors = new ArrayList();
0870:
0871: String actionRequestCd = actionRequest.getActionRequested();
0872: if (actionRequestCd == null
0873: || actionRequestCd.trim().equals("")) {
0874: errors.add(new WorkflowServiceErrorImpl(
0875: "ActionRequest cd null.",
0876: "actionrequest.actionrequestcd.empty",
0877: actionRequest.getActionRequestId().toString()));
0878: } else if (!EdenConstants.ACTION_REQUEST_CD
0879: .containsKey(actionRequestCd)) {
0880: errors.add(new WorkflowServiceErrorImpl(
0881: "ActionRequest cd invalid.",
0882: "actionrequest.actionrequestcd.invalid",
0883: actionRequest.getActionRequestId().toString()));
0884: }
0885:
0886: Long routeHeaderId = actionRequest.getRouteHeaderId();
0887: if (routeHeaderId == null || routeHeaderId.longValue() == 0) {
0888: errors.add(new WorkflowServiceErrorImpl(
0889: "ActionRequest Document id empty.",
0890: "actionrequest.routeheaderid.empty", actionRequest
0891: .getActionRequestId().toString()));
0892: } else if (getRouteHeaderService()
0893: .getRouteHeader(routeHeaderId) == null) {
0894: errors.add(new WorkflowServiceErrorImpl(
0895: "ActionRequest Document id invalid.",
0896: "actionrequest.routeheaderid.invalid",
0897: actionRequest.getActionRequestId().toString()));
0898: }
0899:
0900: String actionRequestStatus = actionRequest.getStatus();
0901: if (actionRequestStatus == null
0902: || actionRequestStatus.trim().equals("")) {
0903: errors.add(new WorkflowServiceErrorImpl(
0904: "ActionRequest status null.",
0905: "actionrequest.actionrequeststatus.empty",
0906: actionRequest.getActionRequestId().toString()));
0907: } else if (!EdenConstants.ACTION_REQUEST_STATUS
0908: .containsKey(actionRequestStatus)) {
0909: errors.add(new WorkflowServiceErrorImpl(
0910: "ActionRequest status invalid.",
0911: "actionrequest.actionrequeststatus.invalid",
0912: actionRequest.getActionRequestId().toString()));
0913: }
0914:
0915: if (actionRequest.getResponsibilityId() == null) {
0916: errors.add(new WorkflowServiceErrorImpl(
0917: "ActionRequest responsibility id null.",
0918: "actionrequest.responsibilityid.empty",
0919: actionRequest.getActionRequestId().toString()));
0920: }
0921:
0922: Integer priority = actionRequest.getPriority();
0923: if (priority == null) {
0924: errors.add(new WorkflowServiceErrorImpl(
0925: "ActionRequest priority null.",
0926: "actionrequest.priority.empty", actionRequest
0927: .getActionRequestId().toString()));
0928: }
0929:
0930: // if(actionRequest.getRouteMethodName() == null || actionRequest.getRouteMethodName().trim().equals("")){
0931: // errors.add(new WorkflowServiceErrorImpl("ActionRequest route method name null.", "actionrequest.routemethodname.empty", actionRequest.getActionRequestId().toString()));
0932: // }
0933:
0934: Integer routeLevel = actionRequest.getRouteLevel();
0935: if (routeLevel == null) {
0936: errors.add(new WorkflowServiceErrorImpl(
0937: "ActionRequest route level null.",
0938: "actionrequest.routelevel.empty", actionRequest
0939: .getActionRequestId().toString()));
0940: } else if (routeLevel.intValue() < -1) {
0941: errors.add(new WorkflowServiceErrorImpl(
0942: "ActionRequest route level invalid.",
0943: "actionrequest.routelevel.invalid", actionRequest
0944: .getActionRequestId().toString()));
0945: }
0946:
0947: Integer version = actionRequest.getDocVersion();
0948: if (version == null) {
0949: errors.add(new WorkflowServiceErrorImpl(
0950: "ActionRequest doc version null.",
0951: "actionrequest.docversion.empty", actionRequest
0952: .getActionRequestId().toString()));
0953: }
0954:
0955: if (actionRequest.getCreateDate() == null) {
0956: errors.add(new WorkflowServiceErrorImpl(
0957: "ActionRequest create date null.",
0958: "actionrequest.createdate.empty", actionRequest
0959: .getActionRequestId().toString()));
0960: }
0961:
0962: String recipientType = actionRequest.getRecipientTypeCd();
0963: if (recipientType != null && !recipientType.trim().equals("")) {
0964: if (recipientType.equals(EdenConstants.WORKGROUP)) {
0965: Long workgroupId = actionRequest.getWorkgroupId();
0966: if (workgroupId == null) {
0967: errors.add(new WorkflowServiceErrorImpl(
0968: "ActionRequest workgroup null.",
0969: "actionrequest.workgroup.empty",
0970: actionRequest.getActionRequestId()
0971: .toString()));
0972: } else if (getWorkgroupService().getWorkgroup(
0973: new WorkflowGroupId(workgroupId)) == null) {
0974: errors.add(new WorkflowServiceErrorImpl(
0975: "ActionRequest workgroup invalid.",
0976: "actionrequest.workgroup.invalid",
0977: actionRequest.getActionRequestId()
0978: .toString()));
0979: }
0980:
0981: }
0982: if (recipientType.equals(EdenConstants.PERSON)) {
0983: String workflowId = actionRequest.getWorkflowId();
0984: if (workflowId == null || workflowId.trim().equals("")) {
0985: errors.add(new WorkflowServiceErrorImpl(
0986: "ActionRequest person id null.",
0987: "actionrequest.persosn.empty",
0988: actionRequest.getActionRequestId()
0989: .toString()));
0990: } else {
0991: try {
0992: getUserService().getWorkflowUser(
0993: new WorkflowUserId(workflowId));
0994: } catch (EdenUserNotFoundException e) {
0995: errors.add(new WorkflowServiceErrorImpl(
0996: "ActionRequest person id invalid.",
0997: "actionrequest.personid.invalid",
0998: actionRequest.getActionRequestId()
0999: .toString()));
1000: }
1001: }
1002:
1003: if (recipientType.equals(EdenConstants.ROLE)
1004: && (actionRequest.getRoleName() == null || actionRequest
1005: .getRoleName().trim().equals(""))) {
1006: errors.add(new WorkflowServiceErrorImpl(
1007: "ActionRequest role name null.",
1008: "actionrequest.rolename.null",
1009: actionRequest.getActionRequestId()
1010: .toString()));
1011: }
1012: }
1013: LOG.debug("Exit validateActionRequest(..) ");
1014: if (!errors.isEmpty()) {
1015: throw new WorkflowServiceErrorException(
1016: "ActionRequest Validation Error", errors);
1017: }
1018: }
1019: }
1020:
1021: public List getDelegateRequests(ActionRequestValue actionRequest) {
1022: List delegateRequests = new ArrayList();
1023: List requests = getTopLevelRequests(actionRequest);
1024: for (Iterator iterator = requests.iterator(); iterator
1025: .hasNext();) {
1026: ActionRequestValue parentActionRequest = (ActionRequestValue) iterator
1027: .next();
1028: delegateRequests.addAll(parentActionRequest
1029: .getChildrenRequests());
1030: }
1031: return delegateRequests;
1032: }
1033:
1034: public List getTopLevelRequests(ActionRequestValue actionRequest) {
1035: List topLevelRequests = new ArrayList();
1036: if (actionRequest.isRoleRequest()) {
1037: topLevelRequests
1038: .addAll(actionRequest.getChildrenRequests());
1039: } else {
1040: topLevelRequests.add(actionRequest);
1041: }
1042: return topLevelRequests;
1043: }
1044:
1045: public boolean isValidActionRequestCode(String actionRequestCode) {
1046: return actionRequestCode != null
1047: && EdenConstants.ACTION_REQUEST_CODES
1048: .containsKey(actionRequestCode);
1049: }
1050:
1051: }
|