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 #ifndef HAVE_STRPTIME
00037 #include "strptime.h"
00038 #endif
00039
00040 static QofLogModule log_module = QOF_MOD_QSF;
00041
00042 static void
00043 qsf_date_default_handler(const gchar *default_name, GHashTable *qsf_default_hash,
00044 xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
00045 {
00046 xmlNodePtr output_parent;
00047 time_t *qsf_time;
00048 gchar date_as_string[QSF_DATE_LENGTH];
00049
00050 output_parent = xmlAddChild(parent_tag, xmlNewNode(ns,
00051 xmlGetProp(import_node, BAD_CAST QSF_OBJECT_TYPE)));
00052 xmlNewProp(output_parent, BAD_CAST QSF_OBJECT_TYPE,
00053 xmlGetProp(import_node, BAD_CAST MAP_VALUE_ATTR));
00054 qsf_time = (time_t*)g_hash_table_lookup(qsf_default_hash, default_name);
00055 qof_strftime(date_as_string, QSF_DATE_LENGTH, QSF_XSD_TIME, gmtime(qsf_time));
00056 xmlNodeAddContent(output_parent, BAD_CAST date_as_string);
00057 }
00058
00059 static void
00060 qsf_string_default_handler(const gchar *default_name, 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, 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 = (xmlChar *)g_hash_table_lookup(qsf_default_hash, default_name);
00071 xmlNodeAddContent(node, output);
00072 }
00073
00074 static void
00075 qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
00076 {
00077 xmlChar *qof_version, *match;
00078 GString *buff;
00079 xmlNodePtr child_node;
00080 xmlChar *obj_type;
00081
00082 if (qsf_is_element(child, ns, MAP_DEFINITION_TAG))
00083 {
00084 qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
00085 buff = g_string_new(" ");
00086 g_string_printf(buff, "%i", QSF_QOF_VERSION);
00087 if (xmlStrcmp(qof_version, BAD_CAST buff->str) != 0)
00088 {
00089 valid->error_state = ERR_QSF_BAD_QOF_VERSION;
00090 return;
00091 }
00092 for (child_node = child->children; child_node != NULL;
00093 child_node = child_node->next)
00094 {
00095 if (qsf_is_element(child_node, ns, MAP_DEFINE_TAG))
00096 {
00097 g_hash_table_insert(valid->validation_table,
00098 xmlGetProp(child_node, BAD_CAST MAP_E_TYPE),
00099 xmlNodeGetContent(child_node));
00100 }
00101 }
00102 }
00103 if (qsf_is_element(child, ns, MAP_OBJECT_TAG))
00104 {
00105 match = NULL;
00106 obj_type = xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR);
00107 match = BAD_CAST g_hash_table_lookup( valid->validation_table, obj_type);
00108 if (match)
00109 {
00110 valid->map_calculated_count++;
00111 if (TRUE == qof_class_is_registered((QofIdTypeConst) obj_type))
00112 {
00113 valid->qof_registered_count++;
00114 PINFO (" %s is to be calculated", obj_type);
00115 }
00116 else
00117 {
00118 PINFO (" %s to be mapped", obj_type);
00119 }
00120 }
00121 }
00122 }
00123
00124 gboolean is_qsf_object_with_map_be(gchar *map_file, qsf_param *params)
00125 {
00126 xmlDocPtr doc, map_doc;
00127 gint valid_count, calc_count;
00128 struct qsf_node_iterate iter;
00129 xmlNodePtr map_root, object_root;
00130 xmlNsPtr map_ns;
00131 qsf_validator valid;
00132 gchar *path;
00133 gchar *map_path;
00134
00135 g_return_val_if_fail((params != NULL), FALSE);
00136 PINFO (" mapfile=%s", map_file);
00137 path = g_strdup(params->filepath);
00138 map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
00139 if (path == NULL)
00140 {
00141 qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
00142 return FALSE;
00143 }
00144 doc = xmlParseFile(path);
00145 if (doc == NULL)
00146 {
00147 qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
00148 return FALSE;
00149 }
00150 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00151 {
00152 qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
00153 return FALSE;
00154 }
00155 object_root = xmlDocGetRootElement(doc);
00156 if (map_path == NULL)
00157 {
00158 qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
00159 return FALSE;
00160 }
00161 valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00162 map_doc = xmlParseFile(map_path);
00163 if (map_doc == NULL)
00164 {
00165 qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
00166 return FALSE;
00167 }
00168 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc))
00169 {
00170 qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
00171 return FALSE;
00172 }
00173 map_root = xmlDocGetRootElement(map_doc);
00174 valid.map_calculated_count = 0;
00175 valid.valid_object_count = 0;
00176 valid.qof_registered_count = 0;
00177 valid.error_state = ERR_BACKEND_NO_ERR;
00178 map_ns = map_root->ns;
00179 iter.ns = object_root->ns;
00180 qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
00181 iter.ns = map_ns;
00182 qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
00183 if (valid.error_state != ERR_BACKEND_NO_ERR)
00184 {
00185 qof_backend_set_error(params->be, valid.error_state);
00186 g_hash_table_destroy(valid.validation_table);
00187 return FALSE;
00188 }
00189
00190
00191
00192
00193
00194 valid_count = g_hash_table_size(valid.validation_table) - valid.map_calculated_count;
00195 calc_count = valid.map_calculated_count -
00196 (valid.valid_object_count + valid.qof_registered_count);
00197 if (valid_count == 0 && calc_count == 0)
00198 {
00199 g_hash_table_destroy(valid.validation_table);
00200 qof_backend_get_error(params->be);
00201 return TRUE;
00202 }
00203 qof_backend_set_error(params->be, ERR_QSF_WRONG_MAP);
00204
00205 PINFO (" Map is wrong. map:%d object:%d reg:%d size:%d result:%d",
00206 valid.map_calculated_count, valid.valid_object_count,
00207 valid.qof_registered_count,
00208 g_hash_table_size(valid.validation_table), valid_count);
00209 if (valid_count != 0)
00210 {
00211 PINFO (" size - map != 0. actual: %d.", valid_count);
00212 }
00213 if (calc_count != 0)
00214 {
00215 PINFO (" map - (object + registered) != 0. Actual: %d.", calc_count);
00216 }
00217 g_hash_table_destroy(valid.validation_table);
00218 return TRUE;
00219 }
00220
00221 gboolean is_qsf_object_with_map(const gchar *path, gchar *map_file)
00222 {
00223 xmlDocPtr doc, map_doc;
00224 gint valid_count;
00225 struct qsf_node_iterate iter;
00226 xmlNodePtr map_root, object_root;
00227 xmlNsPtr map_ns;
00228 qsf_validator valid;
00229 gchar *map_path;
00230
00231 map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
00232 if (path == NULL)
00233 {
00234 return FALSE;
00235 }
00236 doc = xmlParseFile(path);
00237 if (doc == NULL)
00238 {
00239 return FALSE;
00240 }
00241 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00242 {
00243 return FALSE;
00244 }
00245 object_root = xmlDocGetRootElement(doc);
00246 if (map_path == NULL)
00247 {
00248 return FALSE;
00249 }
00250 valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00251 map_doc = xmlParseFile(map_path);
00252 if (map_doc == NULL)
00253 {
00254 return FALSE;
00255 }
00256 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc))
00257 {
00258 return FALSE;
00259 }
00260 map_root = xmlDocGetRootElement(map_doc);
00261 valid.map_calculated_count = 0;
00262 valid.valid_object_count = 0;
00263 valid.error_state = ERR_BACKEND_NO_ERR;
00264 map_ns = map_root->ns;
00265 iter.ns = map_ns;
00266 qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
00267 iter.ns = object_root->ns;
00268 qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
00269 if (valid.error_state != ERR_BACKEND_NO_ERR)
00270 {
00271 g_hash_table_destroy(valid.validation_table);
00272 return FALSE;
00273 }
00274 valid_count = 0 - g_hash_table_size(valid.validation_table);
00275 valid_count += valid.map_calculated_count;
00276 valid_count += valid.valid_object_count;
00277 g_hash_table_destroy(valid.validation_table);
00278 if (valid_count == 0)
00279 {
00280 return TRUE;
00281 }
00282 return FALSE;
00283 }
00284
00285 gboolean is_qsf_map_be(qsf_param *params)
00286 {
00287 xmlDocPtr doc;
00288 struct qsf_node_iterate iter;
00289 qsf_validator valid;
00290 xmlNodePtr map_root;
00291 xmlNsPtr map_ns;
00292 gchar *path;
00293
00294 g_return_val_if_fail((params != NULL), FALSE);
00295 qof_backend_get_error(params->be);
00296 path = g_strdup(params->filepath);
00297 if (path == NULL)
00298 {
00299 qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
00300 return FALSE;
00301 }
00302 doc = xmlParseFile(path);
00303 if (doc == NULL)
00304 {
00305 qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
00306 return FALSE;
00307 }
00308 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00309 {
00310 qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
00311 return FALSE;
00312 }
00313 map_root = xmlDocGetRootElement(doc);
00314 map_ns = map_root->ns;
00315 iter.ns = map_ns;
00316 valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00317 valid.error_state = ERR_BACKEND_NO_ERR;
00318 qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
00319 if (valid.error_state != ERR_BACKEND_NO_ERR)
00320 {
00321 qof_backend_set_error(params->be, valid.error_state);
00322 g_hash_table_destroy(valid.validation_table);
00323 return FALSE;
00324 }
00325 qof_backend_get_error(params->be);
00326 g_hash_table_destroy(valid.validation_table);
00327 return TRUE;
00328 }
00329
00330 gboolean is_qsf_map(const gchar *path)
00331 {
00332 xmlDocPtr doc;
00333 struct qsf_node_iterate iter;
00334 qsf_validator valid;
00335 xmlNodePtr map_root;
00336 xmlNsPtr map_ns;
00337
00338 g_return_val_if_fail((path != NULL), FALSE);
00339 if (path == NULL)
00340 {
00341 return FALSE;
00342 }
00343 doc = xmlParseFile(path);
00344 if (doc == NULL)
00345 {
00346 return FALSE;
00347 }
00348 if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
00349 {
00350 xmlFreeDoc(doc);
00351 return FALSE;
00352 }
00353 map_root = xmlDocGetRootElement(doc);
00354 map_ns = map_root->ns;
00355 iter.ns = map_ns;
00356 valid.error_state = ERR_BACKEND_NO_ERR;
00357 valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00358 qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
00359 if (valid.error_state != ERR_BACKEND_NO_ERR)
00360 {
00361 g_hash_table_destroy(valid.validation_table);
00362 return FALSE;
00363 }
00364 g_hash_table_destroy(valid.validation_table);
00365 return TRUE;
00366 }
00367
00368
00369 static void
00370 qsf_map_default_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params )
00371 {
00372 xmlChar *qsf_enum;
00373 gchar* iterate;
00374
00375 g_return_if_fail(params->qsf_define_hash != NULL);
00376 iterate = NULL;
00377 if (qsf_is_element(child, ns, MAP_DEFINE_TAG))
00378 {
00379 iterate = (gchar*)xmlGetProp(child, BAD_CAST MAP_ITERATE_ATTR);
00380 if (qof_util_bool_to_int(iterate) == 1)
00381 {
00382 params->qof_foreach = (QofIdType)xmlGetProp(child, BAD_CAST MAP_E_TYPE);
00383 }
00384 if (NULL == g_hash_table_lookup(params->qsf_define_hash,
00385 xmlGetProp(child, BAD_CAST MAP_E_TYPE)))
00386 {
00387 g_hash_table_insert(params->qsf_define_hash,
00388 xmlGetProp(child, BAD_CAST MAP_E_TYPE), params->child_node);
00389 }
00390 else
00391 {
00392 qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
00393 PERR (" ERR_QSF_BAD_MAP set");
00394 return;
00395 }
00396 }
00397 if (qsf_is_element(child, ns, MAP_DEFAULT_TAG))
00398 {
00399 if (qsf_strings_equal(xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR), MAP_ENUM_TYPE))
00400 {
00401 qsf_enum = xmlNodeGetContent(child);
00403 PERR (" enum todo incomplete");
00407 if (NULL == g_hash_table_lookup(params->qsf_default_hash,
00408 xmlNodeGetContent(child)))
00409 {
00410 g_hash_table_insert(params->qsf_default_hash,
00411 xmlNodeGetContent(child), child);
00412 }
00413 else
00414 {
00415 qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
00416 PERR (" ERR_QSF_BAD_MAP set");
00417 return;
00418 }
00419 }
00421 else
00422 {
00423 if (NULL == g_hash_table_lookup(params->qsf_default_hash,
00424 xmlGetProp(child, BAD_CAST MAP_NAME_ATTR)))
00425 {
00426 g_hash_table_insert(params->qsf_default_hash,
00427 xmlGetProp(child, BAD_CAST MAP_NAME_ATTR), child);
00428 }
00429 else
00430
00431
00432 {
00433 qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
00434 PERR (" ERR_QSF_BAD_MAP set");
00435 return;
00436 }
00437 }
00438 }
00439 }
00440
00441 static void
00442 qsf_map_top_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
00443 {
00444 xmlChar *qof_version;
00445 GString *buff;
00446 struct qsf_node_iterate iter;
00447
00448 if (!params->qsf_define_hash) return;
00449 if (!params->qsf_default_hash) return;
00450 ENTER (" child=%s", child->name);
00451 if (qsf_is_element(child, ns, MAP_DEFINITION_TAG))
00452 {
00453 qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
00454 buff = g_string_new(" ");
00455 g_string_printf(buff, "%i", QSF_QOF_VERSION);
00456 if (xmlStrcmp(qof_version, BAD_CAST buff->str) != 0)
00457 {
00458 qof_backend_set_error(params->be, ERR_QSF_BAD_QOF_VERSION);
00459 LEAVE (" ERR_QSF_BAD_QOF_VERSION set");
00460 return;
00461 }
00462 iter.ns = ns;
00463 qsf_node_foreach(child, qsf_map_default_handler, &iter, params);
00464 }
00465 LEAVE (" ");
00466 }
00467
00468 static char*
00469 qsf_else_set_value(xmlNodePtr parent, GHashTable *default_hash,
00470 gchar *content, xmlNsPtr map_ns)
00471 {
00472 xmlNodePtr cur_node;
00473
00474 content = NULL;
00475 for (cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
00476 {
00477 if (qsf_is_element(cur_node, map_ns, QSF_CONDITIONAL_SET))
00478 {
00479 content = (gchar*)xmlNodeGetContent(cur_node);
00480 return content;
00481 }
00482 }
00483 return NULL;
00484 }
00485
00486
00487
00488
00489
00490 static gchar*
00491 qsf_set_handler(xmlNodePtr parent, GHashTable *default_hash,
00492 gchar *content, qsf_param *params)
00493 {
00494 xmlNodePtr cur_node, lookup_node;
00495
00496 ENTER (" lookup problem");
00497 content = NULL;
00498 for (cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
00499 {
00500 if (qsf_is_element(cur_node, params->map_ns, QSF_CONDITIONAL_SET))
00501 {
00502 content = (gchar*)xmlGetProp(cur_node, BAD_CAST QSF_OPTION);
00503 if (qsf_strings_equal(xmlGetProp(cur_node, BAD_CAST QSF_OPTION), "qsf_lookup_string"))
00504 {
00505 lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
00506 xmlNodeGetContent(cur_node));
00507 content = (gchar*)xmlGetProp(lookup_node, BAD_CAST MAP_VALUE_ATTR);
00509
00510 g_message("Lookup %s in the receiving application\n", content );
00511 LEAVE (" todo");
00512 return content;
00513 }
00514 if (content)
00515 {
00516 lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
00517 xmlNodeGetContent(cur_node));
00518 content = (gchar*)xmlGetProp(lookup_node, BAD_CAST "value");
00519 return content;
00520 }
00521 content = (gchar*)xmlGetProp(parent, BAD_CAST "boolean");
00522 if (!content)
00523 {
00525 lookup_node = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash,
00526 xmlGetProp(parent->parent, BAD_CAST MAP_TYPE_ATTR));
00527 if (lookup_node)
00528 {
00529 return (gchar*)xmlNodeGetContent(lookup_node);
00530 }
00531 LEAVE (" check arguments");
00532 return (gchar*)xmlNodeGetContent(cur_node);
00533 }
00534 }
00535 }
00536 LEAVE (" null");
00537 return NULL;
00538 }
00539
00540 static void
00541 qsf_calculate_else(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
00542 {
00543 xmlNodePtr export_node;
00544 xmlChar *output_content, *object_data;
00545
00546 if (qsf_is_element(param_node, params->map_ns, QSF_CONDITIONAL_ELSE))
00547 {
00548 if (params->boolean_calculation_done == 0)
00549 {
00550 output_content = object_data = NULL;
00551 output_content = BAD_CAST qsf_set_handler(param_node,
00552 params->qsf_default_hash, (gchar*)output_content, params);
00553 if (output_content == NULL)
00554 {
00555 output_content = xmlGetProp(param_node, BAD_CAST MAP_TYPE_ATTR);
00556 object_data = BAD_CAST qsf_else_set_value(param_node, params->qsf_default_hash,
00557 (gchar*)output_content, params->map_ns);
00558 output_content = BAD_CAST xmlGetProp( (xmlNodePtr) g_hash_table_lookup(
00559 params->qsf_default_hash, object_data), BAD_CAST MAP_VALUE_ATTR);
00560 }
00561 if (object_data != NULL)
00562 {
00563 export_node = (xmlNodePtr) g_hash_table_lookup(
00564 params->qsf_parameter_hash,
00565 xmlGetProp(params->child_node, BAD_CAST QSF_OBJECT_TYPE));
00566 object_data = xmlNodeGetContent(export_node);
00567 }
00568 if (output_content != NULL)
00569 {
00570 object_data = output_content;
00571 }
00572 export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
00573 xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
00574 xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
00575 xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
00576 xmlNodeAddContent(export_node, object_data);
00577 params->boolean_calculation_done = 1;
00578 }
00579 }
00580 }
00581
00582 static void
00583 qsf_set_format_value(xmlChar *format, gchar *qsf_time_now_as_string,
00584 xmlNodePtr cur_node, qsf_param *params)
00585 {
00586 gint result;
00587 xmlChar *content;
00588 time_t *output;
00589 struct tm *tmp;
00590 time_t tester;
00591 xmlNodePtr kl;
00592 regex_t reg;
00593
00596 result = 0;
00597 if (format == NULL)
00598 {
00599 return;
00600 }
00601 ENTER (" ");
00602 content = xmlNodeGetContent(cur_node);
00603 output = (time_t*) g_hash_table_lookup(params->qsf_default_hash, content);
00604 if (!output)
00605 {
00608 tester = time(NULL);
00609 tmp = gmtime(&tester);
00612 kl = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash, content);
00613 if (!kl)
00614 {
00615 LEAVE (" no suitable date set.");
00616 return;
00617 }
00619 strptime((char*)xmlNodeGetContent(kl), QSF_XSD_TIME, tmp);
00620 if (!tmp)
00621 {
00622 LEAVE (" empty date field in QSF object.\n");
00623 return;
00624 }
00625 tester = mktime(tmp);
00626 output = &tester;
00627 }
00628 result = regcomp(®, "%[a-zA-Z]", REG_EXTENDED | REG_NOSUB);
00629 result = regexec(®, (gchar*)format, (size_t)0, NULL, 0);
00630 if (result == REG_NOMATCH)
00631 {
00632 format = BAD_CAST "%F";
00633 }
00634 regfree(®);
00637 qof_strftime(qsf_time_now_as_string, QSF_DATE_LENGTH, (char*)format, gmtime(output));
00638 LEAVE (" ok");
00639 }
00640
00641 static void
00642 qsf_boolean_set_value(xmlNodePtr parent, qsf_param *params,
00643 gchar *content, xmlNsPtr map_ns)
00644 {
00645 xmlNodePtr cur_node;
00646 xmlChar *boolean_name;
00647
00648 boolean_name = NULL;
00649 for (cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
00650 {
00651 if (qsf_is_element(cur_node, map_ns, QSF_CONDITIONAL_SET))
00652 {
00653 boolean_name = xmlGetProp(cur_node, BAD_CAST QSF_FORMATTING_OPTION);
00654 qsf_set_format_value(boolean_name, content, cur_node, params);
00655 }
00656 }
00657 }
00658
00659 static void
00660 qsf_calculate_conditional(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
00661 {
00662 xmlNodePtr export_node;
00663 xmlChar *output_content;
00664
00665 output_content = NULL;
00666 if (qsf_is_element(param_node, params->map_ns, QSF_CONDITIONAL))
00667 {
00668 if (params->boolean_calculation_done == 0)
00669 {
00670
00671 output_content = BAD_CAST qsf_set_handler(param_node, params->qsf_default_hash,
00672 (gchar*)output_content, params);
00673
00674 if (output_content == NULL)
00675 {
00676 if (NULL != xmlGetProp(param_node, BAD_CAST QSF_BOOLEAN_DEFAULT))
00677 {
00678 output_content = xmlGetProp( (xmlNodePtr) g_hash_table_lookup(
00679 params->qsf_default_hash, xmlGetProp(param_node,
00680 BAD_CAST QSF_BOOLEAN_DEFAULT) ), BAD_CAST MAP_VALUE_ATTR);
00681 }
00682
00683 if ( 0 == qsf_compare_tag_strings(output_content, QSF_XML_BOOLEAN_TEST))
00684 {
00685 qsf_boolean_set_value(param_node, params, (gchar*)output_content, params->map_ns);
00686 export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
00687 xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
00688 xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
00689 xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
00690 xmlNodeAddContent(export_node, output_content);
00691 params->boolean_calculation_done = 1;
00692 }
00693 }
00694 }
00695 }
00696 }
00697
00698 static void
00699 qsf_add_object_tag(qsf_param *params, gint count)
00700 {
00701 xmlNodePtr extra_node;
00702 GString *str;
00703 xmlChar *property;
00704
00705 str = g_string_new (" ");
00706 g_string_printf(str, "%i", count);
00707 extra_node = NULL;
00708 extra_node = xmlAddChild(params->output_node,
00709 xmlNewNode(params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
00710 xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_TYPE,
00711 xmlGetProp(params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
00712 property = xmlCharStrdup(str->str);
00713 xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
00714 params->lister = extra_node;
00715 }
00716
00717 static gint
00718 identify_source_func(gconstpointer qsf_object, gconstpointer map)
00719 {
00720 return safe_strcmp(((qsf_objects*)qsf_object)->object_type, (QofIdType)map);
00721 }
00722
00723 static void
00724 qsf_map_calculate_output(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
00725 {
00726 xmlNodePtr export_node;
00727 xmlChar *output_content;
00728 xmlNodePtr node;
00729 GList *source;
00730
00731 DEBUG (" %s", xmlNodeGetContent(param_node));
00732 output_content = xmlNodeGetContent(param_node);
00733
00734 source = g_list_find_custom(params->qsf_object_list,
00735 BAD_CAST xmlGetProp(param_node, BAD_CAST MAP_OBJECT_ATTR),
00736 identify_source_func);
00737 if (!source) return;
00738 params->object_set = source->data;
00739 node = g_hash_table_lookup(params->object_set->parameters, output_content);
00740 export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
00741 xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
00742 xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
00743 xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
00744 if (node)
00745 {
00746 xmlNodeAddContent(export_node, xmlNodeGetContent(node));
00747 }
00748 }
00749
00750 static void
00751 qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
00752 {
00753 xmlNodePtr param_node;
00754 xmlNsPtr map_ns, qsf_ns;
00755 gint result;
00756
00757 map_ns = ns;
00758 qsf_ns = params->qsf_ns;
00759 param_node = NULL;
00760 result = 0;
00761 if (child == NULL)
00762 {
00763 return;
00764 }
00765 if (ns == NULL)
00766 {
00767 return;
00768 }
00769 params->boolean_calculation_done = 0;
00770
00771 if (qsf_is_element(child, map_ns, MAP_CALCULATE_TAG))
00772 {
00773 params->boolean_calculation_done = 0;
00774
00775 for (param_node = child->children; param_node != NULL;
00776 param_node = param_node->next)
00777 {
00778 if (qsf_is_element(param_node, map_ns, QSF_CONDITIONAL_SET))
00779 {
00780
00781 if (0 == qsf_compare_tag_strings(
00782 xmlNodeGetContent(param_node), "qsf_enquiry_date"))
00783 {
00784 qsf_string_default_handler("qsf_enquiry_date",
00785 params->qsf_default_hash, params->lister, child, qsf_ns);
00786 }
00787 if (0 == qsf_compare_tag_strings(
00788 xmlNodeGetContent(param_node), "qsf_time_now"))
00789 {
00790 qsf_date_default_handler("qsf_time_now",
00791 params->qsf_default_hash, params->lister, child, qsf_ns);
00792 }
00793 if (0 == qsf_compare_tag_strings(
00794 xmlNodeGetContent(param_node), "qsf_time_string"))
00795 {
00796 qsf_string_default_handler("qsf_time_string",
00797 params->qsf_default_hash, params->lister, child, qsf_ns);
00798 }
00799 qsf_map_calculate_output(param_node, child, params);
00800 }
00801 qsf_calculate_conditional( param_node, child, params);
00802 qsf_calculate_else(param_node, child, params);
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 }
00819 }
00820
00821 static void
00822 iterator_cb(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
00823 {
00824 gchar *object_name;
00825
00826
00827 if (qsf_is_element(child, ns, QSF_OBJECT_TAG))
00828 {
00829 object_name = (gchar *)xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE);
00830 if (0 == safe_strcmp(object_name, params->qof_foreach))
00831 {
00832 params->foreach_limit++;
00833 }
00834 }
00835 }
00836
00837 xmlDocPtr
00838 qsf_object_convert(xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params)
00839 {
00840
00841 struct qsf_node_iterate iter;
00842 xmlDocPtr output_doc;
00843 xmlNode *cur_node;
00844 xmlNode *map_root, *output_root;
00845
00846 g_return_val_if_fail((mapDoc && qsf_root && params), NULL);
00847 ENTER (" root=%s", qsf_root->name);
00848
00849 iter.ns = params->qsf_ns;
00850 output_doc = xmlNewDoc(BAD_CAST QSF_XML_VERSION);
00851 output_root = xmlNewNode(NULL, BAD_CAST QSF_ROOT_TAG);
00852 xmlDocSetRootElement(output_doc, output_root);
00853 xmlSetNs(output_root, params->qsf_ns);
00854 params->output_node = xmlNewChild(output_root, params->qsf_ns,
00855 BAD_CAST QSF_BOOK_TAG, NULL);
00856 xmlNewProp(params->output_node, BAD_CAST QSF_BOOK_COUNT, BAD_CAST "1");
00857
00858 qsf_book_node_handler(qsf_root->children->next, params->qsf_ns, params);
00859
00860 map_root = xmlDocGetRootElement(mapDoc);
00861 params->foreach_limit = 0;
00862 iter.ns = params->map_ns;
00863 qsf_node_foreach(map_root, qsf_map_top_node_handler, &iter, params);
00864
00865 iter.ns = params->qsf_ns;
00866 qsf_node_foreach(qsf_root->children->next, iterator_cb, &iter, params);
00867
00868 params->count = 0;
00869 for (cur_node = map_root->children; cur_node != NULL; cur_node = cur_node->next)
00870 {
00871 params->convert_node = cur_node;
00872 if (qsf_is_element(cur_node, params->map_ns, MAP_OBJECT_TAG))
00873 {
00874 gint i;
00875
00876 params->lister = NULL;
00877
00878 if (!qof_class_is_registered(
00879 (QofIdTypeConst)xmlGetProp(cur_node,
00880 BAD_CAST MAP_TYPE_ATTR)))
00881 {
00882 continue;
00883 }
00884 qsf_add_object_tag(params, params->count);
00885 params->count++;
00886 iter.ns = params->map_ns;
00887 for (i = 0; i < params->foreach_limit; i++)
00888 {
00889 qsf_node_foreach(cur_node, qsf_map_object_handler, &iter, params);
00890 params->qsf_object_list = g_list_next(params->qsf_object_list);
00891 qsf_add_object_tag(params, params->count);
00892 params->count++;
00893 }
00894 }
00895 }
00896 params->file_type = OUR_QSF_OBJ;
00897
00898
00899 LEAVE (" ");
00900 return output_doc;
00901 }