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, gchar * content,
00512 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 (gchar *) output_content, params->map_ns);
00615 output_content =
00616 BAD_CAST xmlGetProp ((xmlNodePtr)
00617 g_hash_table_lookup (params->
00618 qsf_default_hash,
00619 object_data), BAD_CAST MAP_VALUE_ATTR);
00620 }
00621 if (object_data != NULL)
00622 {
00623 export_node =
00624 (xmlNodePtr) g_hash_table_lookup (params->
00625 qsf_parameter_hash,
00626 xmlGetProp (params->
00627 child_node, BAD_CAST QSF_OBJECT_TYPE));
00628 object_data = xmlNodeGetContent (export_node);
00629 }
00630 if (output_content != NULL)
00631 {
00632 object_data = output_content;
00633 }
00634 export_node =
00635 xmlAddChild (params->lister,
00636 xmlNewNode (params->qsf_ns,
00637 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00638 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00639 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00640 xmlNodeAddContent (export_node, object_data);
00641 params->boolean_calculation_done = 1;
00642 }
00643 }
00644 }
00645
00646 static void
00647 qsf_set_format_value (xmlChar * format, gchar * qsf_time_now_as_string,
00648 xmlNodePtr cur_node, qsf_param * params)
00649 {
00650 gint result;
00651 xmlChar *content;
00652 time_t *output;
00653 struct tm *tmp;
00654 time_t tester;
00655 xmlNodePtr kl;
00656 regex_t reg;
00657
00660 result = 0;
00661 if (format == NULL)
00662 {
00663 return;
00664 }
00665 ENTER (" ");
00666 content = xmlNodeGetContent (cur_node);
00667 output =
00668 (time_t *) g_hash_table_lookup (params->qsf_default_hash, content);
00669 if (!output)
00670 {
00673 tester = time (NULL);
00674 tmp = gmtime (&tester);
00677 kl = (xmlNodePtr) g_hash_table_lookup (params->qsf_parameter_hash,
00678 content);
00679 if (!kl)
00680 {
00681 LEAVE (" no suitable date set.");
00682 return;
00683 }
00685 strptime ((char *) xmlNodeGetContent (kl), QSF_XSD_TIME, tmp);
00686 if (!tmp)
00687 {
00688 LEAVE (" empty date field in QSF object.\n");
00689 return;
00690 }
00691 tester = mktime (tmp);
00692 output = &tester;
00693 }
00694 result = regcomp (®, "%[a-zA-Z]", REG_EXTENDED | REG_NOSUB);
00695 result = regexec (®, (gchar *) format, (size_t) 0, NULL, 0);
00696 if (result == REG_NOMATCH)
00697 {
00698 format = BAD_CAST "%F";
00699 }
00700 regfree (®);
00701
00702 strftime (qsf_time_now_as_string, QSF_DATE_LENGTH, (char *) format,
00703 gmtime (output));
00704 LEAVE (" ok");
00705 }
00706
00707 static void
00708 qsf_boolean_set_value (xmlNodePtr parent, qsf_param * params,
00709 gchar * content, xmlNsPtr map_ns)
00710 {
00711 xmlNodePtr cur_node;
00712 xmlChar *boolean_name;
00713
00714 boolean_name = NULL;
00715 for (cur_node = parent->children; cur_node != NULL;
00716 cur_node = cur_node->next)
00717 {
00718 if (qsf_is_element (cur_node, map_ns, QSF_CONDITIONAL_SET))
00719 {
00720 boolean_name =
00721 xmlGetProp (cur_node, BAD_CAST QSF_FORMATTING_OPTION);
00722 qsf_set_format_value (boolean_name, content, cur_node, params);
00723 }
00724 }
00725 }
00726
00727 static void
00728 qsf_calculate_conditional (xmlNodePtr param_node, xmlNodePtr child,
00729 qsf_param * params)
00730 {
00731 xmlNodePtr export_node;
00732 xmlChar *output_content;
00733
00734 output_content = NULL;
00735 if (qsf_is_element (param_node, params->map_ns, QSF_CONDITIONAL))
00736 {
00737 if (params->boolean_calculation_done == 0)
00738 {
00739
00740 output_content =
00741 BAD_CAST qsf_set_handler (param_node,
00742 params->qsf_default_hash,
00743 (gchar *) output_content, params);
00744
00745 if (output_content == NULL)
00746 {
00747 if (NULL !=
00748 xmlGetProp (param_node, BAD_CAST QSF_BOOLEAN_DEFAULT))
00749 {
00750 output_content =
00751 xmlGetProp ((xmlNodePtr)
00752 g_hash_table_lookup (params->
00753 qsf_default_hash,
00754 xmlGetProp
00755 (param_node,
00756 BAD_CAST
00757 QSF_BOOLEAN_DEFAULT)),
00758 BAD_CAST MAP_VALUE_ATTR);
00759 }
00760
00761 if (0 ==
00762 qsf_compare_tag_strings (output_content,
00763 QSF_XML_BOOLEAN_TEST))
00764 {
00765 qsf_boolean_set_value (param_node, params,
00766 (gchar *) output_content, params->map_ns);
00767 export_node =
00768 xmlAddChild (params->lister,
00769 xmlNewNode (params->qsf_ns,
00770 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00771 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00772 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00773 xmlNodeAddContent (export_node, output_content);
00774 params->boolean_calculation_done = 1;
00775 }
00776 }
00777 }
00778 }
00779 }
00780
00781 static void
00782 qsf_add_object_tag (qsf_param * params, gint count)
00783 {
00784 xmlNodePtr extra_node;
00785 GString *str;
00786 xmlChar *property;
00787
00788 str = g_string_new (" ");
00789 g_string_printf (str, "%i", count);
00790 extra_node = NULL;
00791 extra_node = xmlAddChild (params->output_node,
00792 xmlNewNode (params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
00793 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_TYPE,
00794 xmlGetProp (params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
00795 property = xmlCharStrdup (str->str);
00796 xmlNewProp (extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
00797 params->lister = extra_node;
00798 }
00799
00800 static gint
00801 identify_source_func (gconstpointer qsf_object, gconstpointer map)
00802 {
00803 PINFO (" qsf_object=%s, map=%s",
00804 ((qsf_objects *) qsf_object)->object_type, (QofIdType) map);
00805 return safe_strcmp (((qsf_objects *) qsf_object)->object_type,
00806 (QofIdType) map);
00807 }
00808
00809 static void
00810 qsf_map_calculate_output (xmlNodePtr param_node, xmlNodePtr child,
00811 qsf_param * params)
00812 {
00813 xmlNodePtr export_node;
00814 xmlChar *output_content;
00815 xmlNodePtr input_node;
00816 GList *source;
00817
00818 output_content = xmlNodeGetContent (param_node);
00819 DEBUG (" %s", output_content);
00820
00821 source = g_list_find_custom (params->qsf_object_list,
00822 BAD_CAST xmlGetProp (param_node,
00823 MAP_OBJECT_ATTR), identify_source_func);
00824 PINFO (" checking %s", BAD_CAST xmlGetProp (param_node,
00825 MAP_OBJECT_ATTR));
00826 if (!source)
00827 {
00828 DEBUG (" no source found in list.");
00829 return;
00830 }
00831 params->object_set = source->data;
00832 input_node = g_hash_table_lookup (params->object_set->parameters,
00833 output_content);
00834 DEBUG (" node_value=%s, content=%s",
00835 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR),
00836 xmlNodeGetContent (input_node));
00837 export_node = xmlAddChild (params->lister, xmlNewNode (params->qsf_ns,
00838 xmlGetProp (child, BAD_CAST QSF_OBJECT_TYPE)));
00839 xmlNewProp (export_node, BAD_CAST QSF_OBJECT_TYPE,
00840 xmlGetProp (child, BAD_CAST MAP_VALUE_ATTR));
00841 xmlNodeAddContent (export_node, xmlNodeGetContent (input_node));
00842 }
00843
00844 static void
00845 qsf_map_object_handler (xmlNodePtr child, xmlNsPtr ns, qsf_param * params)
00846 {
00847 xmlNodePtr param_node;
00848 xmlNsPtr map_ns, qsf_ns;
00849 gint result;
00850
00851 map_ns = ns;
00852 qsf_ns = params->qsf_ns;
00853 param_node = NULL;
00854 result = 0;
00855 if (child == NULL)
00856 {
00857 return;
00858 }
00859 if (ns == NULL)
00860 {
00861 return;
00862 }
00863 params->boolean_calculation_done = 0;
00864
00865 if (qsf_is_element (child, map_ns, MAP_CALCULATE_TAG))
00866 {
00867 params->boolean_calculation_done = 0;
00868
00869 for (param_node = child->children; param_node != NULL;
00870 param_node = param_node->next)
00871 {
00872 if (qsf_is_element (param_node, map_ns, QSF_CONDITIONAL_SET))
00873 {
00874
00875 if (0 ==
00876 qsf_compare_tag_strings (xmlNodeGetContent
00877 (param_node), "qsf_enquiry_date"))
00878 {
00879 qsf_string_default_handler ("qsf_enquiry_date",
00880 params->qsf_default_hash,
00881 params->lister, child, qsf_ns);
00882 }
00883 if (0 ==
00884 qsf_compare_tag_strings (xmlNodeGetContent
00885 (param_node), "qsf_time_now"))
00886 {
00887 qsf_date_default_handler ("qsf_time_now",
00888 params->qsf_default_hash,
00889 params->lister, child, qsf_ns);
00890 }
00891 if (0 ==
00892 qsf_compare_tag_strings (xmlNodeGetContent
00893 (param_node), "qsf_time_string"))
00894 {
00895 qsf_string_default_handler ("qsf_time_string",
00896 params->qsf_default_hash,
00897 params->lister, child, qsf_ns);
00898 }
00899 qsf_map_calculate_output (param_node, child, params);
00900 }
00901 qsf_calculate_conditional (param_node, child, params);
00902 qsf_calculate_else (param_node, child, params);
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 }
00919 }
00920
00921 static void
00922 iterator_cb (xmlNodePtr child, xmlNsPtr ns, qsf_param * params)
00923 {
00924 gchar *object_name;
00925
00926
00927 if (qsf_is_element (child, ns, QSF_OBJECT_TAG))
00928 {
00929 object_name = xmlGetProp (child, QSF_OBJECT_TYPE);
00930 if (0 == safe_strcmp (object_name, params->qof_foreach))
00931 {
00932 params->foreach_limit++;
00933 }
00934 }
00935 }
00936
00937 xmlDocPtr
00938 qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root,
00939 qsf_param * params)
00940 {
00941
00942 struct qsf_node_iterate iter;
00943 xmlDocPtr output_doc;
00944 xmlNode *cur_node;
00945 xmlNode *map_root, *output_root;
00946
00947 g_return_val_if_fail ((mapDoc && qsf_root && params), NULL);
00948 ENTER (" root=%s", qsf_root->name);
00949
00950 iter.ns = params->qsf_ns;
00951 output_doc = xmlNewDoc (BAD_CAST QSF_XML_VERSION);
00952 output_root = xmlNewNode (NULL, BAD_CAST QSF_ROOT_TAG);
00953 xmlDocSetRootElement (output_doc, output_root);
00954 xmlSetNs (output_root, params->qsf_ns);
00955 params->output_node = xmlNewChild (output_root, params->qsf_ns,
00956 BAD_CAST QSF_BOOK_TAG, NULL);
00957 xmlNewProp (params->output_node, BAD_CAST QSF_BOOK_COUNT,
00958 BAD_CAST "1");
00959
00960 qsf_book_node_handler (qsf_root->children->next, params->qsf_ns,
00961 params);
00962
00963 map_root = xmlDocGetRootElement (mapDoc);
00964 params->foreach_limit = 0;
00965 iter.ns = params->map_ns;
00966
00967 qsf_node_foreach (map_root, qsf_map_top_node_handler, &iter, params);
00968
00969 iter.ns = params->qsf_ns;
00970 qsf_node_foreach (qsf_root->children->next, iterator_cb, &iter,
00971 params);
00972 PINFO (" counted %d records", params->foreach_limit);
00973 params->count = 0;
00974 for (cur_node = map_root->children; cur_node != NULL;
00975 cur_node = cur_node->next)
00976 {
00977 params->convert_node = cur_node;
00978 if (qsf_is_element (cur_node, params->map_ns, MAP_OBJECT_TAG))
00979 {
00980 gint i;
00981
00982 params->lister = NULL;
00983 PINFO (" found an object tag. starting calculation");
00984
00985 if (!qof_class_is_registered (BAD_CAST
00986 xmlGetProp (cur_node, MAP_TYPE_ATTR)))
00987 {
00988 continue;
00989 }
00990 qsf_add_object_tag (params, params->count);
00991 params->count++;
00992 iter.ns = params->map_ns;
00993 PINFO (" params->foreach_limit=%d", params->foreach_limit);
00994 for (i = -1; i < params->foreach_limit; i++)
00995 {
00996 qsf_node_foreach (cur_node, qsf_map_object_handler, &iter,
00997 params);
00998 params->qsf_object_list =
00999 g_list_next (params->qsf_object_list);
01000 params->count++;
01001 }
01002 }
01003 }
01004 params->file_type = OUR_QSF_OBJ;
01005
01006 xmlSaveFormatFileEnc ("-", output_doc, "UTF-8", 1);
01007 LEAVE (" ");
01008 return output_doc;
01009 }