📄 flowmanager.java
字号:
/*
* Copyright (c) 2003, Alexander Greif
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Flow4J-Eclipse project nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.orthanc.flow4j.runtime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
/**
* With the help of the FlowManager you can register and
* execute flows.
* @author agreif
*
*/
public class FlowManager {
static private Map taskFlowletSingletons = new HashMap();
static private Map flowSingletons = new HashMap();
static private Map flowSingletons2 = new HashMap();
/**
* Returns whether a flow with the given flow name is registered.
* @param flowName the name of the flow
* @return reue if a flow with the given flow name is registered.
*/
public static boolean isFlowNameRegistered(String flowName) {
return flowSingletons.containsKey(flowName);
}
/**
* Returns an instance for the class, that's classpath is supported, or throws
* an Exception
* @param classPath the class's path
* @return a new instance
* @throws Flow4JRuntimeException
*/
static private Object getInstance(String classPath)
throws Flow4JRuntimeException {
Object obj = null;
try {
obj = getInstance(Class.forName(classPath));
} catch (ClassNotFoundException e) {
throw new Flow4JRuntimeException("Cannot find class: " + classPath);
}
return obj;
}
/**
* TODO
* @param clazz
* @return
*/
static private Object getInstance(Class clazz) {
Object obj = null;
try {
obj = clazz.newInstance();
} catch (InstantiationException e) {
throw new Flow4JRuntimeException(
"Cannot instantiate class: " + clazz.getName());
} catch (IllegalAccessException e) {
throw new Flow4JRuntimeException(
"IllegalAccessException while instantiating class: "
+ clazz.getName());
}
return obj;
}
/**
* TODO
* @param className
* @return
*/
static private Class getClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new Flow4JRuntimeException("Cannot find class: " + className);
}
}
/**
* Registers the task. Puts the task's singleton in the taskFlowlet registry map.
* @param className the task class's fully qualified class name
* @return the registeren task flowlet instance
* @throws Flow4JRuntimeException if the class does not implement the ITaskFlowlet interface
* or if the classname is incorrect
* or if the task instance cannot be registered (taskname already registered but with different class)
*/
static public ITaskFlowlet registerTaskFlowlet(String className)
throws Flow4JRuntimeException {
return registerTaskFlowlet(getClass(className));
}
/**
* Registers the task.
* @param taskFlowletClass
* @return the registeren task flowlet instance
*/
static public ITaskFlowlet registerTaskFlowlet(Class taskFlowletClass) {
Object instance = getInstance(taskFlowletClass);
if (!(instance instanceof ITaskFlowlet))
throw new Flow4JRuntimeException(
"class \""
+ taskFlowletClass.getName()
+ "\" does not implement the ITaskFlowlet interface.");
ITaskFlowlet taskFlowletInstance = (ITaskFlowlet) instance;
String taskName = taskFlowletInstance.getName();
if (taskName == null || taskName.trim().length() == 0)
throw new Flow4JRuntimeException(
"The name of the task \""
+ taskFlowletClass.getName()
+ "\" is either empty or not set");
// check for already registered Task with same name
ITaskFlowlet tempTaskFlowletInstance =
(ITaskFlowlet) taskFlowletSingletons.get(taskName);
if (tempTaskFlowletInstance != null) {
if (!taskFlowletClass
.getName()
.equals(tempTaskFlowletInstance.getClass().getName()))
throw new Flow4JRuntimeException(
"Exception while registering taskFlowlet class \""
+ taskFlowletClass.getName()
+ "\". Task with name \""
+ taskName
+ "\" is already registered for class \""
+ tempTaskFlowletInstance.getClass().getName()
+ "\".");
else
return taskFlowletInstance;
}
taskFlowletSingletons.put(taskName, taskFlowletInstance);
return taskFlowletInstance;
}
/**
* Registers the flow. Puts the flow's singleton in the flow registry map.
* @param className the flow class's fully qualified class name
* @return the registered flow instance
* @throws Flow4JRuntimeException if the class does not implement the IFlow interface
* or if the classname is incorrect
* or if the flow instance cannot be registered (already exists)
*/
static public IFlow registerFlow(String className)
throws Flow4JRuntimeException {
return registerFlow(getClass(className));
}
/**
* Registers the flow.
* @param flowClass
* @return the registered flow instance
*/
static public IFlow registerFlow(Class flowClass) {
Object instance = getInstance(flowClass);
if (!(instance instanceof IFlow))
throw new Flow4JRuntimeException(
"class \""
+ flowClass.getName()
+ "\" does not implement the IFlow interface.");
IFlow flowInstance = (IFlow) instance;
String flowName = flowInstance.getName();
if (flowName == null || flowName.trim().length() == 0)
throw new Flow4JRuntimeException(
"The name of flow \""
+ flowClass.getName()
+ "\" is either empty or not set");
// check for already registered flow with same name
IFlow tempFlowInstance = (IFlow) flowSingletons.get(flowName);
if (tempFlowInstance != null) {
//throw new Flow4JRuntimeException
System.out.println(
"Warning while registering flow class \""
+ flowInstance.getClass().getName()
+ "\". Flow with name \""
+ flowName
+ "\" is already registered for class \""
+ tempFlowInstance.getClass().getName()
+ "\".");
}
flowSingletons.put(flowName, flowInstance);
flowSingletons2.put(flowInstance.getClass(), flowInstance);
return flowInstance;
}
/**
* Registers all flows in the collection.
* @param flowClasses
*/
static public void registerFlows(Collection flowClasses) {
if (flowClasses == null || flowClasses.isEmpty())
return;
for (Iterator iter = flowClasses.iterator(); iter.hasNext();)
registerFlow(((Class) iter.next()).getName());
}
/**
* Registers all flows which are in the flowrepository
* @param flowRepository
*/
static public void registerFlows(IFlowRepository flowRepository) {
if (flowRepository == null)
return;
registerFlows(flowRepository.getFlowClasses());
}
/**
* Executes the given flow with the given start node and an empty dictionary.
* Returns the automatically generated FlowDictionary which might have been
* manipulated/filled by flowlets.
* @param flowName the name of the flow
* @param startFlowletName name of the start node
* @throws Flow4JRuntimeException if something goes wrong
* @return the automatically generated FlowDictionary.
*/
static public FlowDictionary executeFlow(
String flowName,
String startFlowletName)
throws Flow4JRuntimeException {
FlowDictionary dict = new FlowDictionary();
executeFlow(flowName, startFlowletName, dict);
return dict;
}
/**
* Executes the flow with a newly created dictionary.
* The syntax for the flow and its start node is:
* <code>flowname-startflowletname</code>
* Returns the automatically generated FlowDictionary which might have been
* manipulated/filled by flowlets.
* @param flowStart the flow and it's start node
* @throws Flow4JRuntimeException if something goes wrong
* @return the automatically generated FlowDictionary.
*/
static public FlowDictionary executeFlow(String flowStart)
throws Flow4JRuntimeException {
FlowDictionary dict = new FlowDictionary();
executeFlow(flowStart, dict);
return dict;
}
/**
* Executes the flow.
* The flow has to be registered prior calling this method.
* The syntax for the flow and it's start node is:<br/>
* <code>flowname-startflowletname</code>
* @param flowStart the flow and it's start node
* @param dictionary the dictionary containing the runtime data
* @throws Flow4JRuntimeException if something goes wrong
*/
static public void executeFlow(String flowStart, FlowDictionary dictionary)
throws Flow4JRuntimeException {
StringTokenizer tokenizer =
new StringTokenizer(
flowStart,
Flow4JRuntimeConsts.FLOW_START_DELIMITER);
if (tokenizer.countTokens() != 2)
throw new Flow4JRuntimeException(
"Invalid flow-start pair: \""
+ flowStart
+ "\". Valid syntax is {flowname}-{startflowletname}");
String flowName = tokenizer.nextToken();
String startFlowletName = tokenizer.nextToken();
executeFlow(flowName, startFlowletName, dictionary);
}
/**
* Executes the start node of the given flow that uses the supported dictionary.
* The flow has to be registered prior calling this method.
* The syntax for the flow and it's start flowlet is:<br/>
* <code>flowname-startflowletname</code>
* @param flowName the name of the flow
* @param startFlowletName name of the start flowlet
* @param dictionary the map that contains runtime data
* @throws Flow4JRuntimeException if something goes wrong
*/
static public void executeFlow(
String flowName,
String startFlowletName,
FlowDictionary dictionary)
throws Flow4JRuntimeException {
IFlow flowSingleton = (IFlow) flowSingletons.get(flowName);
if (flowSingleton == null)
throw new Flow4JRuntimeException(
"Flow \"" + flowName + "\" not found.");
flowSingleton.execute(startFlowletName, dictionary);
}
/**
* Executes the start node of the given flow.
* The flow does not need to be registered when using this method,
* because the flow class is defined directly.<br/>
* You can use it like: <br/>
* <code>FlowManager.executeFlow(MyFlow.class, "Start");</code>
* Returns the automatically generated FlowDictionary which might have been
* manipulated/filled by flowlets.
* @param flowClass the flow's class
* @param startFlowletName name of the start flowlet
* @return the automatically generated FlowDictionary.
*/
static public FlowDictionary executeFlow(Class flowClass, String startFlowletName) {
FlowDictionary dict = new FlowDictionary();
executeFlow(flowClass, startFlowletName, dict);
return dict;
}
/**
* Executes the start node of the given flow and a valid flow
* dictionary.
* The flow does not need to be registered when using this method,
* because the flow class is defined directly.<br/>
* You can use it like: <br/>
* <code>FlowManager.executeFlow(MyFlow.class, "Start");</code>
* @param flowClass the flow's class
* @param startFlowletName name of the start flowlet
* @param dictionary the map that contains runtime data
*/
static public void executeFlow(
Class flowClass,
String startFlowletName,
FlowDictionary dictionary) {
IFlow flowSingleton = (IFlow) flowSingletons2.get(flowClass);
if (flowSingleton == null)
flowSingleton = registerFlow(flowClass);
flowSingleton.execute(startFlowletName, dictionary);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -