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