From: Andrea Zagli Date: Sun, 14 May 2017 12:38:46 +0000 (+0200) Subject: Started implementation (only one level) of ZakFormValidatorComposite. X-Git-Tag: v0.1.0~1^2~14^2~2 X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=924cc32f0c820a650e7dac19ae579d31cc723e55;p=zakform%2Flibzakform Started implementation (only one level) of ZakFormValidatorComposite. --- diff --git a/src/Makefile.am b/src/Makefile.am index 022e7ff..6c6f9b6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,8 @@ libzakform_la_SOURCES = \ formiprovider.c \ formvalidator.c \ formvalidatorcompare.c \ - formvalidatorcomparedate.c + formvalidatorcomparedate.c \ + formvalidatorcomposite.c libzakform_la_LDFLAGS = -no-undefined @@ -48,7 +49,8 @@ libzakform_include_HEADERS = \ formiprovider.h \ formvalidator.h \ formvalidatorcompare.h \ - formvalidatorcomparedate.h + formvalidatorcomparedate.h \ + formvalidatorcomposite.h libzakform_includedir = $(includedir)/libzakform diff --git a/src/commons.c b/src/commons.c index a1d2892..c4d49f9 100644 --- a/src/commons.c +++ b/src/commons.c @@ -66,7 +66,11 @@ zak_form_get_compare_type_from_string (const gchar *str) } else { - g_warning ("Compare type «%s» not supported.", str); + if (str != NULL + && g_strcmp0 (str, "") != 0) + { + g_warning ("Compare type «%s» not supported.", str); + } ret = ZAK_FORM_COMPARE_TYPE_NONE; } diff --git a/src/form.c b/src/form.c index c14a235..226ca90 100644 --- a/src/form.c +++ b/src/form.c @@ -38,20 +38,19 @@ typedef gboolean (* FormElementXmlParsingFunc) (ZakFormElement *, xmlNodePtr); typedef GObject *(* FormElementExtensionConstructorFunc) (void); typedef gboolean (* FormElementExtensionXmlParsingFunc) (GObject *, xmlNodePtr); typedef ZakFormElementFilter *(* FormElementFilterConstructorFunc) (void); -typedef ZakFormElementValidator *(* FormElementValidatorConstructorFunc) (void); typedef ZakFormValidator *(* FormValidatorConstructorFunc) (void); static void zak_form_form_class_init (ZakFormFormClass *class); static void zak_form_form_init (ZakFormForm *zak_form_form); static void zak_form_form_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); + guint property_id, + const GValue *value, + GParamSpec *pspec); static void zak_form_form_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); + guint property_id, + GValue *value, + GParamSpec *pspec); static void zak_form_form_dispose (GObject *gobject); static void zak_form_form_finalize (GObject *gobject); @@ -166,7 +165,7 @@ zak_form_form_element_xml_parsing (ZakFormForm *zakform, ZakFormElement *element FormElementExtensionConstructorFunc extension_constructor; FormElementExtensionXmlParsingFunc extension_xml_parsing; FormElementFilterConstructorFunc filter_constructor; - FormElementValidatorConstructorFunc validator_constructor; + ZakFormElementValidatorConstructorFunc validator_constructor; gboolean to_unlink; xmlNode *xnode_tmp; @@ -180,7 +179,7 @@ zak_form_form_element_xml_parsing (ZakFormForm *zakform, ZakFormElement *element if (xmlStrcmp (xnode->name, (const xmlChar *)"extension") == 0) { - type = xmlGetProp (xnode, (const xmlChar *)"type"); + type = (gchar *)xmlGetProp (xnode, (const xmlChar *)"type"); /* for each module */ for (i = 0; i < priv->ar_modules->len; i++) @@ -217,7 +216,7 @@ zak_form_form_element_xml_parsing (ZakFormForm *zakform, ZakFormElement *element } else if (xmlStrcmp (xnode->name, (const xmlChar *)"filter") == 0) { - type = xmlGetProp (xnode, (const xmlChar *)"type"); + type = (gchar *)xmlGetProp (xnode, (const xmlChar *)"type"); /* for each module */ for (i = 0; i < priv->ar_modules->len; i++) @@ -246,27 +245,17 @@ zak_form_form_element_xml_parsing (ZakFormForm *zakform, ZakFormElement *element } else if (xmlStrcmp (xnode->name, (const xmlChar *)"validator") == 0) { - type = xmlGetProp (xnode, (const xmlChar *)"type"); + type = (gchar *)xmlGetProp (xnode, (const xmlChar *)"type"); - /* for each module */ - for (i = 0; i < priv->ar_modules->len; i++) + validator_constructor = zak_form_get_form_element_validator (zakform, type); + if (validator_constructor != NULL) { - if (g_module_symbol ((GModule *)g_ptr_array_index (priv->ar_modules, i), - g_strconcat (type, "_new", NULL), - (gpointer *)&validator_constructor)) - { - if (validator_constructor != NULL) - { - validator = validator_constructor (); - zak_form_element_add_validator (element, validator); - - zak_form_element_validator_xml_parsing (validator, xnode); + validator = validator_constructor (); + zak_form_element_add_validator (element, validator); - break; - } - } + zak_form_element_validator_xml_parsing (validator, xnode); } - if (i >= priv->ar_modules->len) + else { g_warning ("Validator «%s» not found.", type); } @@ -289,6 +278,41 @@ zak_form_form_element_xml_parsing (ZakFormForm *zakform, ZakFormElement *element } } +/** + * zak_form_get_form_validator: + * @zakform: + * @namespace: + * + * Returns: + */ +ZakFormElementValidatorConstructorFunc +zak_form_get_form_element_validator (ZakFormForm *zakform, const gchar *namespace) +{ + ZakFormFormPrivate *priv; + + ZakFormElementValidatorConstructorFunc validator_constructor; + + guint i; + + g_return_val_if_fail (ZAK_FORM_IS_FORM (zakform), NULL); + + priv = zak_form_form_get_instance_private (zakform); + + validator_constructor = NULL; + + for (i = 0; i < priv->ar_modules->len; i++) + { + if (g_module_symbol ((GModule *)g_ptr_array_index (priv->ar_modules, i), + g_strconcat (namespace, "_new", NULL), + (gpointer *)&validator_constructor)) + { + break; + } + } + + return validator_constructor; +} + /** * zak_form_form_load_from_xml: * @zakform: @@ -339,16 +363,16 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) { if (xmlStrcmp (cur->name, (const xmlChar *)"element") == 0) { - element = NULL; + element = NULL; - type = xmlGetProp (cur, (const xmlChar *)"type"); + type = (gchar *)xmlGetProp (cur, (const xmlChar *)"type"); /* for each module */ for (i = 0; i < priv->ar_modules->len; i++) { if (g_module_symbol ((GModule *)g_ptr_array_index (priv->ar_modules, i), - g_strconcat (type, "_new", NULL), - (gpointer *)&element_constructor)) + g_strconcat (type, "_new", NULL), + (gpointer *)&element_constructor)) { if (element_constructor != NULL) { @@ -361,8 +385,8 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) zak_form_form_element_xml_parsing (zakform, element, cur_clean); if (g_module_symbol ((GModule *)g_ptr_array_index (priv->ar_modules, i), - g_strconcat (type, "_xml_parsing", NULL), - (gpointer *)&element_xml_parsing)) + g_strconcat (type, "_xml_parsing", NULL), + (gpointer *)&element_xml_parsing)) { if (element_xml_parsing != NULL) { @@ -396,21 +420,21 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) xnodeset = xpresult->nodesetval; for (y = 0; y < xnodeset->nodeNr; y++) { - type = xmlGetProp (xnodeset->nodeTab[y], (const xmlChar *)"type"); + type = (gchar *)xmlGetProp (xnodeset->nodeTab[y], (const xmlChar *)"type"); /* for each module */ for (i = 0; i < priv->ar_modules->len; i++) { if (g_module_symbol ((GModule *)g_ptr_array_index (priv->ar_modules, i), - g_strconcat (type, "_new", NULL), - (gpointer *)&validator_constructor)) + g_strconcat (type, "_new", NULL), + (gpointer *)&validator_constructor)) { if (validator_constructor != NULL) { validator = validator_constructor (); zak_form_form_add_validator (zakform, validator); - zak_form_validator_xml_parsing (validator, xnodeset->nodeTab[y], priv->ar_elements); + zak_form_validator_xml_parsing (validator, xnodeset->nodeTab[y], zakform); break; } diff --git a/src/form.h b/src/form.h index ee78317..55e7991 100644 --- a/src/form.h +++ b/src/form.h @@ -44,6 +44,9 @@ struct _ZakFormFormClass void (*element_added) (ZakFormForm *zakform, ZakFormElement *element); }; +typedef ZakFormElementValidator *(* ZakFormElementValidatorConstructorFunc) (void); + +ZakFormElementValidatorConstructorFunc zak_form_get_form_element_validator (ZakFormForm *zakform, const gchar *namespace); gboolean zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc); gboolean zak_form_form_load_from_file (ZakFormForm *zakform, const gchar *filename); diff --git a/src/formelementvalidatordate.c b/src/formelementvalidatordate.c index b4130cb..55f0ca9 100644 --- a/src/formelementvalidatordate.c +++ b/src/formelementvalidatordate.c @@ -86,6 +86,8 @@ zak_form_element_validator_date_init (ZakFormElementValidatorDate *zak_form_elem { ZakFormElementValidatorDatePrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_DATE_GET_PRIVATE (zak_form_element); + priv->compare_type = ZAK_FORM_COMPARE_TYPE_NONE; + priv->compare_value = NULL; priv->format = NULL; } diff --git a/src/formelementvalidatornotempty.c b/src/formelementvalidatornotempty.c index 87d976e..59d95eb 100644 --- a/src/formelementvalidatornotempty.c +++ b/src/formelementvalidatornotempty.c @@ -33,13 +33,13 @@ static void zak_form_element_validator_notempty_class_init (ZakFormElementValida static void zak_form_element_validator_notempty_init (ZakFormElementValidatorNotempty *zak_form_element); static void zak_form_element_validator_notempty_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); + guint property_id, + const GValue *value, + GParamSpec *pspec); static void zak_form_element_validator_notempty_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); + guint property_id, + GValue *value, + GParamSpec *pspec); static void zak_form_element_validator_notempty_dispose (GObject *gobject); static void zak_form_element_validator_notempty_finalize (GObject *gobject); @@ -171,9 +171,9 @@ gchar /* PRIVATE */ static void zak_form_element_validator_notempty_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { ZakFormElementValidatorNotempty *validator = (ZakFormElementValidatorNotempty *)object; ZakFormElementValidatorNotemptyPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_NOTEMPTY_GET_PRIVATE (validator); @@ -192,9 +192,9 @@ zak_form_element_validator_notempty_set_property (GObject *object, static void zak_form_element_validator_notempty_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) + guint property_id, + GValue *value, + GParamSpec *pspec) { ZakFormElementValidatorNotempty *validator = (ZakFormElementValidatorNotempty *)object; ZakFormElementValidatorNotemptyPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_NOTEMPTY_GET_PRIVATE (validator); @@ -237,7 +237,7 @@ zak_form_element_validator_notempty_finalize (GObject *gobject) static gboolean zak_form_element_validator_notempty_validate (ZakFormElementValidator *validator, - const gchar *value) + const gchar *value) { gboolean ret; diff --git a/src/formvalidator.c b/src/formvalidator.c index 36216fd..24c1f8b 100644 --- a/src/formvalidator.c +++ b/src/formvalidator.c @@ -22,6 +22,7 @@ #include +#include "form.h" #include "formvalidator.h" enum @@ -98,12 +99,12 @@ zak_form_validator_init (ZakFormValidator *zak_form_validator) * zak_form_validator_xml_parsing: * @validator: * @xnode: - * @ar_elements: + * @form: * * Retuns: */ gboolean -zak_form_validator_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements) +zak_form_validator_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form) { gboolean ret; @@ -136,7 +137,7 @@ zak_form_validator_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPt if (ZAK_FORM_VALIDATOR_GET_CLASS (validator)->xml_parsing != NULL) { - ret = ZAK_FORM_VALIDATOR_GET_CLASS (validator)->xml_parsing (validator, xnode, ar_elements); + ret = ZAK_FORM_VALIDATOR_GET_CLASS (validator)->xml_parsing (validator, xnode, form); } return ret; @@ -255,9 +256,9 @@ zak_form_validator_set_enabled (ZakFormValidator *validator, gboolean enabled) /* PRIVATE */ static void zak_form_validator_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { ZakFormValidator *zak_form_validator = (ZakFormValidator *)object; ZakFormValidatorPrivate *priv = zak_form_validator_get_instance_private (zak_form_validator); @@ -284,9 +285,9 @@ zak_form_validator_set_property (GObject *object, static void zak_form_validator_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) + guint property_id, + GValue *value, + GParamSpec *pspec) { ZakFormValidator *zak_form_validator = (ZakFormValidator *)object; ZakFormValidatorPrivate *priv = zak_form_validator_get_instance_private (zak_form_validator); diff --git a/src/formvalidator.h b/src/formvalidator.h index a5b43b5..bdc01a1 100644 --- a/src/formvalidator.h +++ b/src/formvalidator.h @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #ifndef _ZAK_FORM_VALIDATOR_H_ #define _ZAK_FORM_VALIDATOR_H_ @@ -34,11 +35,11 @@ struct _ZakFormValidatorClass { GObjectClass parent_class; - gboolean (*xml_parsing) (ZakFormValidator *self, xmlNode *xnode, GPtrArray *ar_elements); + gboolean (*xml_parsing) (ZakFormValidator *self, xmlNode *xnode, gpointer zakform); gboolean (*validate) (ZakFormValidator *self); }; -gboolean zak_form_validator_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements); +gboolean zak_form_validator_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer zakform); gchar *zak_form_validator_get_id (ZakFormValidator *validator); void zak_form_validator_set_id (ZakFormValidator *validator, const gchar *id); diff --git a/src/formvalidatorcompare.c b/src/formvalidatorcompare.c index 1d0f89b..2053b14 100644 --- a/src/formvalidatorcompare.c +++ b/src/formvalidatorcompare.c @@ -25,6 +25,7 @@ #include #include "commons.h" +#include "form.h" #include "formvalidator.h" #include "formvalidatorcompare.h" @@ -43,7 +44,7 @@ static void zak_form_validator_compare_get_property (GObject *object, static void zak_form_validator_compare_dispose (GObject *gobject); static void zak_form_validator_compare_finalize (GObject *gobject); -static gboolean zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements); +static gboolean zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form); static gboolean zak_form_validator_compare_validate (ZakFormValidator *validator_notempty); struct _ZakFormValidatorCompare @@ -111,11 +112,11 @@ ZakFormValidatorCompare * zak_form_validator_compare_xml_parsing: * @validator: * @xnode: - * @ar_elements: + * @form: * */ static gboolean -zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements) +zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form) { gchar *prop; @@ -126,7 +127,7 @@ zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xn g_free (prop); prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"element1"); - priv->v1 = zak_form_get_element_by_id (ar_elements, prop); + priv->v1 = zak_form_form_get_element_by_id ((ZakFormForm *)form, prop); if (!ZAK_FORM_IS_ELEMENT (priv->v1)) { g_warning ("Validator compare: element1 isn't a ZakFormElement."); @@ -134,7 +135,7 @@ zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xn g_free (prop); prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"element2"); - priv->v2 = zak_form_get_element_by_id (ar_elements, prop); + priv->v2 = zak_form_form_get_element_by_id ((ZakFormForm *)form, prop); if (!ZAK_FORM_IS_ELEMENT (priv->v2)) { g_warning ("Validator compare: element2 isn't a ZakFormElement."); diff --git a/src/formvalidatorcomparedate.c b/src/formvalidatorcomparedate.c index d56864c..13089ee 100644 --- a/src/formvalidatorcomparedate.c +++ b/src/formvalidatorcomparedate.c @@ -25,6 +25,7 @@ #include #include "commons.h" +#include "form.h" #include "formvalidator.h" #include "formvalidatorcomparedate.h" @@ -43,7 +44,7 @@ static void zak_form_validator_compare_date_get_property (GObject *object, static void zak_form_validator_compare_date_dispose (GObject *gobject); static void zak_form_validator_compare_date_finalize (GObject *gobject); -static gboolean zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements); +static gboolean zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form); static gboolean zak_form_validator_compare_date_validate (ZakFormValidator *validator_notempty); struct _ZakFormValidatorCompareDate @@ -114,11 +115,11 @@ ZakFormValidatorCompareDate * zak_form_validator_compare_date_xml_parsing: * @validator: * @xnode: - * @ar_elements: + * @form: * */ static gboolean -zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements) +zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form) { gchar *prop; @@ -129,11 +130,11 @@ zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNod g_free (prop); prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"element1"); - priv->v1 = zak_form_get_element_by_id (ar_elements, prop); + priv->v1 = zak_form_form_get_element_by_id ((ZakFormForm *)form, prop); g_free (prop); prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"element2"); - priv->v2 = zak_form_get_element_by_id (ar_elements, prop); + priv->v2 = zak_form_form_get_element_by_id ((ZakFormForm *)form, prop); g_free (prop); prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"format1"); diff --git a/src/formvalidatorcomposite.c b/src/formvalidatorcomposite.c new file mode 100644 index 0000000..1a11f29 --- /dev/null +++ b/src/formvalidatorcomposite.c @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2017 Andrea Zagli + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include + +#include "commons.h" +#include "form.h" +#include "formelement.h" +#include "formelementvalidator.h" +#include "formvalidator.h" +#include "formvalidatorcomposite.h" + +static void zak_form_validator_composite_class_init (ZakFormValidatorCompositeClass *class); +static void zak_form_validator_composite_init (ZakFormValidatorComposite *validator); + +static void zak_form_validator_composite_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void zak_form_validator_composite_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void zak_form_validator_composite_dispose (GObject *gobject); +static void zak_form_validator_composite_finalize (GObject *gobject); + +static gboolean zak_form_validator_composite_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form); +static gboolean zak_form_validator_composite_validate (ZakFormValidator *validator_notempty); + +struct _ZakFormValidatorComposite +{ + ZakFormValidator parent_instance; + + /* Other members, including private data. */ +}; + +#define ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZAK_FORM_TYPE_VALIDATOR_COMPOSITE, ZakFormValidatorCompositePrivate)) + +typedef struct _ZakFormValidatorCompositePrivate ZakFormValidatorCompositePrivate; +struct _ZakFormValidatorCompositePrivate + { + GNode *tree; + }; + +G_DEFINE_TYPE (ZakFormValidatorComposite, zak_form_validator_composite, ZAK_FORM_TYPE_VALIDATOR) + +typedef enum + { + LOGIC_TYPE_IF = 1, + LOGIC_TYPE_AND, + LOGIC_TYPE_OR + } LogicType; + +typedef struct + { + LogicType type; + ZakFormElementValidator *validator; + ZakFormElement *element; + gchar *message; + } Node; + +static void +zak_form_validator_composite_class_init (ZakFormValidatorCompositeClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + ZakFormValidatorClass *parent_class = ZAK_FORM_VALIDATOR_CLASS (class); + + object_class->set_property = zak_form_validator_composite_set_property; + object_class->get_property = zak_form_validator_composite_get_property; + object_class->dispose = zak_form_validator_composite_dispose; + object_class->finalize = zak_form_validator_composite_finalize; + + parent_class->xml_parsing = zak_form_validator_composite_xml_parsing; + parent_class->validate = zak_form_validator_composite_validate; + + g_type_class_add_private (object_class, sizeof (ZakFormValidatorCompositePrivate)); +} + +static void +zak_form_validator_composite_init (ZakFormValidatorComposite *validator) +{ + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + priv->tree = NULL; +} + +/** + * zak_form_validator_composite_new: + * + * Returns: the newly created #ZakFormValidatorComposite object. + */ +ZakFormValidatorComposite +*zak_form_validator_composite_new () +{ + ZakFormValidatorComposite *zak_form_validator_composite; + + zak_form_validator_composite = ZAK_FORM_VALIDATOR_COMPOSITE (g_object_new (zak_form_validator_composite_get_type (), NULL)); + + return zak_form_validator_composite; +} + +static void +_zak_form_validator_composite_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, ZakFormForm *form, GNode *tree) +{ + xmlNode *cur; + + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + cur = xnode->children; + while (cur) + { + if (xmlStrEqual (cur->name, (xmlChar *)"logic")) + { + GNode *gnode; + Node *n; + + n = (Node *)g_new0 (Node, 1); + + if (xmlStrEqual (xmlGetProp (cur, (xmlChar *)"type"), (xmlChar *)"if")) + { + n->type = LOGIC_TYPE_IF; + } + else if (xmlStrEqual (xmlGetProp (cur, (xmlChar *)"type"), (xmlChar *)"and")) + { + n->type = LOGIC_TYPE_AND; + } + else if (xmlStrEqual (xmlGetProp (cur, (xmlChar *)"type"), (xmlChar *)"or")) + { + n->type = LOGIC_TYPE_OR; + } + else + { + g_warning ("Logic type «%s» not supported.", + xmlGetProp (cur, (xmlChar *)"type")); + continue; + } + + n->message = g_strdup ((gchar *)xmlGetProp (cur, (xmlChar *)"message")); + + if (tree == NULL) + { + gnode = g_node_new (n); + priv->tree = gnode; + } + else + { + gnode = g_node_append (tree, g_node_new (n)); + } + + _zak_form_validator_composite_xml_parsing (validator, cur, form, gnode); + } + else if (xmlStrEqual (cur->name, (xmlChar *)"validator")) + { + ZakFormElement *element; + ZakFormElementValidatorConstructorFunc validator_constructor; + Node *n; + + element = zak_form_form_get_element_by_id (form, (gchar *)xmlGetProp (cur, (xmlChar *)"element")); + if (!ZAK_FORM_IS_ELEMENT (element)) + { + g_warning ("Element «%s» not present in form.", + (gchar *)xmlGetProp (cur, (xmlChar *)"element")); + continue; + } + + n = (Node *)g_new0 (Node, 1); + + validator_constructor = zak_form_get_form_element_validator (form, (gchar *)xmlGetProp (cur, (xmlChar *)"type")); + if (validator_constructor == NULL) + { + g_warning ("Element «%s» not found.", + (gchar *)xmlGetProp (cur, (xmlChar *)"type")); + continue; + } + + n->validator = validator_constructor (); + zak_form_element_validator_xml_parsing (n->validator, cur); + + n->element = element; + + if (tree == NULL) + { + priv->tree = g_node_new (n); + } + else + { + g_node_append (tree, g_node_new (n)); + } + } + + cur = cur->next; + } +} + +static gboolean +traverse_func (GNode *node, + gpointer data) +{ + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE ((ZakFormValidator *)data); + + Node *n = (Node *)node->data; + + if (n->type > 0) + { + g_warning ("Node logic type %d message «%s»", n->type, n->message); + } + else + { + g_warning ("Node validator for element «%s»", zak_form_element_get_name (n->element)); + } + + return FALSE; +} + +/** + * zak_form_validator_composite_xml_parsing: + * @validator: + * @xnode: + * @form: + * + */ +static gboolean +zak_form_validator_composite_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, gpointer form) +{ + + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + _zak_form_validator_composite_xml_parsing (validator, xnode, (ZakFormForm *)form, NULL); + + if (priv->tree != NULL) + { + g_node_traverse (priv->tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1, traverse_func, (gpointer)validator); + } + + return TRUE; +} + +/* PRIVATE */ +static void +zak_form_validator_composite_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorComposite *validator = (ZakFormValidatorComposite *)object; + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_composite_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorComposite *validator = (ZakFormValidatorComposite *)object; + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_composite_dispose (GObject *gobject) +{ + ZakFormValidatorComposite *validator = (ZakFormValidatorComposite *)gobject; + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->dispose (gobject); +} + +static void +zak_form_validator_composite_finalize (GObject *gobject) +{ + ZakFormValidatorComposite *validator = (ZakFormValidatorComposite *)gobject; + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->finalize (gobject); +} + +static gboolean +zak_form_validator_composite_validate (ZakFormValidator *validator) +{ + gboolean ret; + + GNode *root; + GNode *child; + Node *n; + Node *n_child; + + guint i; + guint children; + + ZakFormValidatorCompositePrivate *priv = ZAK_FORM_VALIDATOR_COMPOSITE_GET_PRIVATE (validator); + + if (priv->tree != NULL) + { + root = g_node_get_root (priv->tree); + + n = (Node *)root->data; + + switch (n->type) + { + case LOGIC_TYPE_IF: + break; + + case LOGIC_TYPE_AND: + ret = TRUE; + break; + + case LOGIC_TYPE_OR: + ret = FALSE; + break; + } + + children = g_node_n_children (root); + for (i = 0; i < children; i++) + { + child = g_node_nth_child (root, i); + n_child = (Node *)child->data; + switch (n->type) + { + case LOGIC_TYPE_IF: + break; + + case LOGIC_TYPE_AND: + ret = (ret && zak_form_element_validator_validate (n_child->validator, + zak_form_element_get_value (n_child->element))); + break; + + case LOGIC_TYPE_OR: + ret = (ret || zak_form_element_validator_validate (n_child->validator, + zak_form_element_get_value (n_child->element))); + break; + } + } + + if (!ret) + { + zak_form_validator_set_message (ZAK_FORM_VALIDATOR (validator), n->message); + } + } + else + { + ret = TRUE; + } + + return ret; +} diff --git a/src/formvalidatorcomposite.h b/src/formvalidatorcomposite.h new file mode 100644 index 0000000..e3bd870 --- /dev/null +++ b/src/formvalidatorcomposite.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 Andrea Zagli + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __ZAK_FORM_VALIDATOR_COMPOSITE_H__ +#define __ZAK_FORM_VALIDATOR_COMPOSITE_H__ + + +#include + +#include + +#include "form.h" +#include "formvalidator.h" + + +G_BEGIN_DECLS + + +#define ZAK_FORM_TYPE_VALIDATOR_COMPOSITE zak_form_validator_composite_get_type () +G_DECLARE_FINAL_TYPE (ZakFormValidatorComposite, zak_form_validator_composite, ZAK_FORM, VALIDATOR_COMPOSITE, ZakFormValidator) + +ZakFormValidatorComposite *zak_form_validator_composite_new (void); + + +G_END_DECLS + + +#endif /* __ZAK_FORM_VALIDATOR_COMPOSITE_H__ */ diff --git a/src/libzakform.h b/src/libzakform.h index e3ba88a..63e78ab 100644 --- a/src/libzakform.h +++ b/src/libzakform.h @@ -38,6 +38,7 @@ #include #include #include +#include #endif /* __LIBZAKFORM_H__ */