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.engine.transition;
017    
018    import org.kuali.rice.kew.engine.RouteContext;
019    import org.kuali.rice.kew.engine.node.ProcessDefinitionBo;
020    import org.kuali.rice.kew.engine.node.ProcessResult;
021    import org.kuali.rice.kew.engine.node.RouteNode;
022    import org.kuali.rice.kew.engine.node.RouteNodeInstance;
023    import org.kuali.rice.kew.engine.node.SubProcessNode;
024    import org.kuali.rice.kew.engine.node.SubProcessResult;
025    import org.kuali.rice.kew.api.exception.WorkflowException;
026    
027    import java.util.ArrayList;
028    import 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     */
038    public 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    }