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 qsf_validator * 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 = ERR_QSF_BAD_QOF_VERSION;
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 = ERR_QSF_WRONG_MAP;
00176 }
00177 }
00178 }
00179
00180 static QofBackendError
00181 check_qsf_object_with_map_internal (xmlDocPtr map_doc, xmlDocPtr doc)
00182 {
00183 xmlNodePtr map_root, object_root;
00184 struct qsf_node_iterate iter;
00185 qsf_validator 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 = ERR_BACKEND_NO_ERR;
00197 map_ns = map_root->ns;
00198 iter.ns = object_root->ns;
00199 qsf_valid_foreach (object_root, qsf_object_validation_handler, &iter,
00200 &valid);
00201 iter.ns = map_ns;
00202 qsf_valid_foreach (map_root, qsf_map_validation_handler, &iter,
00203 &valid);
00204 if (valid.error_state != ERR_BACKEND_NO_ERR)
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 if (valid.error_state != ERR_BACKEND_NO_ERR)
00231 {
00232 valid.error_state = ERR_QSF_WRONG_MAP;
00233 }
00234 g_hash_table_destroy (valid.object_table);
00235 g_hash_table_destroy (valid.map_table);
00236 return valid.error_state;
00237 }
00238 g_hash_table_destroy (valid.object_table);
00239 g_hash_table_destroy (valid.map_table);
00240 return ERR_BACKEND_NO_ERR;
00241 }
00242
00243 gboolean
00244 is_qsf_object_with_map_be (gchar * map_file, qsf_param * params)
00245 {
00246 xmlDocPtr doc, map_doc;
00247 QofBackendError result;
00248 gchar *path, *map_path;
00249
00250 g_return_val_if_fail ((params != NULL), FALSE);
00251 path = g_strdup (params->filepath);
00252 map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
00253 PINFO (" checking map file '%s'", map_path);
00254 if (path == NULL)
00255 {
00256 qof_backend_set_error (params->be, ERR_FILEIO_FILE_NOT_FOUND);
00257 return FALSE;
00258 }
00259 doc = xmlParseFile (path);
00260 if (doc == NULL)
00261 {
00262 qof_backend_set_error (params->be, ERR_FILEIO_PARSE_ERROR);
00263 return FALSE;
00264 }
00265 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00266 {
00267 qof_backend_set_error (params->be, ERR_QSF_INVALID_OBJ);
00268 return FALSE;
00269 }
00270 if (map_path == NULL)
00271 {
00272 qof_backend_set_error (params->be, ERR_FILEIO_FILE_NOT_FOUND);
00273 return FALSE;
00274 }
00275 map_doc = xmlParseFile (map_path);
00276 if (map_doc == NULL)
00277 {
00278 qof_backend_set_error (params->be, ERR_FILEIO_PARSE_ERROR);
00279 return FALSE;
00280 }
00281 result = check_qsf_object_with_map_internal (map_doc, doc);
00282 qof_backend_set_error (params->be, result);
00283 return (result == ERR_BACKEND_NO_ERR) ? TRUE : FALSE;
00284 }
00285
00286 gboolean
00287 is_qsf_object_with_map (const gchar * path, gchar * map_file)
00288 {
00289 xmlDocPtr doc, map_doc;
00290 QofBackendError result;
00291 gchar *map_path;
00292
00293 map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
00294 if (path == NULL)
00295 {
00296 return FALSE;
00297 }
00298 doc = xmlParseFile (path);
00299 if (doc == NULL)
00300 {
00301 return FALSE;
00302 }
00303 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00304 {
00305 return FALSE;
00306 }
00307 if (map_path == NULL)
00308 {
00309 return FALSE;
00310 }
00311 map_doc = xmlParseFile (map_path);
00312 result = check_qsf_object_with_map_internal (map_doc, doc);
00313 return (result == ERR_BACKEND_NO_ERR) ? TRUE : FALSE;
00314 }
00315
00316 gboolean
00317 is_qsf_map_be (qsf_param * params)
00318 {
00319 xmlDocPtr doc;
00320 struct qsf_node_iterate iter;
00321 qsf_validator valid;
00322 xmlNodePtr map_root;
00323 xmlNsPtr map_ns;
00324 gchar *path;
00325
00326 g_return_val_if_fail ((params != NULL), FALSE);
00327 qof_backend_get_error (params->be);
00328 path = g_strdup (params->filepath);
00329 if (path == NULL)
00330 {
00331 qof_backend_set_error (params->be, ERR_FILEIO_FILE_NOT_FOUND);
00332 return FALSE;
00333 }
00334 doc = xmlParseFile (path);
00335 if (doc == NULL)
00336 {
00337 qof_backend_set_error (params->be, ERR_FILEIO_PARSE_ERROR);
00338 return FALSE;
00339 }
00340 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00341 {
00342 qof_backend_set_error (params->be, ERR_QSF_INVALID_MAP);
00343 return FALSE;
00344 }
00345 map_root = xmlDocGetRootElement (doc);
00346 map_ns = map_root->ns;
00347 iter.ns = map_ns;
00348 valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
00349 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
00350 valid.error_state = ERR_BACKEND_NO_ERR;
00351 qsf_valid_foreach (map_root, qsf_map_validation_handler, &iter,
00352 &valid);
00353 if (valid.error_state != ERR_BACKEND_NO_ERR)
00354 {
00355 qof_backend_set_error (params->be, valid.error_state);
00356 g_hash_table_destroy (valid.object_table);
00357 return FALSE;
00358 }
00359 qof_backend_get_error (params->be);
00360 g_hash_table_destroy (valid.object_table);
00361 return TRUE;
00362 }
00363
00364 gboolean
00365 is_qsf_map (const gchar * path)
00366 {
00367 xmlDocPtr doc;
00368 struct qsf_node_iterate iter;
00369 qsf_validator valid;
00370 xmlNodePtr map_root;
00371 xmlNsPtr map_ns;
00372
00373 g_return_val_if_fail ((path != NULL), FALSE);
00374 if (path == NULL)
00375 {
00376 return FALSE;
00377 }
00378 doc = xmlParseFile (path);
00379 if (doc == NULL)
00380 {
00381 return FALSE;
00382 }
00383 if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00384 {
00385 return FALSE;
00386 }
00387 map_root = xmlDocGetRootElement (doc);
00388 map_ns = map_root->ns;
00389 iter.ns = map_ns;
00390 valid.error_state = ERR_BACKEND_NO_ERR;
00391 valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
00392 qsf_valid_foreach (map_root, qsf_map_validation_handler, &iter,
00393 &valid);
00394 if (valid.error_state != ERR_BACKEND_NO_ERR)
00395 {
00396 g_hash_table_destroy (valid.map_table);
00397 return FALSE;
00398 }
00399 g_hash_table_destroy (valid.map_table);
00400 return TRUE;
00401 }
00402
00403 static void
00404 qsf_map_default_handler (xmlNodePtr child, xmlNsPtr ns, qsf_param * params)
00405 {
00406 xmlChar *qsf_enum;
00407 gchar *iterate;
00408
00409 g_return_if_fail (params->qsf_define_hash != NULL);
00410 iterate = NULL;
00411 if (qsf_is_element (child, ns, MAP_DEFINE_TAG))
00412 {
00413 iterate = xmlGetProp (child, MAP_ITERATE_ATTR);
00414 if ((qof_util_bool_to_int (iterate) == 1) &&
00415 (qof_class_is_registered
00416 (xmlGetProp (child, BAD_CAST MAP_E_TYPE))))
00417 {
00418 params->qof_foreach = xmlGetProp (child, BAD_CAST MAP_E_TYPE);
00419 PINFO (" iterating over '%s' objects", params->qof_foreach);
00420 }
00421 if (NULL == g_hash_table_lookup (params->qsf_define_hash,
00422 xmlGetProp (child, BAD_CAST MAP_E_TYPE)))
00423 {
00424 g_hash_table_insert (params->qsf_define_hash,
00425 xmlGetProp (child, BAD_CAST MAP_E_TYPE),
00426 params->child_node);
00427 }
00428 else
00429 {
00430 qof_backend_set_error (params->be, ERR_QSF_BAD_MAP);
00431 PERR (" ERR_QSF_BAD_MAP set");
00432 return;
00433 }
00434 }
00435 if (qsf_is_element (child, ns, MAP_DEFAULT_TAG))
00436 {
00437 if (qsf_strings_equal
00438 (xmlGetProp (child, BAD_CAST MAP_TYPE_ATTR), MAP_ENUM_TYPE))
00439 {
00440 qsf_enum = xmlNodeGetContent (child);
00442 PERR (" enum todo incomplete");
00446 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
00447 xmlNodeGetContent (child)))
00448 {
00449 g_hash_table_insert (params->qsf_default_hash,
00450 xmlNodeGetContent (child), child);
00451 }
00452 else
00453 {
00454 qof_backend_set_error (params->be, ERR_QSF_BAD_MAP);
00455 PERR (" ERR_QSF_BAD_MAP set");
00456 return;
00457 }
00458 }
00460 else
00461 {
00462 if (NULL == g_hash_table_lookup (params->qsf_default_hash,
00463 xmlGetProp (child, BAD_CAST MAP_NAME_ATTR)))
00464 {
00465 g_hash_table_insert (params->qsf_default_hash,
00466 xmlGetProp (child, BAD_CAST MAP_NAME_ATTR), child);
00467 }
00468 else
00469
00470
00471 {
00472 qof_backend_set_error (params->be, ERR_QSF_BAD_MAP);
00473 PERR (" ERR_QSF_BAD_MAP set");
00474 return;
00475 }
00476 }
00477 }
00478 }
00479
00480 static void
00481 qsf_map_top_node_handler (xmlNodePtr child, xmlNsPtr ns,
00482 qsf_param * params)
00483 {
00484 xmlChar *qof_version;
00485 gchar *buff;
00486 struct qsf_node_iterate iter;
00487
00488 if (!params->qsf_define_hash)
00489 return;
00490 if (!params->qsf_default_hash)
00491 return;
00492 ENTER (" map top node child=%s", child->name);
00493 buff = NULL;
00494 if (qsf_is_element (child, ns, MAP_DEFINITION_TAG))
00495 {
00496 qof_version = xmlGetProp (child, BAD_CAST MAP_QOF_VERSION);
00497 buff = g_strdup_printf ("%i", QSF_QOF_VERSION);
00498 if (xmlStrcmp (qof_version, BAD_CAST buff) != 0)
00499 {
00500 qof_backend_set_error (params->be, ERR_QSF_BAD_QOF_VERSION);
00501 LEAVE (" ERR_QSF_BAD_QOF_VERSION set");
00502 return;
00503 }
00504 iter.ns = ns;
00505 qsf_node_foreach (child, qsf_map_default_handler, &iter, params);
00506 }
00507 LEAVE (" ");
00508 }
00509
00510 static char *
00511 qsf_else_set_value (xmlNodePtr parent, GHashTable * default_hash,
00512 gchar * content, xmlNsPtr map_ns)
00513 {
00514 xmlNodePtr cur_node;
00515
00516 content = NULL;
00517 for (cur_node = parent->children; cur_node != NULL;
00518 cur_node = cur_node->next)
00519 {
00520 if (qsf_is_element (cur_node, map_ns, QSF_CONDITIONAL_SET))
00521 {
00522 content = (gchar *) xmlNodeGetContent (cur_node);
00523 return content;
00524 }
00525 }
00526 return NULL;
00527 }
00528
00529
00530
00531
00532
00533 static gchar *
00534 qsf_set_handler (xmlNodePtr parent, GHashTable * default_hash,
00535 gchar * content, qsf_param * params)
00536 {
00537 xmlNodePtr cur_node, lookup_node;
00538
00539 ENTER (" lookup problem");
00540 content = NULL;
00541 for (cur_node = parent->children; cur_node != NULL;
00542 cur_node = cur_node->next)
00543 {
00544 if (qsf_is_element (cur_node, params->map_ns, QSF_CONDITIONAL_SET))
00545 {
00546 content = (gchar *) xmlGetProp (cur_node, BAD_CAST QSF_OPTION);
00547 if (qsf_strings_equal (xmlGetProp (cur_node,
00548 BAD_CAST QSF_OPTION), "qsf_lookup_string"))
00549 {
00550 lookup_node =
00551 (xmlNodePtr) g_hash_table_lookup (default_hash,
00552 xmlNodeGetContent (cur_node));
00553 content =
00554 (gchar *) xmlGetProp (lookup_node,
00555 BAD_CAST MAP_VALUE_ATTR);
00557
00558 g_message ("Lookup %s in the receiving application\n",
00559 content);
00560 LEAVE (" todo");
00561 return content;
00562 }
00563 if (content)
00564 {
00565 lookup_node =
00566 (xmlNodePtr) g_hash_table_lookup (default_hash,
00567 xmlNodeGetContent (cur_node));
00568 content =
00569 (gchar *) xmlGetProp (lookup_node, BAD_CAST "value");
00570 return content;
00571 }
00572 content = (gchar *) xmlGetProp (parent, BAD_CAST "boolean");
00573 if (!content)
00574 {
00576 lookup_node =
00577 (xmlNodePtr) g_hash_table_lookup (params->
00578 qsf_parameter_hash,
00579 xmlGetProp (parent->parent, BAD_CAST MAP_TYPE_ATTR));
00580 if (lookup_node)
00581 {
00582 return (gchar *) xmlNodeGetContent (lookup_node);
00583 }
00584 LEAVE (" check arguments");
00585 return (gchar *) xmlNodeGetContent (cur_node);
00586 }
00587 }
00588 }
00589 LEAVE (" null");
00590 return NULL;
00591 }
00592
00593 static void
00594 qsf_calculate_else (xmlNodePtr param_node, xmlNodePtr child,
00595 qsf_param * params)
00596 {
00597 xmlNodePtr export_node;
00598 xmlChar *output_content, *object_data;
00599
00600 if (qsf_is_element (param_node, params->map_ns, QSF_CONDITIONAL_ELSE))
00601 {
00602 if (params->boolean_calculation_done == 0)
00603 {
00604 output_content = object_data = NULL;
00605 output_content = BAD_CAST qsf_set_handler (param_node,
00606 params->
00607 qsf_default_hash, (gchar *) output_content, params);
00608 if (output_content == NULL)
00609 {
00610 output_content =
00611 xmlGetProp (param_node, BAD_CAST MAP_TYPE_ATTR);
00612 object_data =
00613 BAD_CAST qsf_else_set_value (param_node,
00614 params->qsf_default_hash,
00615 (gchar *) output_content, params->map_ns);
00616 output_content =
00617 BAD_CAST xmlGetProp ((xmlNodePtr)
00618 g_hash_table_lookup (params->
00619 qsf_default_hash,
00620 object_data), BAD_CAST MAP_VALUE_ATTR);
00621 }
00622 if (object_data != NULL)
00623 {
00624 export_node =
00625 (xmlNodePtr) g_hash_table_lookup (params->
00626 qsf_parameter_hash,
00627 xmlGetProp (params->
00628 child_node, BAD_CAST QSF_OBJECT_TYPE));
00629 object_data = xmlNodeGetContent (export_node);
00630 }
00631 if (output_content != NULL)
00632 {
00633 object_data = output_content;
00634 }
00635 export_node =
00636 xmlAddChild (params->lister,
00637 xmlNewNode (params->qsf_ns,
00638 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00639 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00640 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00641 xmlNodeAddContent (export_node, object_data);
00642 params->boolean_calculation_done = 1;
00643 }
00644 }
00645 }
00646
00647 static void
00648 qsf_set_format_value (xmlChar * format, gchar * qsf_time_now_as_string,
00649 xmlNodePtr cur_node, qsf_param * params)
00650 {
00651 gint result;
00652 xmlChar *content;
00653 time_t *output;
00654 struct tm *tmp;
00655 time_t tester;
00656 xmlNodePtr kl;
00657 regex_t reg;
00658
00661 result = 0;
00662 if (format == NULL)
00663 {
00664 return;
00665 }
00666 ENTER (" ");
00667 content = xmlNodeGetContent (cur_node);
00668 output =
00669 (time_t *) g_hash_table_lookup (params->qsf_default_hash, content);
00670 if (!output)
00671 {
00674 tester = time (NULL);
00675 tmp = gmtime (&tester);
00678 kl = (xmlNodePtr) g_hash_table_lookup (params->qsf_parameter_hash,
00679 content);
00680 if (!kl)
00681 {
00682 LEAVE (" no suitable date set.");
00683 return;
00684 }
00686 strptime ((char *) xmlNodeGetContent (kl), QSF_XSD_TIME, tmp);
00687 if (!tmp)
00688 {
00689 LEAVE (" empty date field in QSF object.\n");
00690 return;
00691 }
00692 tester = mktime (tmp);
00693 output = &tester;
00694 }
00695 result = regcomp (®, "%[a-zA-Z]", REG_EXTENDED | REG_NOSUB);
00696 result = regexec (®, (gchar *) format, (size_t) 0, NULL, 0);
00697 if (result == REG_NOMATCH)
00698 {
00699 format = BAD_CAST "%F";
00700 }
00701 regfree (®);
00702
00703 strftime (qsf_time_now_as_string, QSF_DATE_LENGTH, (char *) format,
00704 gmtime (output));
00705 LEAVE (" ok");
00706 }
00707
00708 static void
00709 qsf_boolean_set_value (xmlNodePtr parent, qsf_param * params,
00710 gchar * content, xmlNsPtr map_ns)
00711 {
00712 xmlNodePtr cur_node;
00713 xmlChar *boolean_name;
00714
00715 boolean_name = NULL;
00716 for (cur_node = parent->children; cur_node != NULL;
00717 cur_node = cur_node->next)
00718 {
00719 if (qsf_is_element (cur_node, map_ns, QSF_CONDITIONAL_SET))
00720 {
00721 boolean_name =
00722 xmlGetProp (cur_node, BAD_CAST QSF_FORMATTING_OPTION);
00723 qsf_set_format_value (boolean_name, content, cur_node, params);
00724 }
00725 }
00726 }
00727
00728 static void
00729 qsf_calculate_conditional (xmlNodePtr param_node, xmlNodePtr child,
00730 qsf_param * params)
00731 {
00732 xmlNodePtr export_node;
00733 xmlChar *output_content;
00734
00735 output_content = NULL;
00736 if (qsf_is_element (param_node, params->map_ns, QSF_CONDITIONAL))
00737 {
00738 if (params->boolean_calculation_done == 0)
00739 {
00740
00741 output_content =
00742 BAD_CAST qsf_set_handler (param_node,
00743 params->qsf_default_hash,
00744 (gchar *) output_content, params);
00745
00746 if (output_content == NULL)
00747 {
00748 if (NULL !=
00749 xmlGetProp (param_node, BAD_CAST QSF_BOOLEAN_DEFAULT))
00750 {
00751 output_content =
00752 xmlGetProp ((xmlNodePtr)
00753 g_hash_table_lookup (params->
00754 qsf_default_hash,
00755 xmlGetProp
00756 (param_node,
00757 BAD_CAST
00758 QSF_BOOLEAN_DEFAULT)),
00759 BAD_CAST MAP_VALUE_ATTR);
00760 }
00761
00762 if (0 ==
00763 qsf_compare_tag_strings (output_content,
00764 QSF_XML_BOOLEAN_TEST))
00765 {
00766 qsf_boolean_set_value (param_node, params,
00767 (gchar *) output_content, params->map_ns);
00768 export_node =
00769 xmlAddChild (params->lister,
00770 xmlNewNode (params->qsf_ns,
00771 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00772 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00773 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00774 xmlNodeAddContent (export_node, output_content);
00775 params->boolean_calculation_done = 1;
00776 }
00777 }
00778 }
00779 }
00780 }
00781
00782 static void
00783 qsf_add_object_tag (qsf_param * params, gint count)
00784 {
00785 xmlNodePtr extra_node;
00786 GString *str;
00787 xmlChar *property;
00788
00789 str = g_string_new (" ");
00790 g_string_printf (str, "%i", count);
00791 extra_node = NULL;
00792 extra_node = xmlAddChild (params->output_node,
00793 xmlNewNode (params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
00794 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_TYPE,
00795 xmlGetProp (params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
00796 property = xmlCharStrdup (str->str);
00797 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
00798 params->lister = extra_node;
00799 }
00800
00801 static gint
00802 identify_source_func (gconstpointer qsf_object, gconstpointer map)
00803 {
00804 PINFO (" qsf_object=%s, map=%s",
00805 ((qsf_objects *) qsf_object)->object_type, (QofIdType) map);
00806 return safe_strcmp (((qsf_objects *) qsf_object)->object_type,
00807 (QofIdType) map);
00808 }
00809
00810 static void
00811 qsf_map_calculate_output (xmlNodePtr param_node, xmlNodePtr child,
00812 qsf_param * params)
00813 {
00814 xmlNodePtr export_node;
00815 xmlChar *output_content;
00816 xmlNodePtr input_node;
00817 GList *source;
00818
00819 output_content = xmlNodeGetContent (param_node);
00820 DEBUG (" %s", output_content);
00821
00822 source = g_list_find_custom (params->qsf_object_list,
00823 BAD_CAST xmlGetProp (param_node,
00824 MAP_OBJECT_ATTR), identify_source_func);
00825 PINFO (" checking %s", BAD_CAST xmlGetProp (param_node,
00826 MAP_OBJECT_ATTR));
00827 if (!source)
00828 {
00829 DEBUG (" no source found in list.");
00830 return;
00831 }
00832 params->object_set = source->data;
00833 input_node = g_hash_table_lookup (params->object_set->parameters,
00834 output_content);
00835 DEBUG (" node_value=%s, content=%s",
00836 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR),
00837 xmlNodeGetContent (input_node));
00838 export_node = xmlAddChild (params->lister, xmlNewNode (params->qsf_ns,
00839 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00840 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00841 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00842 xmlNodeAddContent (export_node, xmlNodeGetContent (input_node));
00843 }
00844
00845 static void
00846 qsf_map_object_handler (xmlNodePtr child, xmlNsPtr ns, qsf_param * params)
00847 {
00848 xmlNodePtr param_node;
00849 xmlNsPtr map_ns, qsf_ns;
00850 gint result;
00851
00852 map_ns = ns;
00853 qsf_ns = params->qsf_ns;
00854 param_node = NULL;
00855 result = 0;
00856 if (child == NULL)
00857 {
00858 return;
00859 }
00860 if (ns == NULL)
00861 {
00862 return;
00863 }
00864 params->boolean_calculation_done = 0;
00865
00866 if (qsf_is_element (child, map_ns, MAP_CALCULATE_TAG))
00867 {
00868 params->boolean_calculation_done = 0;
00869
00870 for (param_node = child->children; param_node != NULL;
00871 param_node = param_node->next)
00872 {
00873 if (qsf_is_element (param_node, map_ns, QSF_CONDITIONAL_SET))
00874 {
00875
00876 if (0 ==
00877 qsf_compare_tag_strings (xmlNodeGetContent
00878 (param_node), "qsf_enquiry_date"))
00879 {
00880 qsf_string_default_handler ("qsf_enquiry_date",
00881 params->qsf_default_hash,
00882 params->lister, child, qsf_ns);
00883 }
00884 if (0 ==
00885 qsf_compare_tag_strings (xmlNodeGetContent
00886 (param_node), "qsf_time_now"))
00887 {
00888 qsf_date_default_handler ("qsf_time_now",
00889 params->qsf_default_hash,
00890 params->lister, child, qsf_ns);
00891 }
00892 if (0 ==
00893 qsf_compare_tag_strings (xmlNodeGetContent
00894 (param_node), "qsf_time_string"))
00895 {
00896 qsf_string_default_handler ("qsf_time_string",
00897 params->qsf_default_hash,
00898 params->lister, child, qsf_ns);
00899 }
00900 qsf_map_calculate_output (param_node, child, params);
00901 }
00902 qsf_calculate_conditional (param_node, child, params);
00903 qsf_calculate_else (param_node, child, params);
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 }
00920 }
00921
00922 static void
00923 iterator_cb (xmlNodePtr child, xmlNsPtr ns, qsf_param * params)
00924 {
00925 gchar *object_name;
00926
00927
00928 if (qsf_is_element (child, ns, QSF_OBJECT_TAG))
00929 {
00930 object_name = xmlGetProp (child, QSF_OBJECT_TYPE);
00931 if (0 == safe_strcmp (object_name, params->qof_foreach))
00932 {
00933 params->foreach_limit++;
00934 }
00935 }
00936 }
00937
00938 xmlDocPtr
00939 qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root,
00940 qsf_param * params)
00941 {
00942
00943 struct qsf_node_iterate iter;
00944 xmlDocPtr output_doc;
00945 xmlNode *cur_node;
00946 xmlNode *map_root, *output_root;
00947
00948 g_return_val_if_fail ((mapDoc && qsf_root && params), NULL);
00949 ENTER (" root=%s", qsf_root->name);
00950
00951 iter.ns = params->qsf_ns;
00952 output_doc = xmlNewDoc (BAD_CAST QSF_XML_VERSION);
00953 output_root = xmlNewNode (NULL, BAD_CAST QSF_ROOT_TAG);
00954 xmlDocSetRootElement (output_doc, output_root);
00955 xmlSetNs (output_root, params->qsf_ns);
00956 params->output_node = xmlNewChild (output_root, params->qsf_ns,
00957 BAD_CAST QSF_BOOK_TAG, NULL);
00958 xmlNewProp (params->output_node, BAD_CAST QSF_BOOK_COUNT,
00959 BAD_CAST "1");
00960
00961 qsf_book_node_handler (qsf_root->children->next, params->qsf_ns,
00962 params);
00963
00964 map_root = xmlDocGetRootElement (mapDoc);
00965 params->foreach_limit = 0;
00966 iter.ns = params->map_ns;
00967
00968 qsf_node_foreach (map_root, qsf_map_top_node_handler, &iter, params);
00969
00970 iter.ns = params->qsf_ns;
00971 qsf_node_foreach (qsf_root->children->next, iterator_cb, &iter,
00972 params);
00973 PINFO (" counted %d records", params->foreach_limit);
00974 params->count = 0;
00975 for (cur_node = map_root->children; cur_node != NULL;
00976 cur_node = cur_node->next)
00977 {
00978 params->convert_node = cur_node;
00979 if (qsf_is_element (cur_node, params->map_ns, MAP_OBJECT_TAG))
00980 {
00981 gint i;
00982
00983 params->lister = NULL;
00984 PINFO (" found an object tag. starting calculation");
00985
00986 if (!qof_class_is_registered (BAD_CAST
00987 xmlGetProp (cur_node, MAP_TYPE_ATTR)))
00988 {
00989 continue;
00990 }
00991 qsf_add_object_tag (params, params->count);
00992 params->count++;
00993 iter.ns = params->map_ns;
00994 PINFO (" params->foreach_limit=%d", params->foreach_limit);
00995 for (i = -1; i < params->foreach_limit; i++)
00996 {
00997 qsf_node_foreach (cur_node, qsf_map_object_handler, &iter,
00998 params);
00999 params->qsf_object_list =
01000 g_list_next (params->qsf_object_list);
01001 params->count++;
01002 }
01003 }
01004 }
01005 params->file_type = OUR_QSF_OBJ;
01006
01007 xmlSaveFormatFileEnc ("-", output_doc, "UTF-8", 1);
01008 LEAVE (" ");
01009 return output_doc;
01010 }