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