From: Andrea Zagli <azagli@libero.it>
Date: Wed, 16 Mar 2016 22:06:22 +0000 (+0100)
Subject: Complete refactoring of objects relations.
X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;p=libzakgflow

Complete refactoring of objects relations.
---

diff --git a/src/instance.c b/src/instance.c
index 69cc3ab..b160edd 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -51,8 +51,8 @@ static void zak_gflow_instance_finalize (GObject *gobject);
 
 typedef struct
 	{
-		xmlXPathContext *xpcontext;
-		GHashTable *ht_nodes;
+		ZakGFlowModel *model;
+		gchar *process_id;
 		GNode *nodes_history;
 	} ZakGFlowInstancePrivate;
 
@@ -96,7 +96,7 @@ static GPtrArray
 
 	priv = zak_gflow_instance_get_instance_private (instance);
 
-	cur = g_hash_table_lookup (priv->ht_nodes, node_id);
+	cur = zak_gflow_model_get_node (priv->model, priv->process_id, node_id);
 	if (cur != NULL)
 		{
 			_cur_node = g_node_insert_data (cur_node, -1, cur);
@@ -104,7 +104,7 @@ static GPtrArray
 				{
 					g_message ("%s: %s", cur->name, (gchar *)xmlGetProp (cur, (const xmlChar *)"name"));
 
-					xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, cur, (const xmlChar *)"child::bpmn:outgoing");
+					xnodeset = zak_gflow_model_xml_search (priv->model, cur, (const xmlChar *)"child::bpmn:outgoing");
 					if (xnodeset != NULL
 						&& xnodeset->nodeNr > 0)
 						{
@@ -130,7 +130,7 @@ static GPtrArray
 				{
 					g_message ("%s: %s", cur->name, (gchar *)xmlGetProp (cur, (const xmlChar *)"name"));
 
-					xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, cur, (const xmlChar *)"child::bpmn:outgoing");
+					xnodeset = zak_gflow_model_xml_search (priv->model, cur, (const xmlChar *)"child::bpmn:outgoing");
 					if (xnodeset != NULL)
 						{
 							for (i = 0; i < xnodeset->nodeNr; i++)
@@ -158,26 +158,27 @@ static GPtrArray
 
 /*+
  * zak_gflow_instance_new:
- * @ht_nodes:
+ * @model:
+ * @process_id:
  * @node_id:
  *
  */
 ZakGFlowInstance
-*zak_gflow_instance_new (xmlXPathContext *xpcontext, GHashTable *ht_nodes, const gchar *node_id)
+*zak_gflow_instance_new (ZakGFlowModel *model, const gchar *process_id, const gchar *node_id)
 {
 	ZakGFlowInstance *instance;
 	ZakGFlowInstancePrivate *priv;
 
-	g_return_val_if_fail (xpcontext != NULL, NULL);
-	g_return_val_if_fail (ht_nodes != NULL, NULL);
+	g_return_val_if_fail (ZAK_GFLOW_IS_MODEL (model), NULL);
+	g_return_val_if_fail (process_id != NULL, NULL);
 	g_return_val_if_fail (node_id != NULL, NULL);
 
 	instance = ZAK_GFLOW_INSTANCE (g_object_new (zak_gflow_instance_get_type (), NULL));
 
 	priv = zak_gflow_instance_get_instance_private (instance);
 
-	priv->xpcontext = xpcontext;
-	priv->ht_nodes = g_hash_table_ref (ht_nodes);
+	priv->model = model;
+	priv->process_id = g_strdup (process_id);
 
 	zak_gflow_instance_next (instance, node_id, priv->nodes_history);
 
@@ -244,7 +245,7 @@ GPtrArray
 
 	ret = g_ptr_array_new ();
 
-	xnode = (xmlNode *)g_hash_table_lookup (priv->ht_nodes, node_id);
+	xnode = zak_gflow_model_get_node (priv->model, priv->process_id, node_id);
 	if (xnode != NULL)
 		{
 			node = g_node_find (priv->nodes_history,
@@ -259,7 +260,7 @@ GPtrArray
 			else if (node != NULL)
 				{
 					/* move to next */
-					xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, xnode, (const xmlChar *)"child::bpmn:outgoing");
+					xnodeset = zak_gflow_model_xml_search (priv->model, xnode, (const xmlChar *)"child::bpmn:outgoing");
 					if (xnodeset != NULL)
 						{
 							for (i = 0; i < xnodeset->nodeNr; i++)
@@ -311,7 +312,7 @@ GPtrArray
 
 	ret = g_ptr_array_new ();
 
-	xnode = (xmlNode *)g_hash_table_lookup (priv->ht_nodes, node_id);
+	xnode = zak_gflow_model_get_node (priv->model, priv->process_id, node_id);
 	if (xnode != NULL)
 		{
 			node = g_node_find (priv->nodes_history,
diff --git a/src/instance.h b/src/instance.h
index 796c60f..d02d200 100644
--- a/src/instance.h
+++ b/src/instance.h
@@ -25,6 +25,8 @@
 
 #include <libxml/xpath.h>
 
+#include "model.h"
+
 
 G_BEGIN_DECLS
 
@@ -38,7 +40,7 @@ struct _ZakGFlowInstanceClass
 };
 
 
-ZakGFlowInstance *zak_gflow_instance_new (xmlXPathContext *xpcontext, GHashTable *ht_nodes, const gchar *node_id);
+ZakGFlowInstance *zak_gflow_instance_new (ZakGFlowModel *model, const gchar *process_id, const gchar *node_id);
 
 GPtrArray *zak_gflow_instance_get_current_nodes (ZakGFlowInstance *instance);
 
diff --git a/src/model.c b/src/model.c
index 02b360d..c7df7a5 100644
--- a/src/model.c
+++ b/src/model.c
@@ -54,6 +54,7 @@ typedef struct
 		xmlDoc *xdoc;
 		xmlNode *xroot;
 		xmlXPathContext *xpcontext;
+		GHashTable *ht_processes; // each process is an other GHashTable with nodes list
 	} ZakGFlowModelPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (ZakGFlowModel, zak_gflow_model, G_TYPE_OBJECT)
@@ -100,6 +101,8 @@ zak_gflow_model_init (ZakGFlowModel *zak_gflow_model)
 
 	ZakGFlowModelPrivate *priv = zak_gflow_model_get_instance_private (zak_gflow_model);
 
+	priv->ht_processes = g_hash_table_new (g_str_hash, g_str_equal);
+
 #ifdef G_OS_WIN32
 
 	gchar *moddir;
@@ -148,6 +151,19 @@ ZakGFlowModel
 	xmlNs *ns;
 	gchar *prefix;
 
+	GPtrArray *ar_processes;
+	gint i;
+
+	gchar *expr;
+
+	xmlNodeSet *xnodeset;
+
+	xmlNode *cur;
+
+	GHashTable *ht_nodes;
+
+	xmlChar *prop;
+
 	g_return_val_if_fail (xmldoc != NULL, NULL);
 
 	model = ZAK_GFLOW_MODEL (g_object_new (zak_gflow_model_get_type (), NULL));
@@ -189,6 +205,34 @@ ZakGFlowModel
 
 					ns = ns->next;
 				}
+
+			/* creation of processes list */
+			xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, priv->xroot, (const xmlChar *)"child::bpmn:process");
+			if (xnodeset != NULL
+				&& xnodeset->nodeNr > 0)
+				{
+					for (i = 0; i < xnodeset->nodeNr; i++)
+						{
+							/* for each process */
+							ht_nodes = g_hash_table_new (g_str_hash, g_str_equal);
+							g_hash_table_insert (priv->ht_processes, g_strdup ((gchar *)xmlGetProp (xnodeset->nodeTab[i], (const xmlChar *)"id")), (gpointer)g_hash_table_ref (ht_nodes));
+
+							/* creation of an hash table with all nodes */
+							cur = xnodeset->nodeTab[i]->children;
+							while (cur != NULL)
+								{
+									prop = xmlGetProp (cur, (const xmlChar *)"id");
+									if (prop != NULL)
+										{
+											g_hash_table_insert (ht_nodes, (gpointer)g_strdup ((gchar *)prop), (gpointer)cur);
+											xmlFree (prop);
+										}
+
+									cur = cur->next;
+								}
+						}
+				}
+
 		}
 
 	return model;
@@ -228,93 +272,62 @@ GPtrArray
 	GPtrArray *ar;
 	ZakGFlowModelPrivate *priv;
 
-	xmlNodeSet *xnodeset;
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
 
-	gint i;
+	g_return_val_if_fail (ZAK_GFLOW_IS_MODEL (model), NULL);
 
-	ar = NULL;
+	ar = g_ptr_array_new ();
 
 	priv = zak_gflow_model_get_instance_private (model);
 
-	xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, priv->xroot, (const xmlChar *)"child::bpmn:process");
-	if (xnodeset != NULL
-		&& xnodeset->nodeNr > 0)
+	g_hash_table_iter_init (&iter, priv->ht_processes);
+	while (g_hash_table_iter_next (&iter, &key, &value))
 		{
-			ar = g_ptr_array_new ();
-			for (i = 0; i < xnodeset->nodeNr; i++)
-				{
-					g_ptr_array_add (ar, g_strdup ((gchar *)xmlGetProp (xnodeset->nodeTab[i], (const xmlChar *)"id")));
-				}
+			g_ptr_array_add (ar, g_strdup (key));
 		}
 
 	return ar;
 }
 
-/**
- * zak_gflow_model_start:
- * @model:
- * @model_id:
- *
- */
-ZakGFlowInstance
-*zak_gflow_model_start (ZakGFlowModel *model, const gchar *model_id)
+xmlNodeSet
+*zak_gflow_model_xml_search (ZakGFlowModel *model, xmlNode *xnode_start, const xmlChar *xpath_expr)
 {
-	ZakGFlowInstance *instance;
-
 	ZakGFlowModelPrivate *priv;
 
-	xmlNodeSet *xnodeset;
+	priv = zak_gflow_model_get_instance_private (model);
 
-	gchar *expr;
+	return zak_gflow_commons_xml_search (priv->xpcontext, xnode_start, xpath_expr);
+}
 
-	GHashTable *ht_nodes;
+xmlNode
+*zak_gflow_model_get_node (ZakGFlowModel *model, const gchar *process_id, const gchar *node_id)
+{
+	xmlNode *ret;
 
-	xmlNode *cur;
+	ZakGFlowModelPrivate *priv;
 
-	instance = NULL;
+	GHashTable *ht_nodes;
 
 	priv = zak_gflow_model_get_instance_private (model);
 
-	expr = g_strdup_printf ("child::bpmn:process[@id='%s']", model_id);
-	xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, priv->xroot, (const xmlChar *)expr);
-	g_free (expr);
-	if (xnodeset != NULL
-		&& xnodeset->nodeNr > 0)
+	ht_nodes = (GHashTable *)g_hash_table_lookup (priv->ht_processes, process_id);
+	if (ht_nodes == NULL)
 		{
-			/* creation of an hash table with all nodes */
-			ht_nodes = g_hash_table_new (g_str_hash, g_str_equal);
-
-			cur = xnodeset->nodeTab[0]->children;
-			while (cur != NULL)
-				{
-					xmlChar *prop;
-
-					prop = xmlGetProp (cur, (const xmlChar *)"id");
-					if (prop != NULL)
-						{
-							g_hash_table_insert (ht_nodes, (gpointer)g_strdup ((gchar *)prop), (gpointer)cur);
-							xmlFree (prop);
-						}
-
-					cur = cur->next;
-				}
-
-			/* find start node */
-			xnodeset = zak_gflow_commons_xml_search (priv->xpcontext, xnodeset->nodeTab[0], (const xmlChar *)"child::bpmn:startEvent");
-			if (xnodeset != NULL
-				&& xnodeset->nodeNr > 0)
-				{
-					instance = zak_gflow_instance_new (priv->xpcontext, ht_nodes, (const gchar *)xmlGetProp (xnodeset->nodeTab[0], (const xmlChar *)"id"));
-				}
-
-			g_hash_table_unref (ht_nodes);
+			ret = NULL;
+			g_warning ("No process_id <%s> found.", process_id);
 		}
 	else
 		{
-			g_warning ("No process with id <%s>.", model_id);
+			ret = (xmlNode *)g_hash_table_lookup (ht_nodes, node_id);
+			if (ret == NULL)
+				{
+					g_warning ("No node_id <%s> found.", node_id);
+				}
 		}
 
-	return instance;
+	return ret;
 }
 
 /* PRIVATE */
diff --git a/src/model.h b/src/model.h
index 7f62f3c..3ac6a6d 100644
--- a/src/model.h
+++ b/src/model.h
@@ -23,8 +23,7 @@
 #include <glib-object.h>
 
 #include <libxml/tree.h>
-
-#include "instance.h"
+#include <libxml/xpath.h>
 
 
 G_BEGIN_DECLS
@@ -44,7 +43,9 @@ ZakGFlowModel *zak_gflow_model_new_from_file (const gchar *filename);
 
 GPtrArray *zak_gflow_model_list_processes (ZakGFlowModel *model);
 
-ZakGFlowInstance *zak_gflow_model_start (ZakGFlowModel *model, const gchar *model_id);
+xmlNodeSet *zak_gflow_model_xml_search (ZakGFlowModel *model, xmlNode *xnode_start, const xmlChar *xpath_expr);
+
+xmlNode *zak_gflow_model_get_node (ZakGFlowModel *model, const gchar *process_id, const gchar *node_id);
 
 
 G_END_DECLS
diff --git a/tests/exclusive_gateway.c b/tests/exclusive_gateway.c
index 455d02e..5115496 100644
--- a/tests/exclusive_gateway.c
+++ b/tests/exclusive_gateway.c
@@ -37,7 +37,7 @@ main (int argc, char *argv[])
 		}
 	else
 		{
-			instance = zak_gflow_model_start (model, argv[2]);
+			instance = zak_gflow_instance_new (model, argv[2], "StartEvent_1");
 
 			/* wrong node_id */
 			zak_gflow_instance_exclusive_gateway_set_route (instance, "jon_doe", "new_route");
diff --git a/tests/instance.c b/tests/instance.c
index 508888b..877221a 100644
--- a/tests/instance.c
+++ b/tests/instance.c
@@ -37,7 +37,7 @@ main (int argc, char *argv[])
 		}
 	else
 		{
-			instance = zak_gflow_model_start (model, argv[2]);
+			instance = zak_gflow_instance_new (model, argv[2], "StartEvent_1");
 
 			/* general current nodes */
 			ar = zak_gflow_instance_get_current_nodes (instance);