001 /** 002 * Copyright 2005-2013 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.engine.transition; 017 018 import org.kuali.rice.kew.engine.RouteContext; 019 import org.kuali.rice.kew.engine.RouteHelper; 020 import org.kuali.rice.kew.engine.node.Node; 021 import org.kuali.rice.kew.engine.node.ProcessResult; 022 import org.kuali.rice.kew.engine.node.RouteNode; 023 import org.kuali.rice.kew.engine.node.RouteNodeInstance; 024 025 import java.util.ArrayList; 026 import java.util.List; 027 028 029 /** 030 * Common superclass for all Transition Engines. A TransitionEngine handles transitioning into and out of 031 * a {@link RouteNodeInstance}. The TransitionEngine is also responsible for determining if a Node has completed. 032 * 033 * @author Kuali Rice Team (rice.collab@kuali.org) 034 */ 035 public abstract class TransitionEngine { 036 037 private RouteHelper helper; 038 039 public RouteNodeInstance transitionTo(RouteNodeInstance nextNodeInstance, RouteContext context) throws Exception { 040 return nextNodeInstance; 041 } 042 043 /** 044 * Tell the WorkflowEngine processing the activeNodeInstance if the node is complete and transitionFrom can 045 * be called. 046 * 047 * @return boolean 048 * @param context for routing 049 * @throws Exception 050 */ 051 public abstract ProcessResult isComplete(RouteContext context) throws Exception; 052 053 public Transition transitionFrom(RouteContext context, ProcessResult processResult) throws Exception { 054 return new Transition(resolveNextNodeInstances(context.getNodeInstance())); 055 } 056 057 protected void setRouteHelper(RouteHelper helper) { 058 this.helper = helper; 059 } 060 061 protected RouteHelper getRouteHelper() { 062 return helper; 063 } 064 065 protected Node getNode(RouteNode routeNode, Class nodeClass) throws Exception { 066 return helper.getNode(routeNode); 067 } 068 069 /** 070 * Determines the next nodes instances for the transition. If the node instance already 071 * has next nodes instances (i.e. a dynamic node), then those will be returned. Otherwise 072 * it will resolve the next nodes from the RouteNode prototype. 073 * @param nodeInstance for the transition 074 * @param nextRouteNodes list of route notes 075 * @return list of route note instances 076 */ 077 protected List<RouteNodeInstance> resolveNextNodeInstances(RouteNodeInstance nodeInstance, List<RouteNode> nextRouteNodes) { 078 List<RouteNodeInstance> nextNodeInstances = new ArrayList<RouteNodeInstance>(); 079 for (RouteNode nextRouteNode : nextRouteNodes) 080 { 081 RouteNode nextNode = (RouteNode) nextRouteNode; 082 RouteNodeInstance nextNodeInstance = getRouteHelper().getNodeFactory().createRouteNodeInstance(nodeInstance.getDocumentId(), nextNode); 083 nextNodeInstance.setBranch(nodeInstance.getBranch()); 084 nextNodeInstance.setProcess(nodeInstance.getProcess()); 085 nextNodeInstances.add(nextNodeInstance); 086 } 087 return nextNodeInstances; 088 } 089 090 protected List<RouteNodeInstance> resolveNextNodeInstances(RouteNodeInstance nodeInstance) { 091 return resolveNextNodeInstances(nodeInstance, nodeInstance.getRouteNode().getNextNodes()); 092 } 093 094 }