*.bpmn
!tests/*.bpmn
tests/model
-tests/instance
\ No newline at end of file
+tests/instance
+tests/exclusive_gateway
\ No newline at end of file
static void zak_gflow_instance_class_init (ZakGFlowInstanceClass *class);
static void zak_gflow_instance_init (ZakGFlowInstance *zak_gflow_instance);
-static gchar *zak_gflow_instance_next (ZakGFlowInstance *instance, const gchar *node_id, GNode *cur_node);
+static GPtrArray *zak_gflow_instance_next (ZakGFlowInstance *instance, const gchar *node_id, GNode *cur_node);
static void zak_gflow_instance_set_property (GObject *object,
guint property_id,
priv->nodes_history = g_node_new (NULL);
}
-static gchar
+static GPtrArray
*zak_gflow_instance_next (ZakGFlowInstance *instance, const gchar *node_id, GNode *cur_node)
{
- gchar *ret;
+ GPtrArray *ret;
xmlNode *cur;
ZakGFlowInstancePrivate *priv;
- ret = NULL;
+ gint i;
+
+ ret = g_ptr_array_new ();
priv = zak_gflow_instance_get_instance_private (instance);
if (xnodeset != NULL
&& xnodeset->nodeNr > 0)
{
- ret = g_strdup ((const gchar *)xmlNodeGetContent (xnodeset->nodeTab[0]));
+ g_ptr_array_add (ret, g_strdup ((const gchar *)xmlNodeGetContent (xnodeset->nodeTab[0])));
zak_gflow_instance_next (instance, (const gchar *)xmlNodeGetContent (xnodeset->nodeTab[0]), _cur_node);
}
}
{
g_message ("%s: %s (targetRef %s)", cur->name, (gchar *)xmlGetProp (cur, (const xmlChar *)"name"), (gchar *)xmlGetProp (cur, (const xmlChar *)"targetRef"));
- ret = g_strdup ((const gchar *)xmlGetProp (cur, (const xmlChar *)"targetRef"));
+ g_ptr_array_add (ret, g_strdup ((const gchar *)xmlGetProp (cur, (const xmlChar *)"targetRef")));
zak_gflow_instance_next (instance, (const gchar *)xmlGetProp (cur, (const xmlChar *)"targetRef"), _cur_node);
}
else if (xmlStrcmp (cur->name, (const xmlChar *)"task") == 0
{
g_message ("%s: %s", cur->name, (gchar *)xmlGetProp (cur, (const xmlChar *)"name"));
- ret = g_strdup ((gchar *)xmlGetProp (cur, (const xmlChar *)"id"));
+ g_ptr_array_add (ret, g_strdup ((gchar *)xmlGetProp (cur, (const xmlChar *)"id")));
}
else if (xmlStrcmp (cur->name, (const xmlChar *)"exclusiveGateway") == 0)
{
g_message ("%s: %s", cur->name, (gchar *)xmlGetProp (cur, (const xmlChar *)"name"));
- ret = g_strdup ((gchar *)xmlGetProp (cur, (const xmlChar *)"id"));
+ xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, cur, (const xmlChar *)"child::bpmn:outgoing");
+ if (xnodeset != NULL)
+ {
+ for (i = 0; i < xnodeset->nodeNr; i++)
+ {
+ g_ptr_array_add (ret, g_strdup ((const gchar *)xmlNodeGetContent (xnodeset->nodeTab[i])));
+ }
+ }
}
else
{
xmlNodeSet *xnodeset;
gint i;
+ guint j;
- gchar *cur_node_id;
+ GPtrArray *cur_nodes_id;
ZakGFlowInstancePrivate *priv = zak_gflow_instance_get_instance_private (instance);
G_POST_ORDER,
G_TRAVERSE_LEAVES,
xnode);
- if (node != NULL)
+ if (xmlStrcmp (xnode->name, (const xmlChar *)"task") != 0
+ && xmlStrcmp (xnode->name, (const xmlChar *)"userTask") != 0)
+ {
+ g_warning ("The node <%s> isn't a task: it cannot be completed.", node_id);
+ }
+ else if (node != NULL)
{
/* move to next */
xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, xnode, (const xmlChar *)"child::bpmn:outgoing");
- if (xnodeset != NULL
- && xnodeset->nodeNr > 0)
+ if (xnodeset != NULL)
{
for (i = 0; i < xnodeset->nodeNr; i++)
{
- cur_node_id = zak_gflow_instance_next (instance, (const gchar *)xmlNodeGetContent (xnodeset->nodeTab[i]), node);
- g_ptr_array_add (ret, g_strdup (cur_node_id));
- g_free (cur_node_id);
+ cur_nodes_id = zak_gflow_instance_next (instance, (const gchar *)xmlNodeGetContent (xnodeset->nodeTab[i]), node);
+ for (j = 0; j < cur_nodes_id->len; j++)
+ {
+ g_ptr_array_add (ret, g_strdup (g_ptr_array_index (cur_nodes_id, j)));
+ }
}
}
}
else
{
- g_warning ("The node <%s> isn't a waiting node", node_id);
+ g_warning ("The node <%s> isn't a waiting node.", node_id);
}
}
else
return ret;
}
+/**
+ * zak_gflow_instance_exclusive_gateway_set_route:
+ * @instance:
+ * @node_id:
+ * @route_id:
+ *
+ */
+GPtrArray
+*zak_gflow_instance_exclusive_gateway_set_route (ZakGFlowInstance *instance, const gchar *node_id, const gchar *route_id)
+{
+ GPtrArray *ret;
+
+ xmlNode *xnode;
+
+ GNode *node;
+
+ xmlNodeSet *xnodeset;
+
+ guint i;
+
+ GPtrArray *cur_nodes_id;
+
+ ZakGFlowInstancePrivate *priv = zak_gflow_instance_get_instance_private (instance);
+
+ ret = g_ptr_array_new ();
+
+ xnode = (xmlNode *)g_hash_table_lookup (priv->ht_nodes, node_id);
+ if (xnode != NULL)
+ {
+ node = g_node_find (priv->nodes_history,
+ G_POST_ORDER,
+ G_TRAVERSE_LEAVES,
+ xnode);
+ if (xmlStrcmp (xnode->name, (const xmlChar *)"exclusiveGateway") != 0)
+ {
+ g_warning ("The node <%s> isn't an exclusive gateway.", node_id);
+ }
+ else if (node != NULL)
+ {
+ cur_nodes_id = zak_gflow_instance_next (instance, route_id, node);
+ for (i = 0; i < cur_nodes_id->len; i++)
+ {
+ g_ptr_array_add (ret, g_strdup (g_ptr_array_index (cur_nodes_id, i)));
+ }
+ }
+ else
+ {
+ g_warning ("The node <%s> isn't a waiting node.", node_id);
+ }
+ }
+
+ return ret;
+}
+
/* PRIVATE */
static void
zak_gflow_instance_set_property (GObject *object,
GPtrArray *zak_gflow_instance_task_complete (ZakGFlowInstance *instance, const gchar *node_id);
+GPtrArray *zak_gflow_instance_exclusive_gateway_set_route (ZakGFlowInstance *instance, const gchar *node_id, const gchar *route_id);
+
G_END_DECLS
noinst_PROGRAMS = \
model \
- instance
+ instance \
+ exclusive_gateway
EXTRADIST = \
diagram.bpmn
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
+ <bpmn:process id="Process_1" isExecutable="false">
+ <bpmn:startEvent id="StartEvent_1">
+ <bpmn:outgoing>SequenceFlow_0ltcl3v</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:exclusiveGateway id="ExclusiveGateway_0931occ">
+ <bpmn:incoming>SequenceFlow_0ltcl3v</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_1uv2bmp</bpmn:outgoing>
+ <bpmn:outgoing>SequenceFlow_05cclyv</bpmn:outgoing>
+ </bpmn:exclusiveGateway>
+ <bpmn:sequenceFlow id="SequenceFlow_0ltcl3v" sourceRef="StartEvent_1" targetRef="ExclusiveGateway_0931occ" />
+ <bpmn:task id="Task_01ub4ta" name="approved">
+ <bpmn:incoming>SequenceFlow_1uv2bmp</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_005y1vw</bpmn:outgoing>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_1uv2bmp" sourceRef="ExclusiveGateway_0931occ" targetRef="Task_01ub4ta" />
+ <bpmn:task id="Task_0ceadr7" name="rejected">
+ <bpmn:incoming>SequenceFlow_05cclyv</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0gxnj5p</bpmn:outgoing>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_05cclyv" sourceRef="ExclusiveGateway_0931occ" targetRef="Task_0ceadr7" />
+ <bpmn:endEvent id="EndEvent_0uyi6wa">
+ <bpmn:incoming>SequenceFlow_0gxnj5p</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_0gxnj5p" sourceRef="Task_0ceadr7" targetRef="EndEvent_0uyi6wa" />
+ <bpmn:endEvent id="EndEvent_1ci8lj8">
+ <bpmn:incoming>SequenceFlow_005y1vw</bpmn:incoming>
+ </bpmn:endEvent>
+ <bpmn:sequenceFlow id="SequenceFlow_005y1vw" sourceRef="Task_01ub4ta" targetRef="EndEvent_1ci8lj8" />
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="173" y="102" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="ExclusiveGateway_0931occ_di" bpmnElement="ExclusiveGateway_0931occ" isMarkerVisible="true">
+ <dc:Bounds x="293" y="95" width="50" height="50" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="273" y="145" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0ltcl3v_di" bpmnElement="SequenceFlow_0ltcl3v">
+ <di:waypoint xsi:type="dc:Point" x="209" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="293" y="120" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="225.5" y="110" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Task_01ub4ta_di" bpmnElement="Task_01ub4ta">
+ <dc:Bounds x="471" y="80" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1uv2bmp_di" bpmnElement="SequenceFlow_1uv2bmp">
+ <di:waypoint xsi:type="dc:Point" x="343" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="471" y="120" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="362" y="110" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Task_0ceadr7_di" bpmnElement="Task_0ceadr7">
+ <dc:Bounds x="268" y="231" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_05cclyv_di" bpmnElement="SequenceFlow_05cclyv">
+ <di:waypoint xsi:type="dc:Point" x="318" y="145" />
+ <di:waypoint xsi:type="dc:Point" x="318" y="231" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="273" y="178" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="EndEvent_0uyi6wa_di" bpmnElement="EndEvent_0uyi6wa">
+ <dc:Bounds x="300" y="368" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="273" y="404" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0gxnj5p_di" bpmnElement="SequenceFlow_0gxnj5p">
+ <di:waypoint xsi:type="dc:Point" x="318" y="311" />
+ <di:waypoint xsi:type="dc:Point" x="318" y="368" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="273" y="329.5" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="EndEvent_1ci8lj8_di" bpmnElement="EndEvent_1ci8lj8">
+ <dc:Bounds x="651" y="102" width="36" height="36" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="624" y="138" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_005y1vw_di" bpmnElement="SequenceFlow_005y1vw">
+ <di:waypoint xsi:type="dc:Point" x="571" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="607" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="607" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="651" y="120" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="562" y="114.5" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>
--- /dev/null
+/*
+ * Copyright (C) 2016 Andrea Zagli <azagli@libero.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gstdio.h>
+
+#include "model.h"
+#include "instance.h"
+
+int
+main (int argc, char *argv[])
+{
+ ZakGFlowModel *model;
+ ZakGFlowInstance *instance;
+ GPtrArray *ar;
+
+ guint i;
+
+ model = zak_gflow_model_new_from_file (argv[1]);
+ if (model == NULL)
+ {
+ g_warning ("No model loaded from xml file <%s>.", argv[1]);
+ }
+ else
+ {
+ instance = zak_gflow_model_start (model, argv[2]);
+
+ /* wrong node_id */
+ zak_gflow_instance_exclusive_gateway_set_route (instance, "jon_doe", "new_route");
+
+ /* right node_id */
+ ar = zak_gflow_instance_exclusive_gateway_set_route (instance, "ExclusiveGateway_0931occ", "SequenceFlow_1uv2bmp");//05cclyv");
+ for (i = 0; i < ar->len; i++)
+ {
+ g_printf ("Currente node after exclusive_gateway_set_route: %s\n", (gchar *)g_ptr_array_index (ar, i));
+ }
+
+ /* general current nodes */
+ ar = zak_gflow_instance_get_current_nodes (instance);
+ for (i = 0; i < ar->len; i++)
+ {
+ g_printf ("Currente node: %s\n", (gchar *)g_ptr_array_index (ar, i));
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
+ <bpmn:process id="Process_1" isExecutable="false">
+ <bpmn:startEvent id="StartEvent_1">
+ <bpmn:outgoing>SequenceFlow_1okaoto</bpmn:outgoing>
+ </bpmn:startEvent>
+ <bpmn:task id="Task_1mry6ve">
+ <bpmn:incoming>SequenceFlow_1okaoto</bpmn:incoming>
+ <bpmn:outgoing>SequenceFlow_0cd9wu5</bpmn:outgoing>
+ <bpmn:outgoing>SequenceFlow_16m0ajv</bpmn:outgoing>
+ <bpmn:outgoing>SequenceFlow_0vq4xcx</bpmn:outgoing>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_1okaoto" sourceRef="StartEvent_1" targetRef="Task_1mry6ve" />
+ <bpmn:task id="Task_1uh9c57">
+ <bpmn:incoming>SequenceFlow_0cd9wu5</bpmn:incoming>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_0cd9wu5" sourceRef="Task_1mry6ve" targetRef="Task_1uh9c57" />
+ <bpmn:task id="Task_06lxgav">
+ <bpmn:incoming>SequenceFlow_16m0ajv</bpmn:incoming>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_16m0ajv" sourceRef="Task_1mry6ve" targetRef="Task_06lxgav" />
+ <bpmn:task id="Task_05zs44q">
+ <bpmn:incoming>SequenceFlow_0vq4xcx</bpmn:incoming>
+ </bpmn:task>
+ <bpmn:sequenceFlow id="SequenceFlow_0vq4xcx" sourceRef="Task_1mry6ve" targetRef="Task_05zs44q" />
+ </bpmn:process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+ <dc:Bounds x="173" y="102" width="36" height="36" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="Task_1mry6ve_di" bpmnElement="Task_1mry6ve">
+ <dc:Bounds x="282" y="153" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_1okaoto_di" bpmnElement="SequenceFlow_1okaoto">
+ <di:waypoint xsi:type="dc:Point" x="209" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="246" y="120" />
+ <di:waypoint xsi:type="dc:Point" x="246" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="282" y="193" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="198" y="110" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Task_1uh9c57_di" bpmnElement="Task_1uh9c57">
+ <dc:Bounds x="496" y="48" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0cd9wu5_di" bpmnElement="SequenceFlow_0cd9wu5">
+ <di:waypoint xsi:type="dc:Point" x="382" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="439" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="439" y="88" />
+ <di:waypoint xsi:type="dc:Point" x="496" y="88" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="394" y="130.5" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Task_06lxgav_di" bpmnElement="Task_06lxgav">
+ <dc:Bounds x="509" y="203" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_16m0ajv_di" bpmnElement="SequenceFlow_16m0ajv">
+ <di:waypoint xsi:type="dc:Point" x="382" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="446" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="446" y="243" />
+ <di:waypoint xsi:type="dc:Point" x="509" y="243" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="401" y="208" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="Task_05zs44q_di" bpmnElement="Task_05zs44q">
+ <dc:Bounds x="509" y="345" width="100" height="80" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="SequenceFlow_0vq4xcx_di" bpmnElement="SequenceFlow_0vq4xcx">
+ <di:waypoint xsi:type="dc:Point" x="382" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="446" y="193" />
+ <di:waypoint xsi:type="dc:Point" x="446" y="385" />
+ <di:waypoint xsi:type="dc:Point" x="509" y="385" />
+ <bpmndi:BPMNLabel>
+ <dc:Bounds x="401" y="279" width="90" height="20" />
+ </bpmndi:BPMNLabel>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</bpmn:definitions>