00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include <glib.h>
00026 #include <libxml/xmlversion.h>
00027 #include <libxml/xmlmemory.h>
00028 #include <libxml/tree.h>
00029 #include <libxml/parser.h>
00030 #include <libxml/xmlschemas.h>
00031 #include "qof.h"
00032 #include "qof-backend-qsf.h"
00033 #include "qsf-xml.h"
00034 #include "qsf-dir.h"
00035
00036 static QofLogModule log_module = QOF_MOD_QSF;
00037
00038 static void
00039 qsf_date_default_handler (const gchar * default_name,
00040 GHashTable * qsf_default_hash,
00041 xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
00042 {
00043 xmlNodePtr output_parent;
00044 time_t *qsf_time;
00045 gchar date_as_string[QSF_DATE_LENGTH];
00046
00047 output_parent = xmlAddChild (parent_tag, xmlNewNode (ns,
00048 xmlGetProp (import_node, BAD_CAST QSF_OBJECT_TYPE)));
00049 xmlNewProp (output_parent, BAD_CAST QSF_OBJECT_TYPE,
00050 xmlGetProp (import_node, BAD_CAST MAP_VALUE_ATTR));
00051 qsf_time =
00052 (time_t *) g_hash_table_lookup (qsf_default_hash, default_name);
00053 strftime (date_as_string, QSF_DATE_LENGTH, QSF_XSD_TIME,
00054 gmtime (qsf_time));
00055 xmlNodeAddContent (output_parent, BAD_CAST date_as_string);
00056 }
00057
00058 static void
00059 qsf_string_default_handler (const gchar * default_name,
00060 GHashTable * qsf_default_hash,
00061 xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
00062 {
00063 xmlNodePtr node;
00064 xmlChar *output;
00065
00066 node = xmlAddChild (parent_tag,
00067 xmlNewNode (ns,
00068 xmlGetProp (import_node, BAD_CAST QSF_OBJECT_TYPE)));
00069 xmlNewProp (node, BAD_CAST QSF_OBJECT_TYPE,
00070 xmlGetProp (import_node, BAD_CAST MAP_VALUE_ATTR));
00071 output =
00072 (xmlChar *) g_hash_table_lookup (qsf_default_hash, default_name);
00073 xmlNodeAddContent (node, output);
00074 }
00075
00076 static void
00077 qsf_map_validation_handler (xmlNodePtr child, xmlNsPtr ns,
00078 QsfValidator * valid)
00079 {
00080 xmlChar *qof_version, *obj_type;
00081 gboolean match, is_registered;
00082 gchar *buff;
00083 xmlNodePtr child_node;
00084 QsfStatus type, incoming_type;
00085
00086 match = FALSE;
00087 buff = NULL;
00088 is_registered = FALSE;
00089 type = QSF_NO_OBJECT;
00090 if (qsf_is_element (child, ns, MAP_DEFINITION_TAG))
00091 {
00092 qof_version = xmlGetProp (child, BAD_CAST MAP_QOF_VERSION);
00093 buff = g_strdup_printf ("%i", QSF_QOF_VERSION);
00094 if (xmlStrcmp (qof_version, BAD_CAST buff) != 0)
00095 {
00096 PERR (" Wrong QOF_VERSION in map '%s', should be %s",
00097 qof_version, buff);
00098 valid->error_state = QOF_FATAL;
00099 g_free (buff);
00100 return;
00101 }
00102 g_free (buff);
00103 for (child_node = child->children; child_node != NULL;
00104 child_node = child_node->next)
00105 {
00106 if (qsf_is_element (child_node, ns, MAP_DEFINE_TAG))
00107 {
00108 obj_type = xmlGetProp (child_node, MAP_E_TYPE);
00109 type = QSF_DEFINED_OBJECT;
00110 is_registered = qof_class_is_registered (obj_type);
00111 if (is_registered)
00112 {
00113 type = QSF_REGISTERED_OBJECT;
00114 }
00115 g_hash_table_insert (valid->map_table, obj_type,
00116 GINT_TO_POINTER (type));
00117 }
00118 }
00119 }
00120 if (qsf_is_element (child, ns, MAP_OBJECT_TAG))
00121 {
00122 obj_type = xmlGetProp (child, BAD_CAST MAP_TYPE_ATTR);
00123
00124 type =
00125 GPOINTER_TO_INT (g_hash_table_lookup
00126 (valid->map_table, obj_type));
00127 switch (type)
00128 {
00129 case QSF_DEFINED_OBJECT:
00130
00131
00132
00133 {
00134
00135 incoming_type =
00136 GPOINTER_TO_INT (g_hash_table_lookup
00137 (valid->object_table, obj_type));
00138 switch (incoming_type)
00139 {
00140 case QSF_DEFINED_OBJECT:
00141 {
00142 valid->incoming_count++;
00143 g_hash_table_insert (valid->map_table, obj_type,
00144 GINT_TO_POINTER (type));
00145 break;
00146 }
00147 default:
00148 {
00149 PERR (" Missing data: %s", obj_type);
00150 type = QSF_INVALID_OBJECT;
00151 break;
00152 }
00153 }
00154 break;
00155 }
00156 case QSF_REGISTERED_OBJECT:
00157 {
00158 type = QSF_CALCULATED_OBJECT;
00159 valid->map_calculated_count++;
00160 valid->qof_registered_count++;
00161
00162 g_hash_table_insert (valid->map_table, obj_type,
00163 GINT_TO_POINTER (type));
00164 break;
00165 }
00166 default:
00167 {
00168 type = QSF_INVALID_OBJECT;
00169 break;
00170 }
00171 }
00172 PINFO (" final type=%s result=%d", obj_type, type);
00173 if (type == QSF_INVALID_OBJECT)
00174 {
00175 valid->error_state = QOF_FATAL;
00176 }
00177 }
00178 }
00179
00180 static QofErrorId
00181 check_qsf_object_with_map_internal (xmlDocPtr map_doc, xmlDocPtr doc)
00182 {
00183 xmlNodePtr map_root, object_root;
00184 struct QsfNodeIterate qsfiter;
00185 QsfValidator valid;
00186 xmlNsPtr map_ns;
00187
00188 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
00189 valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
00190 map_root = xmlDocGetRootElement (map_doc);
00191 object_root = xmlDocGetRootElement (doc);
00192 valid.map_calculated_count = 0;
00193 valid.valid_object_count = 0;
00194 valid.qof_registered_count = 0;
00195 valid.incoming_count = 0;
00196 valid.error_state = QOF_SUCCESS;
00197 map_ns = map_root->ns;
00198 qsfiter.ns = object_root->ns;
00199 qsf_valid_foreach (object_root, qsf_object_validation_handler,
00200 &qsfiter, &valid);
00201 qsfiter.ns = map_ns;
00202 qsf_valid_foreach (map_root, qsf_map_validation_handler, &qsfiter,
00203 &valid);
00204 if (valid.error_state != QOF_SUCCESS)
00205 {
00206 PINFO (" Map is wrong. Trying the next map.");
00207 g_hash_table_destroy (valid.object_table);
00208 g_hash_table_destroy (valid.map_table);
00209 return valid.error_state;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 if ((valid.qof_registered_count < 1)
00221 || (valid.map_calculated_count < 1)
00222 || (valid.valid_object_count < 1)
00223 || (valid.incoming_count < g_hash_table_size (valid.object_table)))
00224 {
00225 PINFO
00226 (" Map is wrong. map:%d object:%d reg:%d incoming:%d size:%d",
00227 valid.map_calculated_count, valid.valid_object_count,
00228 valid.qof_registered_count, valid.incoming_count,
00229 g_hash_table_size (valid.object_table));
00230 g_hash_table_destroy (valid.object_table);
00231 g_hash_table_destroy (valid.map_table);
00232 return valid.error_state;
00233 }
00234 g_hash_table_destroy (valid.object_table);
00235 g_hash_table_destroy (valid.map_table);
00236 return QOF_SUCCESS;
00237 }
00238
00239 gboolean
00240 is_qsf_object_with_map_be (gchar * map_file, QsfParam * params)
00241 {
00242 xmlDocPtr doc, map_doc;
00243 QofErrorId result;
00244 gchar *path, *map_path;
00245
00246 g_return_val_if_fail ((params != NULL), FALSE);
00247 path = g_strdup (params->filepath);
00248 map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
00249 PINFO (" checking map file '%s'", map_path);
00250 if (path == NULL)
00251 {
00252 qof_error_set_be (params->be, qof_error_register
00253 (_("The QSF XML file '%s' could not be found."), TRUE));
00254 return FALSE;
00255 }
00256 doc = xmlParseFile (path);
00257 if (doc == NULL)
00258 {
00259 qof_error_set_be (params->be, qof_error_register
00260 (_("There was an error parsing the file '%s'."), TRUE));
00261 return FALSE;
00262 }
00263 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00264 {
00265 qof_error_set_be (params->be, qof_error_register
00266 (_("Invalid QSF Object file! The QSF object file '%s' "
00267 " failed to validate against the QSF object schema. "
00268 "The XML structure of the file is either not well-formed "
00269 "or the file contains illegal data."), TRUE));
00270 return FALSE;
00271 }
00272 if (map_path == NULL)
00273 {
00274 qof_error_set_be (params->be, qof_error_register
00275 (_("The QSF map file '%s' could not be found."), TRUE));
00276 return FALSE;
00277 }
00278 map_doc = xmlParseFile (map_path);
00279 if (map_doc == NULL)
00280 {
00281 qof_error_set_be (params->be, qof_error_register
00282 (_("There was an error parsing the file '%s'."), TRUE));
00283 return FALSE;
00284 }
00285 result = check_qsf_object_with_map_internal (map_doc, doc);
00286 return (result == QOF_SUCCESS) ? TRUE : FALSE;
00287 }
00288
00289 gboolean
00290 is_qsf_object_with_map (const gchar * path, gchar * map_file)
00291 {
00292 xmlDocPtr doc, map_doc;
00293 QofErrorId result;
00294 gchar *map_path;
00295
00296 map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
00297 if (path == NULL)
00298 {
00299 return FALSE;
00300 }
00301 doc = xmlParseFile (path);
00302 if (doc == NULL)
00303 {
00304 return FALSE;
00305 }
00306 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00307 {
00308 return FALSE;
00309 }
00310 if (map_path == NULL)
00311 {
00312 return FALSE;
00313 }
00314 map_doc = xmlParseFile (map_path);
00315 result = check_qsf_object_with_map_internal (map_doc, doc);
00316 return (result == QOF_SUCCESS) ? TRUE : FALSE;
00317 }
00318
00319 gboolean
00320 is_qsf_map_be (QsfParam * params)
00321 {
00322 xmlDocPtr doc;
00323 struct QsfNodeIterate qsfiter;
00324 QsfValidator valid;
00325 xmlNodePtr map_root;
00326 xmlNsPtr map_ns;
00327 gchar *path;
00328
00329 g_return_val_if_fail ((params != NULL), FALSE);
00330 path = g_strdup (params->filepath);
00331 if (path == NULL)
00332 {
00333 qof_error_set_be (params->be, qof_error_register
00334 (_("The QSF XML file '%s' could not be found."), TRUE));
00335 return FALSE;
00336 }
00337 doc = xmlParseFile (path);
00338 if (doc == NULL)
00339 {
00340 qof_error_set_be (params->be, qof_error_register
00341 (_("There was an error parsing the file '%s'."), TRUE));
00342 return FALSE;
00343 }
00344 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00345 {
00346 qof_error_set_be (params->be,
00347 qof_error_register (
00348 _("Invalid QSF Map file! The QSF map file "
00349 "failed to validate against the QSF map schema. "
00350 "The XML structure of the file is either not well-formed "
00351 "or the file contains illegal data."), FALSE));
00352 return FALSE;
00353 }
00354 map_root = xmlDocGetRootElement (doc);
00355 map_ns = map_root->ns;
00356 qsfiter.ns = map_ns;
00357 valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
00358 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
00359 valid.error_state = QOF_SUCCESS;
00360 qsf_valid_foreach (map_root, qsf_map_validation_handler,
00361 &qsfiter, &valid);
00362 if (valid.error_state != QOF_SUCCESS)
00363 {
00364 g_hash_table_destroy (valid.object_table);
00365 return FALSE;
00366 }
00367 g_hash_table_destroy (valid.object_table);
00368 return TRUE;
00369 }
00370
00371 gboolean
00372 is_qsf_map (const gchar * path)
00373 {
00374 xmlDocPtr doc;
00375 struct QsfNodeIterate qsfiter;
00376 QsfValidator valid;
00377 xmlNodePtr map_root;
00378 xmlNsPtr map_ns;
00379
00380 g_return_val_if_fail ((path != NULL), FALSE);
00381 if (path == NULL)
00382 {
00383 return FALSE;
00384 }
00385 doc = xmlParseFile (path);
00386 if (doc == NULL)
00387 {
00388 return FALSE;
00389 }
00390 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00391 {
00392 return FALSE;
00393 }
00394 map_root = xmlDocGetRootElement (doc);
00395 map_ns = map_root->ns;
00396 qsfiter.ns = map_ns;
00397 valid.error_state = QOF_SUCCESS;
00398 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
00399 qsf_valid_foreach (map_root, qsf_map_validation_handler,
00400 &qsfiter, &valid);
00401 if (valid.error_state != QOF_SUCCESS)
00402 {
00403 g_hash_table_destroy (valid.map_table);
00404 return FALSE;
00405 }
00406 g_hash_table_destroy (valid.map_table);
00407 return TRUE;
00408 }
00409
00410 static void
00411 qsf_map_default_handler (xmlNodePtr child, xmlNsPtr ns, QsfParam * params)
00412 {
00413 xmlChar *qsf_enum;
00414 gchar *iterate;
00415 QofErrorId bad_map;
00416
00417 g_return_if_fail (params->qsf_define_hash != NULL);
00418 iterate = NULL;
00419 bad_map = qof_error_register
00420 (_("The selected QSF map '%s' contains unusable or "
00421 "missing data. This is usually because not all the "
00422 "required parameters for the defined objects have "
00423 "calculations described in the map."), TRUE);
00424 if (qsf_is_element (child, ns, MAP_DEFINE_TAG))
00425 {
00426 iterate = xmlGetProp (child, MAP_ITERATE_ATTR);
00427 if ((qof_util_bool_to_int (iterate) == 1) &&
00428 (qof_class_is_registered
00429 (xmlGetProp (child, BAD_CAST MAP_E_TYPE))))
00430 {
00431 params->qof_foreach = xmlGetProp (child, BAD_CAST MAP_E_TYPE);
00432 PINFO (" iterating over '%s' objects", params->qof_foreach);
00433 }
00434 if (NULL == g_hash_table_lookup (params->qsf_define_hash,
00435 xmlGetProp (child, BAD_CAST MAP_E_TYPE)))
00436 {
00437 g_hash_table_insert (params->qsf_define_hash,
00438 xmlGetProp (child, BAD_CAST MAP_E_TYPE),
00439 params->child_node);
00440 }
00441 else
00442 {
00443 qof_error_set_be (params->be, bad_map);
00444 PERR (" ERR_QSF_BAD_MAP set");
00445 return;
00446 }
00447 }
00448 if (qsf_is_element (child, ns, MAP_DEFAULT_TAG))
00449 {
00450 if (qsf_strings_equal
00451 (xmlGetProp (child, BAD_CAST MAP_TYPE_ATTR), MAP_ENUM_TYPE))
00452 {
00453 qsf_enum = xmlNodeGetContent (child);
00455 PERR (" enum todo incomplete");
00459 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
00460 xmlNodeGetContent (child)))
00461 {
00462 g_hash_table_insert (params->qsf_default_hash,
00463 xmlNodeGetContent (child), child);
00464 }
00465 else
00466 {
00467 qof_error_set_be (params->be, bad_map);
00468 PERR (" ERR_QSF_BAD_MAP set");
00469 return;
00470 }
00471 }
00473 else
00474 {
00475 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
00476 xmlGetProp (child, BAD_CAST MAP_NAME_ATTR)))
00477 {
00478 g_hash_table_insert (params->qsf_default_hash,
00479 xmlGetProp (child, BAD_CAST MAP_NAME_ATTR), child);
00480 }
00481 else
00482
00483
00484 {
00485 qof_error_set_be (params->be, bad_map);
00486 PERR (" ERR_QSF_BAD_MAP set");
00487 return;
00488 }
00489 }
00490 }
00491 }
00492
00493 static void
00494 qsf_map_top_node_handler (xmlNodePtr child, xmlNsPtr ns,
00495 QsfParam * params)
00496 {
00497 xmlChar *qof_version;
00498 gchar *buff;
00499 struct QsfNodeIterate qsfiter;
00500
00501 if (!params->qsf_define_hash)
00502 return;
00503 if (!params->qsf_default_hash)
00504 return;
00505 ENTER (" map top node child=%s", child->name);
00506 buff = NULL;
00507 if (qsf_is_element (child, ns, MAP_DEFINITION_TAG))
00508 {
00509 qof_version = xmlGetProp (child, BAD_CAST MAP_QOF_VERSION);
00510 buff = g_strdup_printf ("%i", QSF_QOF_VERSION);
00511 if (xmlStrcmp (qof_version, BAD_CAST buff) != 0)
00512 {
00513 qof_error_set_be (params->be, qof_error_register(
00514 _("The QSF Map file '%s' was written for a different "
00515 "version of QOF. It may need to be modified to work with "
00516 "your current QOF installation."), TRUE));
00517 LEAVE (" BAD QOF VERSION");
00518 return;
00519 }
00520 qsfiter.ns = ns;
00521 qsf_node_foreach (child, qsf_map_default_handler, &qsfiter, params);
00522 }
00523 LEAVE (" ");
00524 }
00525
00526 static char *
00527 qsf_else_set_value (xmlNodePtr parent, gchar * content,
00528 xmlNsPtr map_ns)
00529 {
00530 xmlNodePtr cur_node;
00531
00532 content = NULL;
00533 for (cur_node = parent->children; cur_node != NULL;
00534 cur_node = cur_node->next)
00535 {
00536 if (qsf_is_element (cur_node, map_ns, QSF_CONDITIONAL_SET))
00537 {
00538 content = (gchar *) xmlNodeGetContent (cur_node);
00539 return content;
00540 }
00541 }
00542 return NULL;
00543 }
00544
00545
00546
00547
00548
00549 static gchar *
00550 qsf_set_handler (xmlNodePtr parent, GHashTable * default_hash,
00551 gchar * content, QsfParam * params)
00552 {
00553 xmlNodePtr cur_node, lookup_node;
00554
00555 ENTER (" lookup problem");
00556 content = NULL;
00557 for (cur_node = parent->children; cur_node != NULL;
00558 cur_node = cur_node->next)
00559 {
00560 if (qsf_is_element (cur_node, params->map_ns, QSF_CONDITIONAL_SET))
00561 {
00562 content = (gchar *) xmlGetProp (cur_node, BAD_CAST QSF_OPTION);
00563 if (qsf_strings_equal (xmlGetProp (cur_node,
00564 BAD_CAST QSF_OPTION), "qsf_lookup_string"))
00565 {
00566 lookup_node =
00567 (xmlNodePtr) g_hash_table_lookup (default_hash,
00568 xmlNodeGetContent (cur_node));
00569 content =
00570 (gchar *) xmlGetProp (lookup_node,
00571 BAD_CAST MAP_VALUE_ATTR);
00573
00574 g_message ("Lookup %s in the receiving application\n",
00575 content);
00576 LEAVE (" todo");
00577 return content;
00578 }
00579 if (content)
00580 {
00581 lookup_node =
00582 (xmlNodePtr) g_hash_table_lookup (default_hash,
00583 xmlNodeGetContent (cur_node));
00584 content =
00585 (gchar *) xmlGetProp (lookup_node, BAD_CAST "value");
00586 return content;
00587 }
00588 content = (gchar *) xmlGetProp (parent, BAD_CAST "boolean");
00589 if (!content)
00590 {
00592 lookup_node =
00593 (xmlNodePtr) g_hash_table_lookup (params->
00594 qsf_parameter_hash,
00595 xmlGetProp (parent->parent, BAD_CAST MAP_TYPE_ATTR));
00596 if (lookup_node)
00597 {
00598 return (gchar *) xmlNodeGetContent (lookup_node);
00599 }
00600 LEAVE (" check arguments");
00601 return (gchar *) xmlNodeGetContent (cur_node);
00602 }
00603 }
00604 }
00605 LEAVE (" null");
00606 return NULL;
00607 }
00608
00609 static void
00610 qsf_calculate_else (xmlNodePtr param_node, xmlNodePtr child,
00611 QsfParam * params)
00612 {
00613 xmlNodePtr export_node;
00614 xmlChar *output_content, *object_data;
00615
00616 if (qsf_is_element (param_node, params->map_ns, QSF_CONDITIONAL_ELSE))
00617 {
00618 if (params->boolean_calculation_done == 0)
00619 {
00620 output_content = object_data = NULL;
00621 output_content = BAD_CAST qsf_set_handler (param_node,
00622 params->
00623 qsf_default_hash, (gchar *) output_content, params);
00624 if (output_content == NULL)
00625 {
00626 output_content =
00627 xmlGetProp (param_node, BAD_CAST MAP_TYPE_ATTR);
00628 object_data =
00629 BAD_CAST qsf_else_set_value (param_node,
00630 (gchar *) output_content, params->map_ns);
00631 output_content =
00632 BAD_CAST xmlGetProp ((xmlNodePtr)
00633 g_hash_table_lookup (params->
00634 qsf_default_hash,
00635 object_data), BAD_CAST MAP_VALUE_ATTR);
00636 }
00637 if (object_data != NULL)
00638 {
00639 export_node =
00640 (xmlNodePtr) g_hash_table_lookup (params->
00641 qsf_parameter_hash,
00642 xmlGetProp (params->
00643 child_node, BAD_CAST QSF_OBJECT_TYPE));
00644 object_data = xmlNodeGetContent (export_node);
00645 }
00646 if (output_content != NULL)
00647 {
00648 object_data = output_content;
00649 }
00650 export_node =
00651 xmlAddChild (params->lister,
00652 xmlNewNode (params->qsf_ns,
00653 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00654 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00655 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00656 xmlNodeAddContent (export_node, object_data);
00657 params->boolean_calculation_done = 1;
00658 }
00659 }
00660 }
00661
00662 static void
00663 qsf_set_format_value (xmlChar * format, gchar * qsf_time_now_as_string,
00664 xmlNodePtr cur_node, QsfParam * params)
00665 {
00666 gint result;
00667 xmlChar *content;
00668 time_t *output;
00669 struct tm *tmp;
00670 time_t tester;
00671 xmlNodePtr kl;
00672 regex_t reg;
00673
00676 result = 0;
00677 if (format == NULL)
00678 {
00679 return;
00680 }
00681 ENTER (" ");
00682 content = xmlNodeGetContent (cur_node);
00683 output =
00684 (time_t *) g_hash_table_lookup (params->qsf_default_hash, content);
00685 if (!output)
00686 {
00689 tester = time (NULL);
00690 tmp = gmtime (&tester);
00693 kl = (xmlNodePtr) g_hash_table_lookup (params->qsf_parameter_hash,
00694 content);
00695 if (!kl)
00696 {
00697 LEAVE (" no suitable date set.");
00698 return;
00699 }
00701 strptime ((char *) xmlNodeGetContent (kl), QSF_XSD_TIME, tmp);
00702 if (!tmp)
00703 {
00704 LEAVE (" empty date field in QSF object.\n");
00705 return;
00706 }
00707 tester = mktime (tmp);
00708 output = &tester;
00709 }
00710 result = regcomp (®, "%[a-zA-Z]", REG_EXTENDED | REG_NOSUB);
00711 result = regexec (®, (gchar *) format, (size_t) 0, NULL, 0);
00712 if (result == REG_NOMATCH)
00713 {
00714 format = BAD_CAST "%F";
00715 }
00716 regfree (®);
00717
00718 strftime (qsf_time_now_as_string, QSF_DATE_LENGTH, (char *) format,
00719 gmtime (output));
00720 LEAVE (" ok");
00721 }
00722
00723 static void
00724 qsf_boolean_set_value (xmlNodePtr parent, QsfParam * params,
00725 gchar * content, xmlNsPtr map_ns)
00726 {
00727 xmlNodePtr cur_node;
00728 xmlChar *boolean_name;
00729
00730 boolean_name = NULL;
00731 for (cur_node = parent->children; cur_node != NULL;
00732 cur_node = cur_node->next)
00733 {
00734 if (qsf_is_element (cur_node, map_ns, QSF_CONDITIONAL_SET))
00735 {
00736 boolean_name =
00737 xmlGetProp (cur_node, BAD_CAST QSF_FORMATTING_OPTION);
00738 qsf_set_format_value (boolean_name, content, cur_node, params);
00739 }
00740 }
00741 }
00742
00743 static void
00744 qsf_calculate_conditional (xmlNodePtr param_node, xmlNodePtr child,
00745 QsfParam * params)
00746 {
00747 xmlNodePtr export_node;
00748 xmlChar *output_content;
00749
00750 output_content = NULL;
00751 if (qsf_is_element (param_node, params->map_ns, QSF_CONDITIONAL))
00752 {
00753 if (params->boolean_calculation_done == 0)
00754 {
00755
00756 output_content =
00757 BAD_CAST qsf_set_handler (param_node,
00758 params->qsf_default_hash,
00759 (gchar *) output_content, params);
00760
00761 if (output_content == NULL)
00762 {
00763 if (NULL !=
00764 xmlGetProp (param_node, BAD_CAST QSF_BOOLEAN_DEFAULT))
00765 {
00766 output_content =
00767 xmlGetProp ((xmlNodePtr)
00768 g_hash_table_lookup (params->
00769 qsf_default_hash,
00770 xmlGetProp
00771 (param_node,
00772 BAD_CAST
00773 QSF_BOOLEAN_DEFAULT)),
00774 BAD_CAST MAP_VALUE_ATTR);
00775 }
00776
00777 if (0 ==
00778 qsf_compare_tag_strings (output_content,
00779 QSF_XML_BOOLEAN_TEST))
00780 {
00781 qsf_boolean_set_value (param_node, params,
00782 (gchar *) output_content, params->map_ns);
00783 export_node =
00784 xmlAddChild (params->lister,
00785 xmlNewNode (params->qsf_ns,
00786 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00787 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00788 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00789 xmlNodeAddContent (export_node, output_content);
00790 params->boolean_calculation_done = 1;
00791 }
00792 }
00793 }
00794 }
00795 }
00796
00797 static void
00798 qsf_add_object_tag (QsfParam * params, gint count)
00799 {
00800 xmlNodePtr extra_node;
00801 GString *str;
00802 xmlChar *property;
00803
00804 str = g_string_new (" ");
00805 g_string_printf (str, "%i", count);
00806 extra_node = NULL;
00807 extra_node = xmlAddChild (params->output_node,
00808 xmlNewNode (params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
00809 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_TYPE,
00810 xmlGetProp (params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
00811 property = xmlCharStrdup (str->str);
00812 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
00813 params->lister = extra_node;
00814 }
00815
00816 static gint
00817 identify_source_func (gconstpointer qsf_object, gconstpointer map)
00818 {
00819 PINFO (" qsf_object=%s, map=%s",
00820 ((QsfObject *) qsf_object)->object_type, (QofIdType) map);
00821 return safe_strcmp (((QsfObject *) qsf_object)->object_type,
00822 (QofIdType) map);
00823 }
00824
00825 static void
00826 qsf_map_calculate_output (xmlNodePtr param_node, xmlNodePtr child,
00827 QsfParam * params)
00828 {
00829 xmlNodePtr export_node;
00830 xmlChar *output_content;
00831 xmlNodePtr input_node;
00832 GList *source;
00833
00834 output_content = xmlNodeGetContent (param_node);
00835 DEBUG (" %s", output_content);
00836
00837 source = g_list_find_custom (params->qsf_object_list,
00838 BAD_CAST xmlGetProp (param_node,
00839 MAP_OBJECT_ATTR), identify_source_func);
00840 PINFO (" checking %s", BAD_CAST xmlGetProp (param_node,
00841 MAP_OBJECT_ATTR));
00842 if (!source)
00843 {
00844 DEBUG (" no source found in list.");
00845 return;
00846 }
00847 params->object_set = source->data;
00848 input_node = g_hash_table_lookup (params->object_set->parameters,
00849 output_content);
00850 DEBUG (" node_value=%s, content=%s",
00851 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR),
00852 xmlNodeGetContent (input_node));
00853 export_node = xmlAddChild (params->lister, xmlNewNode (params->qsf_ns,
00854 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00855 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00856 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00857 xmlNodeAddContent (export_node, xmlNodeGetContent (input_node));
00858 }
00859
00860 static void
00861 qsf_map_object_handler (xmlNodePtr child, xmlNsPtr ns, QsfParam * params)
00862 {
00863 xmlNodePtr param_node;
00864 xmlNsPtr map_ns, qsf_ns;
00865 gint result;
00866
00867 map_ns = ns;
00868 qsf_ns = params->qsf_ns;
00869 param_node = NULL;
00870 result = 0;
00871 if (child == NULL)
00872 {
00873 return;
00874 }
00875 if (ns == NULL)
00876 {
00877 return;
00878 }
00879 params->boolean_calculation_done = 0;
00880
00881 if (qsf_is_element (child, map_ns, MAP_CALCULATE_TAG))
00882 {
00883 params->boolean_calculation_done = 0;
00884
00885 for (param_node = child->children; param_node != NULL;
00886 param_node = param_node->next)
00887 {
00888 if (qsf_is_element (param_node, map_ns, QSF_CONDITIONAL_SET))
00889 {
00890
00891 if (0 ==
00892 qsf_compare_tag_strings (xmlNodeGetContent
00893 (param_node), "qsf_enquiry_date"))
00894 {
00895 qsf_string_default_handler ("qsf_enquiry_date",
00896 params->qsf_default_hash,
00897 params->lister, child, qsf_ns);
00898 }
00899 if (0 ==
00900 qsf_compare_tag_strings (xmlNodeGetContent
00901 (param_node), "qsf_time_now"))
00902 {
00903 qsf_date_default_handler ("qsf_time_now",
00904 params->qsf_default_hash,
00905 params->lister, child, qsf_ns);
00906 }
00907 if (0 ==
00908 qsf_compare_tag_strings (xmlNodeGetContent
00909 (param_node), "qsf_time_string"))
00910 {
00911 qsf_string_default_handler ("qsf_time_string",
00912 params->qsf_default_hash,
00913 params->lister, child, qsf_ns);
00914 }
00915 qsf_map_calculate_output (param_node, child, params);
00916 }
00917 qsf_calculate_conditional (param_node, child, params);
00918 qsf_calculate_else (param_node, child, params);
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 }
00935 }
00936
00937 static void
00938 iterator_cb (xmlNodePtr child, xmlNsPtr ns, QsfParam * params)
00939 {
00940 gchar *object_name;
00941
00942
00943 if (qsf_is_element (child, ns, QSF_OBJECT_TAG))
00944 {
00945 object_name = xmlGetProp (child, QSF_OBJECT_TYPE);
00946 if (0 == safe_strcmp (object_name, params->qof_foreach))
00947 {
00948 params->foreach_limit++;
00949 }
00950 }
00951 }
00952
00953 xmlDocPtr
00954 qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root,
00955 QsfParam * params)
00956 {
00957
00958 struct QsfNodeIterate qsfiter;
00959 xmlDocPtr output_doc;
00960 xmlNode *cur_node;
00961 xmlNode *map_root, *output_root;
00962
00963 g_return_val_if_fail ((mapDoc && qsf_root && params), NULL);
00964 ENTER (" root=%s", qsf_root->name);
00965
00966 qsfiter.ns = params->qsf_ns;
00967 output_doc = xmlNewDoc (BAD_CAST QSF_XML_VERSION);
00968 output_root = xmlNewNode (NULL, BAD_CAST QSF_ROOT_TAG);
00969 xmlDocSetRootElement (output_doc, output_root);
00970 xmlSetNs (output_root, params->qsf_ns);
00971 params->output_node = xmlNewChild (output_root, params->qsf_ns,
00972 BAD_CAST QSF_BOOK_TAG, NULL);
00973 xmlNewProp (params->output_node, BAD_CAST QSF_BOOK_COUNT,
00974 BAD_CAST "1");
00975
00976 qsf_book_node_handler (qsf_root->children->next, params->qsf_ns,
00977 params);
00978
00979 map_root = xmlDocGetRootElement (mapDoc);
00980 params->foreach_limit = 0;
00981 qsfiter.ns = params->map_ns;
00982
00983 qsf_node_foreach (map_root, qsf_map_top_node_handler, &qsfiter, params);
00984
00985 qsfiter.ns = params->qsf_ns;
00986 qsf_node_foreach (qsf_root->children->next, iterator_cb, &qsfiter,
00987 params);
00988 PINFO (" counted %d records", params->foreach_limit);
00989 params->count = 0;
00990 for (cur_node = map_root->children; cur_node != NULL;
00991 cur_node = cur_node->next)
00992 {
00993 params->convert_node = cur_node;
00994 if (qsf_is_element (cur_node, params->map_ns, MAP_OBJECT_TAG))
00995 {
00996 gint i;
00997
00998 params->lister = NULL;
00999 PINFO (" found an object tag. starting calculation");
01000
01001 if (!qof_class_is_registered (BAD_CAST
01002 xmlGetProp (cur_node, MAP_TYPE_ATTR)))
01003 {
01004 continue;
01005 }
01006 qsf_add_object_tag (params, params->count);
01007 params->count++;
01008 qsfiter.ns = params->map_ns;
01009 PINFO (" params->foreach_limit=%d", params->foreach_limit);
01010 for (i = -1; i < params->foreach_limit; i++)
01011 {
01012 qsf_node_foreach (cur_node, qsf_map_object_handler,
01013 &qsfiter, params);
01014 params->qsf_object_list =
01015 g_list_next (params->qsf_object_list);
01016 params->count++;
01017 }
01018 }
01019 }
01020 params->file_type = OUR_QSF_OBJ;
01021
01022 xmlSaveFormatFileEnc ("-", output_doc, "UTF-8", 1);
01023 LEAVE (" ");
01024 return output_doc;
01025 }