mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
impossible to override configuration settings. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13549 57a11ea4-9604-0410-9ed3-97b8803252fd
727 lines
22 KiB
C
727 lines
22 KiB
C
/***************************************************************************
|
|
* qsf-xml-map.c
|
|
*
|
|
* Sat Jan 1 07:31:55 2005
|
|
* Copyright 2005-2006 Neil Williams
|
|
* linux@codehelp.co.uk
|
|
****************************************************************************/
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include "config.h"
|
|
|
|
#include <libxml/xmlversion.h>
|
|
#include <libxml/xmlmemory.h>
|
|
#include <libxml/tree.h>
|
|
#include <libxml/parser.h>
|
|
#include <libxml/xmlschemas.h>
|
|
#include "qof.h"
|
|
#include "qof-backend-qsf.h"
|
|
#include "qsf-xml.h"
|
|
#include "qsf-dir.h"
|
|
|
|
static QofLogModule log_module = QOF_MOD_QSF;
|
|
|
|
static void
|
|
qsf_date_default_handler(const char *default_name, GHashTable *qsf_default_hash,
|
|
xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
|
|
{
|
|
xmlNodePtr output_parent;
|
|
time_t *qsf_time;
|
|
char date_as_string[QSF_DATE_LENGTH];
|
|
|
|
output_parent = xmlAddChild(parent_tag, xmlNewNode(ns,
|
|
xmlGetProp(import_node, BAD_CAST QSF_OBJECT_TYPE)));
|
|
xmlNewProp(output_parent, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(import_node, BAD_CAST MAP_VALUE_ATTR));
|
|
qsf_time = (time_t*)g_hash_table_lookup(qsf_default_hash, default_name);
|
|
strftime(date_as_string, QSF_DATE_LENGTH, QSF_XSD_TIME, gmtime(qsf_time));
|
|
xmlNodeAddContent(output_parent, BAD_CAST date_as_string);
|
|
}
|
|
|
|
static void
|
|
qsf_string_default_handler(const char *default_name, GHashTable *qsf_default_hash,
|
|
xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
|
|
{
|
|
xmlNodePtr node;
|
|
xmlChar *output;
|
|
|
|
node = xmlAddChild(parent_tag,
|
|
xmlNewNode(ns, xmlGetProp(import_node, BAD_CAST QSF_OBJECT_TYPE)));
|
|
xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(import_node, BAD_CAST MAP_VALUE_ATTR));
|
|
output = (xmlChar *)g_hash_table_lookup(qsf_default_hash, default_name);
|
|
xmlNodeAddContent(node, output);
|
|
}
|
|
|
|
static void
|
|
qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
|
|
{
|
|
xmlChar *qof_version, *match;
|
|
GString *buff;
|
|
xmlNodePtr child_node;
|
|
|
|
if (qsf_is_element(child, ns, MAP_DEFINITION_TAG)) {
|
|
qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
|
|
buff = g_string_new(" ");
|
|
g_string_printf(buff, "%i", QSF_QOF_VERSION);
|
|
if(xmlStrcmp(qof_version, BAD_CAST buff->str) != 0)
|
|
{
|
|
valid->error_state = ERR_QSF_BAD_QOF_VERSION;
|
|
return;
|
|
}
|
|
for(child_node = child->children; child_node != NULL;
|
|
child_node = child_node->next)
|
|
{
|
|
if (qsf_is_element(child_node, ns, MAP_DEFINE_TAG)) {
|
|
g_hash_table_insert(valid->validation_table,
|
|
xmlGetProp(child_node, BAD_CAST MAP_E_TYPE),
|
|
xmlNodeGetContent(child_node));
|
|
}
|
|
}
|
|
}
|
|
if(qsf_is_element(child, ns, MAP_OBJECT_TAG)) {
|
|
match = NULL;
|
|
match = BAD_CAST g_hash_table_lookup( valid->validation_table,
|
|
xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR));
|
|
if(match) {
|
|
valid->map_calculated_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
gboolean is_qsf_object_with_map_be(char *map_file, qsf_param *params)
|
|
{
|
|
xmlDocPtr doc, map_doc;
|
|
int valid_count;
|
|
struct qsf_node_iterate iter;
|
|
xmlNodePtr map_root, object_root;
|
|
xmlNsPtr map_ns;
|
|
qsf_validator valid;
|
|
char *path;
|
|
gchar *map_path;
|
|
|
|
g_return_val_if_fail((params != NULL),FALSE);
|
|
path = g_strdup(params->filepath);
|
|
map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
|
|
if(path == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
|
|
return FALSE;
|
|
}
|
|
doc = xmlParseFile(path);
|
|
if(doc == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
|
|
return FALSE;
|
|
}
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) {
|
|
qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
|
|
return FALSE;
|
|
}
|
|
object_root = xmlDocGetRootElement(doc);
|
|
if(map_path == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
|
|
return FALSE;
|
|
}
|
|
valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
|
|
map_doc = xmlParseFile(map_path);
|
|
if(map_doc == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
|
|
return FALSE;
|
|
}
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc)) {
|
|
qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
|
|
return FALSE;
|
|
}
|
|
map_root = xmlDocGetRootElement(map_doc);
|
|
valid.map_calculated_count = 0;
|
|
valid.valid_object_count = 0;
|
|
valid.qof_registered_count = 0;
|
|
valid.error_state = ERR_BACKEND_NO_ERR;
|
|
map_ns = map_root->ns;
|
|
iter.ns = object_root->ns;
|
|
qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
|
|
iter.ns = map_ns;
|
|
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
|
|
if (valid.error_state != ERR_BACKEND_NO_ERR) {
|
|
qof_backend_set_error(params->be, valid.error_state);
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return FALSE;
|
|
}
|
|
valid_count = 0 - g_hash_table_size(valid.validation_table);
|
|
valid_count += valid.map_calculated_count;
|
|
valid_count += valid.valid_object_count;
|
|
g_hash_table_destroy(valid.validation_table);
|
|
if(valid_count == 0) {
|
|
qof_backend_get_error(params->be);
|
|
return TRUE;
|
|
}
|
|
qof_backend_set_error(params->be, ERR_QSF_WRONG_MAP);
|
|
/* the object is OK, only the map is wrong. */
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean is_qsf_object_with_map(const char *path, char *map_file)
|
|
{
|
|
xmlDocPtr doc, map_doc;
|
|
int valid_count;
|
|
struct qsf_node_iterate iter;
|
|
xmlNodePtr map_root, object_root;
|
|
xmlNsPtr map_ns;
|
|
qsf_validator valid;
|
|
gchar *map_path;
|
|
|
|
map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
|
|
if(path == NULL) {
|
|
return FALSE;
|
|
}
|
|
doc = xmlParseFile(path);
|
|
if(doc == NULL) {
|
|
return FALSE;
|
|
}
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) {
|
|
return FALSE;
|
|
}
|
|
object_root = xmlDocGetRootElement(doc);
|
|
if(map_path == NULL) {
|
|
return FALSE;
|
|
}
|
|
valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
|
|
map_doc = xmlParseFile(map_path);
|
|
if(map_doc == NULL) {
|
|
return FALSE;
|
|
}
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc)) {
|
|
return FALSE;
|
|
}
|
|
map_root = xmlDocGetRootElement(map_doc);
|
|
valid.map_calculated_count = 0;
|
|
valid.valid_object_count = 0;
|
|
valid.error_state = ERR_BACKEND_NO_ERR;
|
|
map_ns = map_root->ns;
|
|
iter.ns = map_ns;
|
|
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
|
|
iter.ns = object_root->ns;
|
|
qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
|
|
if (valid.error_state != ERR_BACKEND_NO_ERR) {
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return FALSE;
|
|
}
|
|
valid_count = 0 - g_hash_table_size(valid.validation_table);
|
|
valid_count += valid.map_calculated_count;
|
|
valid_count += valid.valid_object_count;
|
|
g_hash_table_destroy(valid.validation_table);
|
|
if(valid_count == 0) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
gboolean is_qsf_map_be(qsf_param *params)
|
|
{
|
|
xmlDocPtr doc;
|
|
struct qsf_node_iterate iter;
|
|
qsf_validator valid;
|
|
xmlNodePtr map_root;
|
|
xmlNsPtr map_ns;
|
|
char *path;
|
|
|
|
g_return_val_if_fail((params != NULL),FALSE);
|
|
qof_backend_get_error(params->be);
|
|
path = g_strdup(params->filepath);
|
|
if(path == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
|
|
return FALSE;
|
|
}
|
|
doc = xmlParseFile(path);
|
|
if(doc == NULL) {
|
|
qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
|
|
return FALSE;
|
|
}
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc)) {
|
|
qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
|
|
return FALSE;
|
|
}
|
|
map_root = xmlDocGetRootElement(doc);
|
|
map_ns = map_root->ns;
|
|
iter.ns = map_ns;
|
|
valid.error_state = ERR_BACKEND_NO_ERR;
|
|
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
|
|
if (valid.error_state != ERR_BACKEND_NO_ERR) {
|
|
qof_backend_set_error(params->be, valid.error_state);
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return FALSE;
|
|
}
|
|
qof_backend_get_error(params->be);
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean is_qsf_map(const char *path)
|
|
{
|
|
xmlDocPtr doc;
|
|
struct qsf_node_iterate iter;
|
|
qsf_validator valid;
|
|
xmlNodePtr map_root;
|
|
xmlNsPtr map_ns;
|
|
|
|
g_return_val_if_fail((path != NULL),FALSE);
|
|
if(path == NULL) { return FALSE; }
|
|
doc = xmlParseFile(path);
|
|
if(doc == NULL) { return FALSE; }
|
|
if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc)) {
|
|
return FALSE;
|
|
}
|
|
map_root = xmlDocGetRootElement(doc);
|
|
map_ns = map_root->ns;
|
|
iter.ns = map_ns;
|
|
valid.error_state = ERR_BACKEND_NO_ERR;
|
|
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
|
|
if (valid.error_state != ERR_BACKEND_NO_ERR) {
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return FALSE;
|
|
}
|
|
g_hash_table_destroy(valid.validation_table);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static void
|
|
qsf_map_default_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params )
|
|
{
|
|
xmlChar *qsf_enum;
|
|
|
|
g_return_if_fail(params->qsf_define_hash != NULL);
|
|
if (qsf_is_element(child, ns, MAP_DEFINE_TAG)) {
|
|
if(NULL == g_hash_table_lookup(params->qsf_define_hash,
|
|
xmlGetProp(child, BAD_CAST MAP_E_TYPE)))
|
|
{
|
|
g_hash_table_insert(params->qsf_define_hash,
|
|
xmlGetProp(child, BAD_CAST MAP_E_TYPE), params->child_node);
|
|
}
|
|
else {
|
|
qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
|
|
PERR (" ERR_QSF_BAD_MAP set");
|
|
return;
|
|
}
|
|
}
|
|
if(qsf_is_element(child, ns, MAP_DEFAULT_TAG)) {
|
|
if(qsf_strings_equal(xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR), MAP_ENUM_TYPE))
|
|
{
|
|
qsf_enum = xmlNodeGetContent(child);
|
|
/** Use content to discriminate enums in QOF */
|
|
PERR (" enum todo incomplete");
|
|
/** \todo FIXME: the default enum value is not used
|
|
implemented properly or fully handled.
|
|
*/
|
|
if(NULL == g_hash_table_lookup(params->qsf_default_hash,
|
|
xmlNodeGetContent(child)))
|
|
{
|
|
g_hash_table_insert(params->qsf_default_hash,
|
|
xmlNodeGetContent(child), child);
|
|
}
|
|
else
|
|
{
|
|
qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
|
|
PERR (" ERR_QSF_BAD_MAP set");
|
|
return;
|
|
}
|
|
}
|
|
/** Non-enum defaults */
|
|
else {
|
|
if(NULL == g_hash_table_lookup(params->qsf_default_hash,
|
|
xmlGetProp(child, BAD_CAST MAP_NAME_ATTR)))
|
|
{
|
|
g_hash_table_insert(params->qsf_default_hash,
|
|
xmlGetProp(child, BAD_CAST MAP_NAME_ATTR), child);
|
|
}
|
|
else
|
|
/* if(0 != xmlHashAddEntry(params->default_map,
|
|
xmlGetProp(child_node, MAP_NAME_ATTR), child_node))*/
|
|
{
|
|
qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
|
|
LEAVE (" ");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
qsf_map_top_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
|
|
{
|
|
xmlChar *qof_version;
|
|
GString *buff;
|
|
struct qsf_node_iterate iter;
|
|
|
|
if(!params->qsf_define_hash) return;
|
|
if(!params->qsf_default_hash) return;
|
|
if(qsf_is_element(child, ns, MAP_DEFINITION_TAG)) {
|
|
qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
|
|
buff = g_string_new(" ");
|
|
g_string_printf(buff, "%i", QSF_QOF_VERSION);
|
|
if(xmlStrcmp(qof_version, BAD_CAST buff->str) != 0) {
|
|
qof_backend_set_error(params->be, ERR_QSF_BAD_QOF_VERSION);
|
|
PERR (" ERR_QSF_BAD_QOF_VERSION set");
|
|
return;
|
|
}
|
|
iter.ns = ns;
|
|
qsf_node_foreach(child, qsf_map_default_handler, &iter, params);
|
|
}
|
|
}
|
|
|
|
static char*
|
|
qsf_else_set_value(xmlNodePtr parent, GHashTable *default_hash,
|
|
char *content, xmlNsPtr map_ns)
|
|
{
|
|
xmlNodePtr cur_node;
|
|
|
|
content = NULL;
|
|
for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
|
|
{
|
|
if(qsf_is_element(cur_node, map_ns, QSF_CONDITIONAL_SET)) {
|
|
content = (char*)xmlNodeGetContent(cur_node);
|
|
return content;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/* Handles the set tag in the map.
|
|
This function will be overhauled once inside QOF
|
|
QOF hook required for "Lookup in the receiving application"
|
|
*/
|
|
static char*
|
|
qsf_set_handler(xmlNodePtr parent, GHashTable *default_hash,
|
|
char *content, qsf_param *params)
|
|
{
|
|
xmlNodePtr cur_node, lookup_node;
|
|
|
|
ENTER (" lookup problem");
|
|
content = NULL;
|
|
for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
|
|
{
|
|
if(qsf_is_element(cur_node, params->map_ns, QSF_CONDITIONAL_SET))
|
|
{
|
|
content = (char*)xmlGetProp(cur_node, BAD_CAST QSF_OPTION);
|
|
if(qsf_strings_equal(xmlGetProp(cur_node, BAD_CAST QSF_OPTION), "qsf_lookup_string"))
|
|
{
|
|
lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
|
|
xmlNodeGetContent(cur_node));
|
|
content = (char*)xmlGetProp(lookup_node, BAD_CAST MAP_VALUE_ATTR);
|
|
/** \todo FIXME: do the lookup. type is defined by output object. */
|
|
/* Find by name, get GUID, return GUID as string. */
|
|
g_message("Lookup %s in the receiving application\n", content );
|
|
LEAVE (" todo");
|
|
return content;
|
|
}
|
|
if(content)
|
|
{
|
|
lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
|
|
xmlNodeGetContent(cur_node));
|
|
content = (char*)xmlGetProp(lookup_node, BAD_CAST "value");
|
|
return content;
|
|
}
|
|
content = (char*)xmlGetProp(parent, BAD_CAST "boolean");
|
|
if(!content) {
|
|
/** \todo Check qsf_parameter_hash arguments */
|
|
lookup_node = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash,
|
|
xmlGetProp(parent->parent, BAD_CAST MAP_TYPE_ATTR));
|
|
if(lookup_node) { return (char*)xmlNodeGetContent(lookup_node); }
|
|
LEAVE (" check arguments");
|
|
return (char*)xmlNodeGetContent(cur_node);
|
|
}
|
|
}
|
|
}
|
|
LEAVE (" null");
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
qsf_calculate_else(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
|
|
{
|
|
xmlNodePtr export_node;
|
|
xmlChar *output_content, *object_data;
|
|
|
|
if(qsf_is_element(param_node, params->map_ns, QSF_CONDITIONAL_ELSE)) {
|
|
if(params->boolean_calculation_done == 0) {
|
|
output_content = object_data = NULL;
|
|
output_content = BAD_CAST qsf_set_handler(param_node,
|
|
params->qsf_default_hash, (char*)output_content, params);
|
|
if(output_content == NULL) {
|
|
output_content = xmlGetProp(param_node, BAD_CAST MAP_TYPE_ATTR);
|
|
object_data = BAD_CAST qsf_else_set_value(param_node, params->qsf_default_hash,
|
|
(char*)output_content, params->map_ns);
|
|
output_content = BAD_CAST xmlGetProp( (xmlNodePtr) g_hash_table_lookup(
|
|
params->qsf_default_hash, object_data), BAD_CAST MAP_VALUE_ATTR);
|
|
}
|
|
if(object_data != NULL) {
|
|
export_node =(xmlNodePtr) g_hash_table_lookup(
|
|
params->qsf_parameter_hash,
|
|
xmlGetProp(params->child_node, BAD_CAST QSF_OBJECT_TYPE));
|
|
object_data = xmlNodeGetContent(export_node);
|
|
}
|
|
if(output_content != NULL) { object_data = output_content; }
|
|
export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
|
|
xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
|
|
xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
|
|
xmlNodeAddContent(export_node, object_data);
|
|
params->boolean_calculation_done = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
qsf_set_format_value(xmlChar *format, char *qsf_time_now_as_string,
|
|
xmlNodePtr cur_node, qsf_param *params)
|
|
{
|
|
int result;
|
|
xmlChar *content;
|
|
time_t *output;
|
|
struct tm *tmp;
|
|
time_t tester;
|
|
xmlNodePtr kl;
|
|
regex_t reg;
|
|
|
|
/** Comments retained - this behaves a little strangely */
|
|
|
|
result = 0;
|
|
if(format == NULL) { return; }
|
|
ENTER (" ");
|
|
content = xmlNodeGetContent(cur_node);
|
|
output = (time_t*) g_hash_table_lookup(params->qsf_default_hash, content);
|
|
if(!output) {
|
|
/** No default time set, use the object time */
|
|
/** fill the time structs with temp data */
|
|
tester = time(NULL);
|
|
tmp = gmtime(&tester);
|
|
/** Lookup the object value to read */
|
|
/** \todo qsf_parameter_hash check correct arguments */
|
|
kl = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash, content);
|
|
if(!kl) {
|
|
LEAVE (" no suitable date set.");
|
|
return;
|
|
}
|
|
/** Read the object value as a dateTime */
|
|
strptime((char*)xmlNodeGetContent(kl), QSF_XSD_TIME, tmp);
|
|
if(!tmp) {
|
|
LEAVE (" empty date field in QSF object.\n");
|
|
return;
|
|
}
|
|
tester = mktime(tmp);
|
|
output = &tester;
|
|
}
|
|
result = regcomp(®, "%[a-zA-Z]", REG_EXTENDED|REG_NOSUB);
|
|
result = regexec(®, (char*)format,(size_t)0,NULL,0);
|
|
if(result == REG_NOMATCH) { format = BAD_CAST "%F"; }
|
|
regfree(®);
|
|
/** QSF_DATE_LENGTH preset for all internal and QSF_XSD_TIME string formats.
|
|
*/
|
|
strftime(qsf_time_now_as_string, QSF_DATE_LENGTH, (char*)format, gmtime(output));
|
|
LEAVE (" ok");
|
|
}
|
|
|
|
static void
|
|
qsf_boolean_set_value(xmlNodePtr parent, qsf_param *params,
|
|
char *content, xmlNsPtr map_ns)
|
|
{
|
|
xmlNodePtr cur_node;
|
|
xmlChar *boolean_name;
|
|
|
|
boolean_name = NULL;
|
|
for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next) {
|
|
if(qsf_is_element(cur_node, map_ns, QSF_CONDITIONAL_SET)) {
|
|
boolean_name = xmlGetProp(cur_node, BAD_CAST QSF_FORMATTING_OPTION);
|
|
qsf_set_format_value(boolean_name, content, cur_node, params);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
qsf_calculate_conditional(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
|
|
{
|
|
xmlNodePtr export_node;
|
|
xmlChar *output_content;
|
|
|
|
output_content = NULL;
|
|
if(qsf_is_element(param_node, params->map_ns, QSF_CONDITIONAL)) {
|
|
if(params->boolean_calculation_done == 0) {
|
|
/* set handler */
|
|
output_content = BAD_CAST qsf_set_handler(param_node, params->qsf_default_hash,
|
|
(char*)output_content, params);
|
|
/* If the 'if' contains a boolean that has a default value */
|
|
if(output_content == NULL) {
|
|
if(NULL != xmlGetProp(param_node, BAD_CAST QSF_BOOLEAN_DEFAULT)) {
|
|
output_content = xmlGetProp( (xmlNodePtr) g_hash_table_lookup(
|
|
params->qsf_default_hash, xmlGetProp(param_node,
|
|
BAD_CAST QSF_BOOLEAN_DEFAULT) ), BAD_CAST MAP_VALUE_ATTR);
|
|
}
|
|
/* Is the default set to true? */
|
|
if( 0 == qsf_compare_tag_strings(output_content, QSF_XML_BOOLEAN_TEST))
|
|
{
|
|
qsf_boolean_set_value(param_node, params, (char*)output_content, params->map_ns);
|
|
export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
|
|
xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
|
|
xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
|
|
xmlNodeAddContent(export_node, output_content);
|
|
params->boolean_calculation_done = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static xmlNodePtr
|
|
qsf_add_object_tag(qsf_param *params, int count)
|
|
{
|
|
xmlNodePtr extra_node;
|
|
GString *str;
|
|
xmlChar *property;
|
|
|
|
str = g_string_new (" ");
|
|
g_string_printf(str, "%i", count);
|
|
extra_node = NULL;
|
|
extra_node = xmlAddChild(params->output_node,
|
|
xmlNewNode(params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
|
|
xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
|
|
property = xmlCharStrdup(str->str);
|
|
xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
|
|
return extra_node;
|
|
}
|
|
|
|
static void
|
|
qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
|
|
{
|
|
xmlNodePtr param_node, export_node;
|
|
xmlNsPtr map_ns, qsf_ns;
|
|
xmlChar *output_content;
|
|
int result, count;
|
|
|
|
map_ns = ns;
|
|
qsf_ns = params->qsf_ns;
|
|
param_node = NULL;
|
|
result = 0;
|
|
count = params->count;
|
|
if(child == NULL) { return; }
|
|
if(ns == NULL) { return; }
|
|
params->boolean_calculation_done = 0;
|
|
|
|
if(qsf_is_element(child, map_ns, MAP_CALCULATE_TAG)) {
|
|
params->boolean_calculation_done = 0;
|
|
for(param_node = child->children; param_node != NULL;
|
|
param_node = param_node->next)
|
|
{
|
|
output_content = NULL;
|
|
export_node = NULL;
|
|
if(!params->lister) { params->lister = qsf_add_object_tag(params, count); }
|
|
if(qsf_is_element(param_node, map_ns, "set"))
|
|
{
|
|
/* Map the pre-defined defaults */
|
|
if(0 == qsf_compare_tag_strings(
|
|
xmlNodeGetContent(param_node), "qsf_enquiry_date"))
|
|
{
|
|
qsf_string_default_handler("qsf_enquiry_date",
|
|
params->qsf_default_hash, params->lister, child, qsf_ns);
|
|
}
|
|
if(0 == qsf_compare_tag_strings(
|
|
xmlNodeGetContent(param_node), "qsf_time_now"))
|
|
{
|
|
qsf_date_default_handler("qsf_time_now",
|
|
params->qsf_default_hash, params->lister, child, qsf_ns);
|
|
}
|
|
if(0 == qsf_compare_tag_strings(
|
|
xmlNodeGetContent(param_node), "qsf_time_string"))
|
|
{
|
|
qsf_string_default_handler("qsf_time_string",
|
|
params->qsf_default_hash, params->lister, child, qsf_ns);
|
|
}
|
|
output_content = xmlNodeGetContent(param_node);
|
|
if(output_content != NULL) {
|
|
output_content = xmlNodeGetContent((xmlNodePtr) g_hash_table_lookup(
|
|
params->qsf_parameter_hash, xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR)));
|
|
if(output_content != NULL) {
|
|
export_node = xmlAddChild(params->lister, xmlNewNode(qsf_ns,
|
|
xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
|
|
xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
|
|
xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
|
|
xmlNodeAddContent(export_node, output_content);
|
|
xmlFree(output_content);
|
|
}
|
|
}
|
|
}
|
|
|
|
qsf_calculate_conditional( param_node, child, params);
|
|
qsf_calculate_else(param_node, child, params);
|
|
}
|
|
|
|
/* calculate_map currently not in use */
|
|
/* ensure uniqueness of the key before re-instating */
|
|
/* result = xmlHashAddEntry2(calculate_map,
|
|
xmlGetProp(child_node, MAP_TYPE_ATTR),
|
|
xmlGetProp(child_node, MAP_VALUE_ATTR), child_node);
|
|
if(result != 0) {
|
|
printf("add entry to calculate hash failed. %s\t%s\t%s.\n",
|
|
xmlGetProp(child_node, MAP_TYPE_ATTR),
|
|
xmlGetProp(child_node, MAP_VALUE_ATTR), child_node->name);
|
|
return;
|
|
}
|
|
|
|
is_qsf_object_with_map(path, map_path);
|
|
*/
|
|
}
|
|
}
|
|
|
|
xmlDocPtr
|
|
qsf_object_convert(xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params)
|
|
{
|
|
struct qsf_node_iterate iter;
|
|
xmlDocPtr output_doc;
|
|
xmlNode *cur_node;
|
|
xmlNode *map_root, *output_root, *output_node;
|
|
|
|
ENTER (" ");
|
|
output_doc = xmlNewDoc(BAD_CAST QSF_XML_VERSION);
|
|
output_root = xmlDocCopyNode(qsf_root,output_doc,2);
|
|
xmlSetNs(output_root, params->qsf_ns);
|
|
output_node = NULL;
|
|
|
|
qsf_node_foreach(qsf_root, qsf_object_node_handler, &iter, params);
|
|
map_root = xmlDocGetRootElement(mapDoc);
|
|
|
|
iter.ns = params->map_ns;
|
|
qsf_node_foreach(map_root, qsf_map_top_node_handler, &iter, params);
|
|
|
|
for(cur_node = map_root->children; cur_node != NULL; cur_node = cur_node->next)
|
|
{
|
|
params->convert_node = cur_node;
|
|
params->count = 0;
|
|
if(qsf_is_element(cur_node, params->map_ns, MAP_OBJECT_TAG))
|
|
{
|
|
params->lister = NULL;
|
|
params->count++;
|
|
iter.ns = params->map_ns;
|
|
qsf_node_foreach(cur_node, qsf_map_object_handler, &iter, params);
|
|
}
|
|
}
|
|
params->file_type = OUR_QSF_OBJ;
|
|
LEAVE (" ");
|
|
return output_doc;
|
|
}
|