miércoles, 22 de julio de 2009

Uso de un nodo de decisión

Un nodo de decisión se usa para modelar un punto en el flujo en que el propio proceso quien tomar una decisión sobre el camino a seguir. Los criterios de la decisión se pueden especificar de las siguientes formas:
  • Añadiendo condiciones a las transiciones o beanshell scripts que devuelven un boolean. Los nodos recorreran sus transiciones examinando las condiciones hasta encontrar la primera transición que cumpla las condiciones.
  • Mediante DecissionHandler que devuelve la transición a seguir.
En este post vamos a crear un proceso que contiene un nodo de decisión que utiliza un DecissionHandler para conocer la transición a seguir.

En la siguiente imagen se puede ver el proceso de ejemplo:

Este proceso empieza en un nodo de inicio del que se sale mediante la transicion comenzar. Esta transición tiene una acción crearvalor manejada por la clase ValorAction, que se encarga de introducir en el contexto de ejecución una variable valor:
public class ValorAction implements ActionHandler {
public String valor;

@Override
public void execute(ExecutionContext executionContext) throws Exception {
executionContext.getContextInstance().setVariable("valor", valor);
}
}

A continuación se llega a un nodo de decision manejado por una clase Decisor, que comprueba si en el contexto de ejecución existe una variable valor con un valor asignado. Si existe esta variable se abandona el nodo por la transición terminar1 y si no, por la transición terminar2:
public class Decisor implements DecisionHandler {

public Decisor(String info) {
super();
}

@Override
public String decide(ExecutionContext executionContext) throws Exception {

String valor =
(String)executionContext.getContextInstance().getVariable("valor");

if(valor != null) {
return "terminar1";
} else {
return "terminar2";
}
}
}

Por último, al llegar a cualquiera de los nodos finales se lanza una acción que muestra en que nodo está terminando la ejecución del flujo, manejada por la clase MostrarMensajeAction:
public class MostrarMensajeAction implements ActionHandler {

public MostrarMensajeAction(String info) {
super();
}

@Override
public void execute(ExecutionContext executionContext) throws Exception {

System.out.println(
"Se sale del flujo por el nodo: "
+ executionContext.getNode().getName());
}
}

Se puede ejecutar este proceso mediante una clase de test como esta:
public void testSimpleProcess() throws Exception {

// Extraer la definicion de proceso del archivo processdefinition.xml.
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlResource("decision/processdefinition.xml");
assertNotNull("La definicion debe no ser nula", processDefinition);

// Create an instance of the process definition.
ProcessInstance instance = new ProcessInstance(processDefinition);
assertEquals(
"La instancia está en el estado inicial",
instance.getRootToken().getNode().getName(),
"inicio");
assertNull(
"La variable 'valor' no debe existir todavía",
instance.getContextInstance().getVariable("valor"));

// Mueve la instancia de proceso desde el estado inicial al primer estado.
instance.signal();
}
}

Si en la configuración se ha introducido un valor para la variable valor, por la consola se verá un mensaje que indica que estamos terminando en el nodo final1. En caso contrario veremos que se termina en el nodo final2.

Referencias:
jBPM Javadoc

1 comentario:

  1. Hola,

    Excelente artículo (toda la "saga").

    Una pregunta... cuando intento ejecutar la clase de test (como en tu ejemplo), no es capaz de encontrar las clases

    Vorg.jbpm.JbpmException: could not instantiate class es.mec.jbpm.Decisor
    at org.jbpm.instantiation.InstantiatorUtil.instantiate(InstantiatorUtil.java:46)...

    ¿Alguna idea?

    ResponderEliminar