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