001/**
002 * Copyright 2005-2015 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 */
016package org.kuali.rice.kew.engine.transition;
017
018import org.kuali.rice.kew.engine.RouteContext;
019import org.kuali.rice.kew.engine.node.ProcessDefinitionBo;
020import org.kuali.rice.kew.engine.node.ProcessResult;
021import org.kuali.rice.kew.engine.node.RouteNode;
022import org.kuali.rice.kew.engine.node.RouteNodeInstance;
023import org.kuali.rice.kew.engine.node.SubProcessNode;
024import org.kuali.rice.kew.engine.node.SubProcessResult;
025import org.kuali.rice.kew.api.exception.WorkflowException;
026
027import java.util.ArrayList;
028import java.util.List;
029
030
031/**
032 * Handles transitions into and out of {@link SubProcessNode} nodes.
033 * 
034 * @see SubProcessNode
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 */
038public class SubProcessTransitionEngine extends TransitionEngine {
039    
040    public RouteNodeInstance transitionTo(RouteNodeInstance nextNodeInstance, RouteContext context) throws Exception {
041        String processName = nextNodeInstance.getRouteNode().getRouteNodeName();
042        ProcessDefinitionBo process = context.getDocument().getDocumentType().getNamedProcess(processName);
043        if (process == null) {
044            throw new WorkflowException("Could not locate named sub process: " + processName);
045        }
046        RouteNodeInstance subProcessNodeInstance = nextNodeInstance;
047        subProcessNodeInstance.setInitial(false);
048        subProcessNodeInstance.setActive(false);
049        nextNodeInstance = getRouteHelper().getNodeFactory().createRouteNodeInstance(subProcessNodeInstance.getDocumentId(), process.getInitialRouteNode());
050        nextNodeInstance.setBranch(subProcessNodeInstance.getBranch());
051        nextNodeInstance.setProcess(subProcessNodeInstance);
052            return nextNodeInstance;
053        }
054
055        public ProcessResult isComplete(RouteContext context) throws Exception {
056        throw new UnsupportedOperationException("isComplete() should not be invoked on a SubProcess!");
057    }
058
059    public Transition transitionFrom(RouteContext context, ProcessResult processResult) throws Exception {
060                RouteNodeInstance processInstance = context.getNodeInstance().getProcess();
061        processInstance.setComplete(true);
062                SubProcessNode node = (SubProcessNode)getNode(processInstance.getRouteNode(), SubProcessNode.class);
063                SubProcessResult result = node.process(context);
064                List<RouteNodeInstance> nextNodeInstances = new ArrayList<RouteNodeInstance>();
065                if (result.isComplete()) {
066                        List<RouteNode> nextNodes = processInstance.getRouteNode().getNextNodes();
067            for (RouteNode nextNode : nextNodes)
068            {
069                RouteNodeInstance nextNodeInstance = getRouteHelper().getNodeFactory().createRouteNodeInstance(processInstance.getDocumentId(), nextNode);
070                nextNodeInstance.setBranch(processInstance.getBranch());
071                nextNodeInstance.setProcess(processInstance.getProcess());
072                nextNodeInstances.add(nextNodeInstance);
073            }
074                }
075                return new Transition(nextNodeInstances);
076        }
077
078}