001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.workflow.lite;
016    
017    import org.apache.oozie.workflow.WorkflowException;
018    import org.apache.oozie.workflow.WorkflowInstance;
019    import org.apache.oozie.ErrorCode;
020    
021    import java.util.ArrayList;
022    import java.util.List;
023    
024    //TODO javadoc
025    public abstract class NodeHandler {
026    
027        public interface Context {
028    
029            public NodeDef getNodeDef();
030    
031            public String getExecutionPath();
032    
033            public String getParentExecutionPath(String executionPath);
034    
035            public String getSignalValue();
036    
037            public void setVar(String name, String value);
038    
039            public String getVar(String name);
040    
041            public void setTransientVar(String name, Object value);
042    
043            public Object getTransientVar(String name);
044    
045            public String createExecutionPath(String name);
046    
047            //can be called only from exit(), creation of execPaths is automatic
048            //when a handler returns more than one transition.
049            public void deleteExecutionPath();
050    
051            //must be used by multiExit
052            public String createFullTransition(String executionPath, String transition);
053    
054            public void killJob();
055    
056            public void completeJob();
057    
058            public LiteWorkflowInstance getProcessInstance();
059        }
060    
061        private static final String VISITED = "visited";
062    
063        public static String getLoopFlag(String nodeName) {
064            return nodeName + WorkflowInstance.NODE_VAR_SEPARATOR + VISITED;
065        }
066    
067        public void loopDetection(Context context) throws WorkflowException {
068            String flag = getLoopFlag(context.getNodeDef().getName());
069            if (context.getVar(flag) != null) {
070                throw new WorkflowException(ErrorCode.E0709, context.getNodeDef().getName());
071            }
072            context.setVar(flag, "true");
073        }
074    
075        // TRUE means immediate exit, false means has to be signal
076        public abstract boolean enter(Context context) throws WorkflowException;
077    
078        // the return list contains executionPath#transition, important for fork
079        public List<String> multiExit(Context context) throws WorkflowException {
080            List<String> transitions = new ArrayList<String>(1);
081            String transition = exit(context);
082            if (transition != null) {
083                transitions.add(context.createFullTransition(context.getExecutionPath(), transition));
084            }
085            return transitions;
086        }
087    
088    
089        public abstract String exit(Context context) throws WorkflowException;
090    
091        public void kill(Context context) {
092        }
093    
094        public void fail(Context context) {
095        }
096    }