26 #include <libxml/xmlversion.h>
27 #include <libxml/xmlmemory.h>
28 #include <libxml/tree.h>
29 #include <libxml/parser.h>
30 #include <libxml/xmlschemas.h>
39 qsf_date_default_handler (
const gchar * default_name,
40 GHashTable * qsf_default_hash,
41 xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
43 xmlNodePtr output_parent;
47 output_parent = xmlAddChild (parent_tag, xmlNewNode (ns,
52 (time_t *) g_hash_table_lookup (qsf_default_hash, default_name);
55 xmlNodeAddContent (output_parent, BAD_CAST date_as_string);
59 qsf_string_default_handler (
const gchar * default_name,
60 GHashTable * qsf_default_hash,
61 xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
66 node = xmlAddChild (parent_tag,
68 xmlGetProp (import_node, BAD_CAST QSF_OBJECT_TYPE)));
69 xmlNewProp (node, BAD_CAST QSF_OBJECT_TYPE,
72 (xmlChar *) g_hash_table_lookup (qsf_default_hash, default_name);
73 xmlNodeAddContent (node, output);
77 qsf_map_validation_handler (xmlNodePtr child, xmlNsPtr ns,
80 xmlChar *qof_version, *obj_type;
81 gboolean match, is_registered;
83 xmlNodePtr child_node;
88 is_registered = FALSE;
94 if (xmlStrcmp (qof_version, BAD_CAST buff) != 0)
96 PERR (
" Wrong QOF_VERSION in map '%s', should be %s",
103 for (child_node = child->children; child_node != NULL;
104 child_node = child_node->next)
108 obj_type = xmlGetProp (child_node,
MAP_E_TYPE);
115 g_hash_table_insert (valid->
map_table, obj_type,
116 GINT_TO_POINTER (type));
125 GPOINTER_TO_INT (g_hash_table_lookup
136 GPOINTER_TO_INT (g_hash_table_lookup
138 switch (incoming_type)
143 g_hash_table_insert (valid->
map_table, obj_type,
144 GINT_TO_POINTER (type));
149 PERR (
" Missing data: %s", obj_type);
162 g_hash_table_insert (valid->
map_table, obj_type,
163 GINT_TO_POINTER (type));
172 PINFO (
" final type=%s result=%d", obj_type, type);
181 check_qsf_object_with_map_internal (xmlDocPtr map_doc, xmlDocPtr doc)
183 xmlNodePtr map_root, object_root;
188 valid.
map_table = g_hash_table_new (g_str_hash, g_str_equal);
189 valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
190 map_root = xmlDocGetRootElement (map_doc);
191 object_root = xmlDocGetRootElement (doc);
192 valid.map_calculated_count = 0;
193 valid.valid_object_count = 0;
194 valid.qof_registered_count = 0;
195 valid.incoming_count = 0;
197 map_ns = map_root->ns;
198 qsfiter.ns = object_root->ns;
199 qsf_valid_foreach (object_root, qsf_object_validation_handler,
202 qsf_valid_foreach (map_root, qsf_map_validation_handler, &qsfiter,
206 PINFO (
" Map is wrong. Trying the next map.");
207 g_hash_table_destroy (valid.object_table);
208 g_hash_table_destroy (valid.map_table);
209 return valid.error_state;
220 if ((valid.qof_registered_count < 1)
221 || (valid.map_calculated_count < 1)
222 || (valid.valid_object_count < 1)
223 || (valid.incoming_count < g_hash_table_size (valid.object_table)))
226 (
" Map is wrong. map:%d object:%d reg:%d incoming:%d size:%d",
227 valid.map_calculated_count, valid.valid_object_count,
228 valid.qof_registered_count, valid.incoming_count,
229 g_hash_table_size (valid.object_table));
230 g_hash_table_destroy (valid.object_table);
231 g_hash_table_destroy (valid.map_table);
232 return valid.error_state;
234 g_hash_table_destroy (valid.object_table);
235 g_hash_table_destroy (valid.map_table);
240 is_qsf_object_with_map_be (gchar * map_file,
QsfParam * params)
242 xmlDocPtr doc, map_doc;
244 gchar *path, *map_path;
246 g_return_val_if_fail ((params != NULL), FALSE);
248 map_path = g_strdup_printf (
"%s/%s", QSF_SCHEMA_DIR, map_file);
249 PINFO (
" checking map file '%s'", map_path);
253 (_(
"The QSF XML file '%s' could not be found."), TRUE));
256 doc = xmlParseFile (path);
260 (_(
"There was an error parsing the file '%s'."), TRUE));
266 (_(
"Invalid QSF Object file! The QSF object file '%s' "
267 " failed to validate against the QSF object schema. "
268 "The XML structure of the file is either not well-formed "
269 "or the file contains illegal data."), TRUE));
272 if (map_path == NULL)
275 (_(
"The QSF map file '%s' could not be found."), TRUE));
278 map_doc = xmlParseFile (map_path);
282 (_(
"There was an error parsing the file '%s'."), TRUE));
285 result = check_qsf_object_with_map_internal (map_doc, doc);
290 is_qsf_object_with_map (
const gchar * path, gchar * map_file)
292 xmlDocPtr doc, map_doc;
296 map_path = g_strdup_printf (
"%s/%s", QSF_SCHEMA_DIR, map_file);
301 doc = xmlParseFile (path);
310 if (map_path == NULL)
314 map_doc = xmlParseFile (map_path);
315 result = check_qsf_object_with_map_internal (map_doc, doc);
329 g_return_val_if_fail ((params != NULL), FALSE);
334 (_(
"The QSF XML file '%s' could not be found."), TRUE));
337 doc = xmlParseFile (path);
341 (_(
"There was an error parsing the file '%s'."), TRUE));
346 qof_error_set_be (params->
be,
348 _(
"Invalid QSF Map file! The QSF map file "
349 "failed to validate against the QSF map schema. "
350 "The XML structure of the file is either not well-formed "
351 "or the file contains illegal data."), FALSE));
354 map_root = xmlDocGetRootElement (doc);
355 map_ns = map_root->ns;
357 valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
358 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
360 qsf_valid_foreach (map_root, qsf_map_validation_handler,
364 g_hash_table_destroy (valid.object_table);
367 g_hash_table_destroy (valid.object_table);
372 is_qsf_map (
const gchar * path)
380 g_return_val_if_fail ((path != NULL), FALSE);
385 doc = xmlParseFile (path);
394 map_root = xmlDocGetRootElement (doc);
395 map_ns = map_root->ns;
398 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
399 qsf_valid_foreach (map_root, qsf_map_validation_handler,
403 g_hash_table_destroy (valid.map_table);
406 g_hash_table_destroy (valid.map_table);
411 qsf_map_default_handler (xmlNodePtr child, xmlNsPtr ns,
QsfParam * params)
417 g_return_if_fail (params->qsf_define_hash != NULL);
420 (_(
"The selected QSF map '%s' contains unusable or "
421 "missing data. This is usually because not all the "
422 "required parameters for the defined objects have "
423 "calculations described in the map."), TRUE);
431 params->
qof_foreach = xmlGetProp (child, BAD_CAST MAP_E_TYPE);
434 if (NULL == g_hash_table_lookup (params->qsf_define_hash,
435 xmlGetProp (child, BAD_CAST MAP_E_TYPE)))
437 g_hash_table_insert (params->qsf_define_hash,
438 xmlGetProp (child, BAD_CAST MAP_E_TYPE),
443 qof_error_set_be (params->
be, bad_map);
444 PERR (
" ERR_QSF_BAD_MAP set");
450 if (qsf_strings_equal
453 qsf_enum = xmlNodeGetContent (child);
455 PERR (
" enum todo incomplete");
459 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
460 xmlNodeGetContent (child)))
462 g_hash_table_insert (params->qsf_default_hash,
463 xmlNodeGetContent (child), child);
467 qof_error_set_be (params->
be, bad_map);
468 PERR (
" ERR_QSF_BAD_MAP set");
475 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
478 g_hash_table_insert (params->qsf_default_hash,
479 xmlGetProp (child, BAD_CAST MAP_NAME_ATTR), child);
485 qof_error_set_be (params->
be, bad_map);
486 PERR (
" ERR_QSF_BAD_MAP set");
494 qsf_map_top_node_handler (xmlNodePtr child, xmlNsPtr ns,
497 xmlChar *qof_version;
501 if (!params->qsf_define_hash)
503 if (!params->qsf_default_hash)
505 ENTER (
" map top node child=%s", child->name);
511 if (xmlStrcmp (qof_version, BAD_CAST buff) != 0)
514 _(
"The QSF Map file '%s' was written for a different "
515 "version of QOF. It may need to be modified to work with "
516 "your current QOF installation."), TRUE));
517 LEAVE (
" BAD QOF VERSION");
521 qsf_node_foreach (child, qsf_map_default_handler, &qsfiter, params);
527 qsf_else_set_value (xmlNodePtr parent, gchar * content,
533 for (cur_node = parent->children; cur_node != NULL;
534 cur_node = cur_node->next)
538 content = (gchar *) xmlNodeGetContent (cur_node);
550 qsf_set_handler (xmlNodePtr parent, GHashTable * default_hash,
553 xmlNodePtr cur_node, lookup_node;
555 ENTER (
" lookup problem");
557 for (cur_node = parent->children; cur_node != NULL;
558 cur_node = cur_node->next)
562 content = (gchar *) xmlGetProp (cur_node, BAD_CAST
QSF_OPTION);
563 if (qsf_strings_equal (xmlGetProp (cur_node,
564 BAD_CAST QSF_OPTION),
"qsf_lookup_string"))
567 (xmlNodePtr) g_hash_table_lookup (default_hash,
568 xmlNodeGetContent (cur_node));
570 (gchar *) xmlGetProp (lookup_node,
574 g_message (
"Lookup %s in the receiving application\n",
582 (xmlNodePtr) g_hash_table_lookup (default_hash,
583 xmlNodeGetContent (cur_node));
585 (gchar *) xmlGetProp (lookup_node, BAD_CAST
"value");
588 content = (gchar *) xmlGetProp (parent, BAD_CAST
"boolean");
593 (xmlNodePtr) g_hash_table_lookup (params->
595 xmlGetProp (parent->parent, BAD_CAST MAP_TYPE_ATTR));
598 return (gchar *) xmlNodeGetContent (lookup_node);
600 LEAVE (
" check arguments");
601 return (gchar *) xmlNodeGetContent (cur_node);
610 qsf_calculate_else (xmlNodePtr param_node, xmlNodePtr child,
613 xmlNodePtr export_node;
614 xmlChar *output_content, *object_data;
620 output_content = object_data = NULL;
621 output_content = BAD_CAST qsf_set_handler (param_node,
623 qsf_default_hash, (gchar *) output_content, params);
624 if (output_content == NULL)
627 xmlGetProp (param_node, BAD_CAST MAP_TYPE_ATTR);
629 BAD_CAST qsf_else_set_value (param_node,
630 (gchar *) output_content, params->map_ns);
632 BAD_CAST xmlGetProp ((xmlNodePtr)
633 g_hash_table_lookup (params->
637 if (object_data != NULL)
640 (xmlNodePtr) g_hash_table_lookup (params->
643 child_node, BAD_CAST QSF_OBJECT_TYPE));
644 object_data = xmlNodeGetContent (export_node);
646 if (output_content != NULL)
648 object_data = output_content;
651 xmlAddChild (params->
lister,
652 xmlNewNode (params->
qsf_ns,
653 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
654 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
656 xmlNodeAddContent (export_node, object_data);
663 qsf_set_format_value (xmlChar * format, gchar * qsf_time_now_as_string,
664 xmlNodePtr cur_node,
QsfParam * params)
682 content = xmlNodeGetContent (cur_node);
684 (time_t *) g_hash_table_lookup (params->qsf_default_hash, content);
689 tester = time (NULL);
690 tmp = gmtime (&tester);
697 LEAVE (
" no suitable date set.");
701 strptime ((
char *) xmlNodeGetContent (kl),
QSF_XSD_TIME, tmp);
704 LEAVE (
" empty date field in QSF object.\n");
707 tester = mktime (tmp);
710 result = regcomp (®,
"%[a-zA-Z]", REG_EXTENDED | REG_NOSUB);
711 result = regexec (®, (gchar *) format, (
size_t) 0, NULL, 0);
712 if (result == REG_NOMATCH)
714 format = BAD_CAST
"%F";
724 qsf_boolean_set_value (xmlNodePtr parent,
QsfParam * params,
725 gchar * content, xmlNsPtr map_ns)
728 xmlChar *boolean_name;
731 for (cur_node = parent->children; cur_node != NULL;
732 cur_node = cur_node->next)
738 qsf_set_format_value (boolean_name, content, cur_node, params);
744 qsf_calculate_conditional (xmlNodePtr param_node, xmlNodePtr child,
747 xmlNodePtr export_node;
748 xmlChar *output_content;
750 output_content = NULL;
757 BAD_CAST qsf_set_handler (param_node,
758 params->qsf_default_hash,
759 (gchar *) output_content, params);
761 if (output_content == NULL)
767 xmlGetProp ((xmlNodePtr)
768 g_hash_table_lookup (params->
773 QSF_BOOLEAN_DEFAULT)),
778 qsf_compare_tag_strings (output_content,
781 qsf_boolean_set_value (param_node, params,
782 (gchar *) output_content, params->map_ns);
784 xmlAddChild (params->
lister,
785 xmlNewNode (params->
qsf_ns,
786 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
787 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
789 xmlNodeAddContent (export_node, output_content);
798 qsf_add_object_tag (
QsfParam * params, gint count)
800 xmlNodePtr extra_node;
804 str = g_string_new (
" ");
805 g_string_printf (str,
"%i", count);
809 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_TYPE,
810 xmlGetProp (params->
convert_node, BAD_CAST QSF_OBJECT_TYPE));
811 property = xmlCharStrdup (str->str);
813 params->
lister = extra_node;
817 identify_source_func (gconstpointer qsf_object, gconstpointer map)
819 PINFO (
" qsf_object=%s, map=%s",
826 qsf_map_calculate_output (xmlNodePtr param_node, xmlNodePtr child,
829 xmlNodePtr export_node;
830 xmlChar *output_content;
831 xmlNodePtr input_node;
834 output_content = xmlNodeGetContent (param_node);
835 DEBUG (
" %s", output_content);
838 BAD_CAST xmlGetProp (param_node,
840 PINFO (
" checking %s", BAD_CAST xmlGetProp (param_node,
844 DEBUG (
" no source found in list.");
848 input_node = g_hash_table_lookup (params->
object_set->parameters,
850 DEBUG (
" node_value=%s, content=%s",
852 xmlNodeGetContent (input_node));
853 export_node = xmlAddChild (params->
lister, xmlNewNode (params->
qsf_ns,
854 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
855 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
856 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
857 xmlNodeAddContent (export_node, xmlNodeGetContent (input_node));
861 qsf_map_object_handler (xmlNodePtr child, xmlNsPtr ns,
QsfParam * params)
863 xmlNodePtr param_node;
864 xmlNsPtr map_ns, qsf_ns;
885 for (param_node = child->children; param_node != NULL;
886 param_node = param_node->next)
892 qsf_compare_tag_strings (xmlNodeGetContent
893 (param_node),
"qsf_enquiry_date"))
895 qsf_string_default_handler (
"qsf_enquiry_date",
896 params->qsf_default_hash,
897 params->
lister, child, qsf_ns);
900 qsf_compare_tag_strings (xmlNodeGetContent
901 (param_node),
"qsf_time_now"))
903 qsf_date_default_handler (
"qsf_time_now",
904 params->qsf_default_hash,
905 params->
lister, child, qsf_ns);
908 qsf_compare_tag_strings (xmlNodeGetContent
909 (param_node),
"qsf_time_string"))
911 qsf_string_default_handler (
"qsf_time_string",
912 params->qsf_default_hash,
913 params->
lister, child, qsf_ns);
915 qsf_map_calculate_output (param_node, child, params);
917 qsf_calculate_conditional (param_node, child, params);
918 qsf_calculate_else (param_node, child, params);
938 iterator_cb (xmlNodePtr child, xmlNsPtr ns,
QsfParam * params)
945 object_name = xmlGetProp (child, QSF_OBJECT_TYPE);
954 qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root,
959 xmlDocPtr output_doc;
961 xmlNode *map_root, *output_root;
963 g_return_val_if_fail ((mapDoc && qsf_root && params), NULL);
964 ENTER (
" root=%s", qsf_root->name);
966 qsfiter.ns = params->
qsf_ns;
969 xmlDocSetRootElement (output_doc, output_root);
970 xmlSetNs (output_root, params->
qsf_ns);
976 qsf_book_node_handler (qsf_root->children->next, params->
qsf_ns,
979 map_root = xmlDocGetRootElement (mapDoc);
981 qsfiter.ns = params->map_ns;
983 qsf_node_foreach (map_root, qsf_map_top_node_handler, &qsfiter, params);
985 qsfiter.ns = params->
qsf_ns;
986 qsf_node_foreach (qsf_root->children->next, iterator_cb, &qsfiter,
990 for (cur_node = map_root->children; cur_node != NULL;
991 cur_node = cur_node->next)
999 PINFO (
" found an object tag. starting calculation");
1002 xmlGetProp (cur_node, MAP_TYPE_ATTR)))
1006 qsf_add_object_tag (params, params->
count);
1008 qsfiter.ns = params->map_ns;
1012 qsf_node_foreach (cur_node, qsf_map_object_handler,
1022 xmlSaveFormatFileEnc (
"-", output_doc,
"UTF-8", 1);