qsf-xml.h File Reference

Private QSF header - not for use by applications. More...

#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <time.h>
#include "qof.h"
#include <libintl.h>

Go to the source code of this file.

Data Structures

struct  qsf_object_set
 Holds a description of the QofObject. More...
struct  qsf_metadata
 QSF Parameters. More...
struct  qsf_validates
 Validation metadata. More...
struct  qsf_node_iterate
 One iterator, two typedefs. More...

Defines

#define _(String)   dgettext (GETTEXT_PACKAGE, String)
#define QSF_QOF_VERSION   QOF_OBJECT_VERSION
#define QSF_XSD_TIME   QOF_UTC_DATE_FORMAT
#define QSF_XML_BOOLEAN_TEST   "true"
#define QSF_OBJECT_SCHEMA   "qsf-object.xsd.xml"
#define QSF_MAP_SCHEMA   "qsf-map.xsd.xml"
QSF Object XML
#define QSF_ROOT_TAG   "qof-qsf"
#define QSF_DEFAULT_NS   "http://qof.sourceforge.net/"
#define QSF_DATE_LENGTH   MAX_DATE_LENGTH
#define QSF_BOOK_TAG   "book"
#define QSF_BOOK_GUID   "book-guid"
#define QSF_BOOK_COUNT   "count"
#define QSF_OBJECT_TAG   "object"
#define QSF_OBJECT_TYPE   "type"
#define QSF_OBJECT_COUNT   "count"
#define QSF_XML_VERSION   "1.0"
Representing KVP as XML
<kvp type="kvp" path="/from-sched-xaction" value="guid">c858b9a3235723b55bc1179f0e8c1322</kvp> A kvp type KVP parameter located at $path containing a GncGUID $value.

The relevance of type="kvp" won't be evident in GnuCash, they all use "kvp".

A non-GnuCash example helps: <kvp type="pilot_addr_kvp" path="/user/name" value="guid">c858b9a3235723b55bc1179f0e8c1322</kvp> A pilot_addr_kvp type KVP parameter located at /user/name containing a guid value.

#define QSF_OBJECT_KVP   "path"
#define QSF_OBJECT_VALUE   "value"
QSF Map XML
#define MAP_ROOT_TAG   "qsf-map"
#define MAP_DEFINITION_TAG   "definition"
#define MAP_DEFINE_TAG   "define"
#define MAP_ITERATE_ATTR   "foreach"
#define MAP_DEFAULT_TAG   "default"
#define MAP_OBJECT_TAG   "object"
#define MAP_CALCULATE_TAG   "calculate"
#define MAP_QOF_VERSION   "qof_version"
#define MAP_NAME_ATTR   "name"
#define MAP_TYPE_ATTR   "type"
#define MAP_VALUE_ATTR   "value"
#define MAP_OBJECT_ATTR   "object"
#define MAP_E_TYPE   "e_type"
#define MAP_ENUM_TYPE   "enum"
#define QSF_BOOLEAN_DEFAULT   "boolean"
 A specific boolean default for this map.
#define QSF_CONDITIONAL   "if"
#define QSF_CONDITIONAL_SET   "set"
#define QSF_CONDITIONAL_ELSE   "else"
#define QSF_OPTION   "option"
#define QSF_FORMATTING_OPTION   "format"

Typedefs

typedef struct qsf_object_set qsf_objects
 Holds a description of the QofObject.
typedef struct qsf_metadata qsf_param
 QSF Parameters.
typedef struct qsf_validates qsf_validator
 Validation metadata.

Enumerations

enum  qsf_type {
  QSF_UNDEF = 0, IS_QSF_MAP, IS_QSF_OBJ, HAVE_QSF_MAP,
  OUR_QSF_OBJ
}

Functions

gint qsf_compare_tag_strings (const xmlChar *node_name, gchar *tag_name)
 shorthand function
gint qsf_strings_equal (const xmlChar *node_name, gchar *tag_name)
 shorthand function
gint qsf_is_element (xmlNodePtr a, xmlNsPtr ns, gchar *c)
 shorthand function
gint qsf_check_tag (qsf_param *params, gchar *qof_type)
 shorthand function
void qsf_object_validation_handler (xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
 Checks all incoming objects for QOF registration.
gboolean qsf_is_valid (const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
 Compares an xmlDoc in memory against the schema file.
GList ** qsf_map_prepare_list (GList **maps)
 Prepare the default list of maps.
void qsf_book_node_handler (xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params)
 Book and book-guid node handler.
KvpValuestring_to_kvp_value (const gchar *content, KvpValueType type)
 Convert a string value into KvpValue.
void qsf_valid_foreach (xmlNodePtr parent, qsf_validCB cb, struct qsf_node_iterate *iter, qsf_validator *valid)
void qsf_node_foreach (xmlNodePtr parent, qsf_nodeCB cb, struct qsf_node_iterate *iter, qsf_param *params)
xmlDocPtr qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params)
 Convert between QSF objects.
void qsf_object_node_handler (xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params)


Detailed Description

Private QSF header - not for use by applications.

Author:
Copyright (C) 2004-2005 Neil Williams <linux@codehelp.co.uk>

Definition in file qsf-xml.h.


Define Documentation

#define MAP_CALCULATE_TAG   "calculate"

One calculation for every parameter that needs to be set.

QSF follows the same rule as qof_book_merge. Only if a getter and a setter function are defined for a parameter is it available to QSF. If a QofAccessFunc and QofSetterFunc are both defined for any QofObject parameter, that parameter MUST be calculated in any map that defines that object.

Definition at line 194 of file qsf-xml.h.

#define MAP_DEFAULT_TAG   "default"

User editable defaults for data not available within the available QSF objects.

Some defaults will relate to how to format descriptive dates, whether discount should be considered, which account to use for certain QSF data from applications that do not use accounts.

Some defaults are pre-defined and cannot be over-written:

  • qsf_time_now
  • qsf_time_string

Attributes (All are mandatory):

name The text name for this default. Certain pre-defined defaults exist but user- or map-defined defaults can have any unique text name. Spaces are NOT allowed, use undersccores instead. The value of name must not duplicate any existing default, define, object or parameter unless the special type, enum, is used.

type QOF_TYPE - must be one of the recognised QOF data types for the qof_version in use or the special type, enum.

value Text representation of the required value. For numeric, use the format [0-9]?/[0-9]?

Attention:
Using boolean defaults
A boolean default is not output in the QSF directly, instead the value is used in the calculations to modify certain values. If the boolean default is set to true, the if statement containing the boolean name will be evaluated. If the boolean default is set to false, the corresponding else will be evaluted. Make sure your calculations contain an appropriate else statement so that the boolean value can be adjusted without invalidating the map!

QSF deals with partial QofBooks - each object is fully described but the book does not have to contain any specific object types or have any particular structure. To merge partial books into usual QofBook data sources, the map must deal with entities that need to be referenced in the target QofBook but which simply do not exist in the QofBook used to generate the QSF. e.g. pilot-link knows nothing of Accounts yet when QSF creates a gncInvoice from qof-datebook, gncInvoice needs to know the GncGUID of certain accounts in the target QofBook. This is handled in the map by specifying the name of the account as a default for that map. When imported, the QSF QofBackend looks up the object required using the name of the parameter to obtain the parameter type. This is the only situation where QSF converts between QOF data types. A string description of the required object is converted to the GncGUID for that specific entity. The map cannot contain the GncGUID as it is generic and used by multiple users.

Attention:
Using enumerators
  • enum types are the only defaults that are allowed to use the same name value more than once.
  • enum types are used to increase the readability of a QSF map.
  • The enum name acts to group the enum values together - in a similar fashion to radio buttons in HTML forms.
  • enum types are used only where the QOF object itself uses an enum type.
e.g. the tax_included enum type allows maps to use the full name of the enum value GNC_TAXINCLUDED_YES, instead of the cryptic digit value, 1.

Definition at line 126 of file qsf-xml.h.

#define MAP_DEFINE_TAG   "define"

defines each object supported by this QSF map

Attributes: e_type Copied directly from the QofObject definition. Content: The full QofObject description for the defined QOF object.

Definition at line 119 of file qsf-xml.h.

#define MAP_DEFINITION_TAG   "definition"

Second level container for defined objects

Attributes: qof_version - Taken from the QOF_OBJECT_VERSION macro in QOF, At the time of QSF development, QOF_OBJECT_VERSION is defined as 3. All QSF maps and QSF objects must use the same qof_version which in turn must match the QOF_OBJECT_VERSION for the QOF library in use by the calling process.

No text content allowed.

Definition at line 110 of file qsf-xml.h.

#define MAP_E_TYPE   "e_type"

Validates the objects defined in the map

The e_type will be used to match incoming QSF objects with the relevant QSF map. The value of the e_type must be the value of the e_type for that object in the originating QOF application. The define tag must contain the value of the description of the same object in the same originating QOF application.

Definition at line 232 of file qsf-xml.h.

#define MAP_ENUM_TYPE   "enum"

Todo:
enum is an attempt to make enumerator values descriptive in the maps and QSF (possibly). Not working yet.

Definition at line 241 of file qsf-xml.h.

#define MAP_ITERATE_ATTR   "foreach"

Dictate which object type is the basis for iteration in a hierarchical object set.

Definition at line 124 of file qsf-xml.h.

#define MAP_NAME_ATTR   "name"

The name of the default setting.

Use this name to refer to the value of this default in the map calculations.

Make sure that the type of this default matches the type of the parameter being set by the parent calculation!

Definition at line 208 of file qsf-xml.h.

#define MAP_OBJECT_ATTR   "object"

The object to use to provide the data being set using the map.

Definition at line 230 of file qsf-xml.h.

#define MAP_OBJECT_TAG   "object"

Contains all the calculations to make one object from others.

Note that creating an object for the import application can involve using data from more than one QSF object, as well as defaults and lookups in the import application itself. Conditionals, simple arithmetic and date/time formatting options are also available.

Definition at line 186 of file qsf-xml.h.

#define MAP_QOF_VERSION   "qof_version"

This is the QOF_OBJECT_VERSION from QOF.

QSF maps may need to be updated if QOF itself is upgraded. This setting is coded into QOF and maps for one version cannot necessarily be used by other versions. At the first release of QSF, QOF_OBJECT_VERSION = 3.

Definition at line 202 of file qsf-xml.h.

#define MAP_ROOT_TAG   "qsf-map"

Top level root tag for QSF Maps

Definition at line 109 of file qsf-xml.h.

#define MAP_TYPE_ATTR   "type"

QSF will NOT convert between QOF types.

QSF will allow a conditional to use a parameter of one type to determine the value from a parameter of another type, but the final value assigned MUST be of the same type as the parent calculation.

Definition at line 215 of file qsf-xml.h.

#define MAP_VALUE_ATTR   "value"

The value of the tag, used in defaults and calculations.

The value of a default is a string representation of the value to be inserted into the calculation where the default is used.

The value of a calculation is the name of the parameter that will be set by that calculation.

Definition at line 221 of file qsf-xml.h.

#define QSF_BOOK_COUNT   "count"

Sequential counter of each book in this file

Definition at line 83 of file qsf-xml.h.

#define QSF_BOOK_GUID   "book-guid"

QOF GncGUID tag for the QofBook described by this QSF object file

Definition at line 81 of file qsf-xml.h.

#define QSF_BOOK_TAG   "book"

First level child: book tag - the QofBook.

Definition at line 80 of file qsf-xml.h.

#define QSF_CONDITIONAL   "if"

child of calculate.

Conditionals can reference objects as if within the original application. In operation, the map is overlaid across both sets of defined objects, an import object in the source application and an output object for the destination object. The current import and output QSF objects are therefore always available to the map. Conditionals can reference parameter as well as object values.

Definition at line 247 of file qsf-xml.h.

#define QSF_CONDITIONAL_ELSE   "else"

Alternative

if(){} else{} is also supported. Nesting of conditionals causes problems for validating the final map against any sensible XML Schema and a map that does not validate will be rejected. When editing conditionals in a QSF map, ALWAYS validate the map using xmllint. If necessary, define a variable at the foot of the definitions block, using a similar syntax to a default, then use that variable in another conditional

variable name="my_rate" type="numeric" value="0/1"

The syntax for xmllint is:

xmllint --schema <schema file> <qsf-file>

Use the qsf-object.xsd.xml schema for objects and qsf-map.xsd.xml for map files.

e.g. xmllint --schema qsf-object.xsd.xml --noout qof-qsf.xml

Definition at line 263 of file qsf-xml.h.

#define QSF_CONDITIONAL_SET   "set"

Assignment statement

Map assignments can use the native values within the output object. The output object must support setting the relevant parameter using the value exactly as given in the map because the relevant set() function will be called using this value. This may reduce the readability of the map but the relevant application could also be modified to support a more readable set function.

Definition at line 255 of file qsf-xml.h.

#define QSF_DATE_LENGTH   MAX_DATE_LENGTH

Max length of QSF_XSD_TIME.

MAX_DATE_LENGTH itself is defined in gnc-date.h

Definition at line 77 of file qsf-xml.h.

#define QSF_DEFAULT_NS   "http://qof.sourceforge.net/"

Default namespace for QSF root tag

The map namespace is not included as maps are not currently written out by QOF.

Definition at line 73 of file qsf-xml.h.

#define QSF_FORMATTING_OPTION   "format"

How to format dates/times

When the QSF map uses a date/time value as a string, the formatting can be adjusted to personal preference. format will only be evaluated if the calculated parameter is a QOF_TYPE_STRING - any format attributes on other data types will be ignored.

Definition at line 290 of file qsf-xml.h.

#define QSF_MAP_SCHEMA   "qsf-map.xsd.xml"

Name of the QSF Map Schema.

Definition at line 334 of file qsf-xml.h.

#define QSF_OBJECT_COUNT   "count"

Sequential counter for each QSF object in this file

Definition at line 86 of file qsf-xml.h.

#define QSF_OBJECT_KVP   "path"

The path to this KVP value in the entity frame.

Definition at line 103 of file qsf-xml.h.

#define QSF_OBJECT_SCHEMA   "qsf-object.xsd.xml"

Name of the QSF Object Schema.

Definition at line 333 of file qsf-xml.h.

#define QSF_OBJECT_TAG   "object"

Second level child: object tag

Definition at line 84 of file qsf-xml.h.

#define QSF_OBJECT_TYPE   "type"

QSF parameter name for object type specifiers

Definition at line 85 of file qsf-xml.h.

#define QSF_OBJECT_VALUE   "value"

The KVP Value.

Definition at line 104 of file qsf-xml.h.

#define QSF_OPTION   "option"

enum operator

Not implemented yet - may need to change once work starts. Theoretically, option will specify when an enumerator value is in use - it is quite possible that it will be unnecessary.

Definition at line 283 of file qsf-xml.h.

#define QSF_QOF_VERSION   QOF_OBJECT_VERSION

QOF Version check.

Make sure the same version of QOF is in use in both applications.

Definition at line 65 of file qsf-xml.h.

#define QSF_ROOT_TAG   "qof-qsf"

The top level root tag

Definition at line 72 of file qsf-xml.h.

#define QSF_XML_BOOLEAN_TEST   "true"

needs to be lowercase for XML validation

Definition at line 331 of file qsf-xml.h.

#define QSF_XML_VERSION   "1.0"

The current XML version.

Definition at line 88 of file qsf-xml.h.

#define QSF_XSD_TIME   QOF_UTC_DATE_FORMAT

xsd:dateTime format in coordinated universal time, UTC.

You can reproduce the string from the GNU/Linux command line using the date utility:

date -u +Y-m-dTH:M:SZ

2004-12-12T23:39:11Z

The datestring must be timezone independent and include all specified fields.

Remember to use gmtime() NOT localtime()!. From the command line, use the -u switch with the date command: date -u

To generate a timestamp based on a real time, use the qsf_time_now and qsf_time_string defaults.

qsf_time_now : Format: QOF_TYPE_DATE. The current time taken from the moment the default is read into a QSF object at runtime.

qsf_time_string : Format: QOF_TYPE_STRING. The current timestamp taken from the moment the default is read into a QSF object at runtime. This form is used when the output parameter needs a formatted date string, not an actual date object. The format is determined by the optional format attribute of the set tag which takes the same operators as the GNU C Library for strftime() and output may therefore be dependent on the locale of the calling process - take care. Default value is F, used when qsf_time_string is set without the format attribute.

Both defaults use UTC.

Definition at line 300 of file qsf-xml.h.


Typedef Documentation

typedef void(* qsf_nodeCB)(xmlNodePtr, xmlNsPtr, qsf_param *)

map and qsf object callback

This callback cannot do both the map and the validation tasks because validation sometimes needs to be done without qsf_params.

e.g. when selecting which backend should be used for a particular data source where two or more backends share the same access_method.

Definition at line 486 of file qsf-xml.h.

typedef struct qsf_object_set qsf_objects

Holds a description of the QofObject.

Used when converting QOF objects from another application. The incoming, unknown, objects need to be stored prior to conversion. This allows many-to-many conversions where an invoice can receive data from an incoming expense AND datebook and use data from an incoming contacts object to lookup the customer for the invoice.

typedef struct qsf_metadata qsf_param

QSF Parameters.

This struct is a catch-all for all parameters required for various stages of the process. There are lots of elements here that will finally be removed.

typedef struct qsf_validates qsf_validator

Validation metadata.

The validation is a separate parse with separate data. This is used to determine which backend should load the data.

typedef void(* qsf_validCB)(xmlNodePtr, xmlNsPtr, qsf_validator *)

validator callback

Todo:
The need for separate metadata means a separate callback typedef is needed for the validator, but this should be fixed to only need one.

Definition at line 492 of file qsf-xml.h.


Enumeration Type Documentation

enum qsf_type

Enumerator:
QSF_UNDEF  Initial undefined value.
IS_QSF_MAP  A QSF map
IS_QSF_OBJ  A QSF object without a map - it may or may not need one.
HAVE_QSF_MAP  A QSF object with the map it needs.
OUR_QSF_OBJ  A QSF object that can be loaded without a map.

Definition at line 41 of file qsf-xml.h.

00042 {
00043     QSF_UNDEF = 0, 
00044     IS_QSF_MAP,   
00045     IS_QSF_OBJ,   
00046     HAVE_QSF_MAP, 
00047     OUR_QSF_OBJ,  
00048 } qsf_type;


Function Documentation

gboolean is_our_qsf_object ( const gchar *  path  ) 

Validate a QSF file.

Parameters:
path Absolute or relative path to the file to be validated
The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to see if it is registered with QOF within the QOF environment of the calling process.

Files that pass the test can be imported into the QOF appliction without the need for a QSF map.

Returns:
TRUE if the file validates and all objects pass, otherwise FALSE.

Definition at line 155 of file qsf-xml.c.

00156 {
00157     xmlDocPtr doc;
00158     struct qsf_node_iterate iter;
00159     xmlNodePtr object_root;
00160     qsf_validator valid;
00161     gint table_count;
00162 
00163     g_return_val_if_fail((path != NULL), FALSE);
00164     doc = xmlParseFile(path);
00165     if (doc == NULL)
00166     {
00167         return FALSE;
00168     }
00169     if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00170     {
00171         PINFO (" validation failed %s %s %s", QSF_SCHEMA_DIR,
00172                QSF_OBJECT_SCHEMA, path);
00173         xmlFreeDoc(doc);
00174         return FALSE;
00175     }
00176     object_root = xmlDocGetRootElement(doc);
00177     /* check that all objects in the file are already registered in QOF */
00178     valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00179     valid.qof_registered_count = 0;
00180     valid.valid_object_count = 0;
00181     iter.ns = object_root->ns;
00182     qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
00183     table_count = g_hash_table_size(valid.validation_table);
00184     g_hash_table_destroy(valid.validation_table);
00185     if (table_count == valid.qof_registered_count)
00186     {
00187         return TRUE;
00188     }
00189     return FALSE;
00190 }

gboolean is_our_qsf_object_be ( qsf_param params  ) 

Validate a QSF file and determine type.

Parameters:
params Pointer to qsf_param context
The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to see if it is registered with QOF within the QOF environment of the calling process.

Files that pass the test can be imported into the QOF appliction without the need for a QSF map.

Returns:
TRUE if the file validates and all objects pass, otherwise FALSE.

Definition at line 217 of file qsf-xml.c.

00218 {
00219     xmlDocPtr doc;
00220     struct qsf_node_iterate iter;
00221     xmlNodePtr object_root;
00222     qsf_validator valid;
00223     gint table_count;
00224     gchar *path;
00225 
00226     g_return_val_if_fail((params != NULL), FALSE);
00227     path = g_strdup(params->filepath);
00228     if (path == NULL)
00229     {
00230         qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
00231         return FALSE;
00232     }
00233     if (params->file_type != QSF_UNDEF)
00234     {
00235         return FALSE;
00236     }
00237     doc = xmlParseFile(path);
00238     if (doc == NULL)
00239     {
00240         qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
00241         return FALSE;
00242     }
00243     if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00244     {
00245         qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
00246         return FALSE;
00247     }
00248     params->file_type = IS_QSF_OBJ;
00249     object_root = xmlDocGetRootElement(doc);
00250     valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
00251     valid.qof_registered_count = 0;
00252     iter.ns = object_root->ns;
00253     qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
00254     table_count = g_hash_table_size(valid.validation_table);
00255     if (table_count == valid.qof_registered_count)
00256     {
00257         g_hash_table_destroy(valid.validation_table);
00258         qof_backend_set_error(params->be, ERR_BACKEND_NO_ERR);
00259         return TRUE;
00260     }
00261     g_hash_table_destroy(valid.validation_table);
00262     qof_backend_set_error(params->be, ERR_QSF_NO_MAP);
00263     return FALSE;
00264 }

gboolean is_qsf_map ( const gchar *  path  ) 

Validate a QSF map file.

Parameters:
path Absolute or relative path to the file to be validated
These functions are in pairs. When called from within a QofSession, the qsf_param context will be available. When just determining the type of file, qsf_param is not necessary. Use the *_be functions from within the QofBackend and the corresponding function in other code.

The file is validated aginst the QSF map schema, qsf-map.xsd.xsml. This function is called by is_qsf_object. If called directly, the map file is validated and closed, no data is retrieved. QSF maps do not contain user data but are used to import QSF object files from other applications.

Returns:
TRUE if the map validates, otherwise FALSE.

Definition at line 330 of file qsf-xml-map.c.

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 }

gboolean is_qsf_map_be ( qsf_param params  ) 

Validate a QSF map file.

Parameters:
params Pointer to qsf_param context
The file is validated aginst the QSF map schema, qsf-map.xsd.xsml. This function is called by is_qsf_object. If called directly, the map file is validated and closed with a QofBackend error. QSF maps do not contain user data and are used to import QSF object files.

Returns:
TRUE if the map validates, otherwise FALSE.

Definition at line 285 of file qsf-xml-map.c.

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 }

gboolean is_qsf_object ( const gchar *  path  ) 

Validate a QSF file and identify a suitable QSF map.

Parameters:
path Absolute or relative path to the file to be validated.
These functions are in pairs. When called from within a QofSession, the qsf_param context will be available. When just determining the type of file, qsf_param is not necessary. Use the *_be functions from within the QofBackend and the corresponding function in other code.

The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to find out if a suitable QSF map exists. Map files are accepted if all objects described in the QSF object file are defined in the QSF map.

Returns:
TRUE if the file validates and a QSF map can be found, otherwise FALSE.

Definition at line 192 of file qsf-xml.c.

00193 {
00194     xmlDocPtr doc;
00195 
00196     g_return_val_if_fail((path != NULL), FALSE);
00197     if (path == NULL)
00198     {
00199         return FALSE;
00200     }
00201     doc = xmlParseFile(path);
00202     if (doc == NULL)
00203     {
00204         return FALSE;
00205     }
00206     if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00207     {
00208         xmlFreeDoc(doc);
00209         return FALSE;
00210     }
00211     xmlFreeDoc(doc);
00212     /* Note cannot test against a map here, so if the file is valid QSF,
00213     accept it and work out the details later. */
00214     return TRUE;
00215 }

gboolean is_qsf_object_be ( qsf_param params  ) 

Validate a QSF file and identify a suitable QSF map.

Parameters:
params Pointer to qsf_param context
These functions are in pairs. When called from within a QofSession, the qsf_param context will be available. When just determining the type of file, qsf_param is not necessary. Use the *_be functions from within the QofBackend and the corresponding function in other code.

The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to find out if a suitable QSF map exists. Map files are accepted if all objects described in the QSF object file are defined in the QSF map.

Returns:
TRUE if the file validates and a QSF map can be found, otherwise FALSE.

Definition at line 266 of file qsf-xml.c.

00267 {
00268     gboolean result;
00269     xmlDocPtr doc;
00270     GList *maps;
00271     gchar *path;
00272 
00273     g_return_val_if_fail((params != NULL), FALSE);
00274     path = g_strdup(params->filepath);
00275     if (path == NULL)
00276     {
00277         qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
00278         return FALSE;
00279     }
00280     /* skip validation if is_our_qsf_object has already been called. */
00281     if (ERR_QSF_INVALID_OBJ == qof_backend_get_error(params->be))
00282     {
00283         return FALSE;
00284     }
00285     if (params->file_type == QSF_UNDEF)
00286     {
00287         doc = xmlParseFile(path);
00288         if (doc == NULL)
00289         {
00290             qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
00291             return FALSE;
00292         }
00293         if (TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
00294         {
00295             qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
00296             return FALSE;
00297         }
00298     }
00299     result = FALSE;
00300     /* retrieve list of maps from config frame. */
00301     for (maps = params->map_files; maps; maps = maps->next)
00302     {
00303         QofBackendError err;
00304         result = is_qsf_object_with_map_be(maps->data, params);
00305         err = qof_backend_get_error(params->be);
00306         if ((err == ERR_BACKEND_NO_ERR) && result)
00307         {
00308             params->map_path = maps->data;
00309             PINFO ("map chosen = %s", params->map_path);
00310             break;
00311         }
00312         /* pop the error back on the stack. */
00313         else
00314         {
00315             qof_backend_set_error(params->be, err);
00316         }
00317     }
00318     return result;
00319 }

gboolean is_qsf_object_with_map ( const gchar *  path,
gchar *  map_file 
)

Validate a QSF file and a selected QSF map.

Parameters:
path Absolute or relative path to the selected QSF map file
map_file Name of the map file
The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to find out if the supplied QSF map is suitable. Map files are accepted if all objects described in the QSF object file are defined in the QSF map.

Returns:
TRUE if the file validates and the supplied QSF map is usable, otherwise FALSE.

Definition at line 221 of file qsf-xml-map.c.

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 }

gboolean is_qsf_object_with_map_be ( gchar *  map_path,
qsf_param params 
)

Validate a QSF file and a selected QSF map.

Parameters:
map_path Absolute or relative path to the selected QSF map file
params Pointer to qsf_param context
The file is validated against the QSF object schema, qsf-object.xsd.xml and each object described in the file is checked to find out if the supplied QSF map is suitable. Map files are accepted if all objects described in the QSF object file are defined in the QSF map.

This backend twin also sets QofBackendError codes.

Returns:
TRUE if the file validates and the supplied QSF map is usable, otherwise FALSE.

Definition at line 124 of file qsf-xml-map.c.

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     /* check all counted objects are valid */
00190     /* Should be:
00191     the same number of valid object calculations as there are defined in the map.
00192     And the number of calculations must match the number of unregistered
00193     objects plus the number of registered objects defined. */
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     /* the object is OK, only the map is wrong. */
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 }

void qsf_book_node_handler ( xmlNodePtr  child,
xmlNsPtr  qsf_ns,
qsf_param params 
)

Book and book-guid node handler.

Reads the book count="" attribute (currently only 1 QofBook is supported per QSF object file) Sets the book-guid as the GncGUID of the current QofBackend QofBook in qsf_param. Calls the next handler, qsf_object_node_handler, with the child of the book tag.

Definition at line 377 of file qsf-xml.c.

00378 {
00379     gchar *book_count_s, *tail;
00380     gint book_count;
00381     xmlNodePtr child_node;
00382     struct qsf_node_iterate iter;
00383     gchar *buffer;
00384     GncGUID book_guid;
00385 
00386     g_return_if_fail(child);
00387     g_return_if_fail(params);
00388     ENTER (" child=%s", child->name);
00389     if (qsf_is_element(child, ns, QSF_BOOK_TAG))
00390     {
00391         book_count_s = (gchar*)xmlGetProp(child, BAD_CAST QSF_BOOK_COUNT);
00392         if (book_count_s)
00393         {
00394             book_count = (gint)strtol(book_count_s, &tail, 0);
00395             /* More than one book not currently supported. */
00396             g_return_if_fail(book_count == 1);
00397         }
00398         iter.ns = ns;
00399         child_node = child->children->next;
00400         if (qsf_is_element(child_node, ns, QSF_BOOK_GUID))
00401         {
00402             DEBUG (" trying to set book GncGUID");
00403             buffer = g_strdup((gchar*)xmlNodeGetContent(child_node));
00404             g_return_if_fail(TRUE == string_to_guid(buffer, &book_guid));
00405             qof_instance_set_guid(QOF_INSTANCE(params->book), &book_guid);
00406             xmlNewChild(params->output_node, params->qsf_ns,
00407                         BAD_CAST QSF_BOOK_GUID, BAD_CAST buffer);
00408             g_free(buffer);
00409         }
00410         qsf_node_foreach(child, qsf_object_node_handler, &iter, params);
00411     }
00412     LEAVE (" ");
00413 }

gint qsf_check_tag ( qsf_param params,
gchar *  qof_type 
)

shorthand function

This may look repetitive but each one is used separately as well as in a block.

Definition at line 69 of file qsf-xml.c.

00070 {
00071     return qsf_is_element(params->child_node, params->qsf_ns, qof_type);
00072 }

gint qsf_compare_tag_strings ( const xmlChar *  node_name,
gchar *  tag_name 
)

shorthand function

This may look repetitive but each one is used separately as well as in a block.

Definition at line 39 of file qsf-xml.c.

00040 {
00041     return xmlStrcmp(node_name, (const xmlChar *)tag_name);
00042 }

gint qsf_is_element ( xmlNodePtr  a,
xmlNsPtr  ns,
gchar *  c 
)

shorthand function

This may look repetitive but each one is used separately as well as in a block.

Definition at line 55 of file qsf-xml.c.

00056 {
00057     g_return_val_if_fail(a != NULL, 0);
00058     g_return_val_if_fail(ns != NULL, 0);
00059     g_return_val_if_fail(c != NULL, 0);
00060     if ((a->ns == ns) && (a->type == XML_ELEMENT_NODE) &&
00061             qsf_strings_equal(a->name, c))
00062     {
00063         return 1;
00064     }
00065     return 0;
00066 }

gboolean qsf_is_valid ( const gchar *  schema_dir,
const gchar *  schema_filename,
xmlDocPtr  doc 
)

Compares an xmlDoc in memory against the schema file.

Parameters:
schema_dir set at compile time to $prefix/share/qsf/
schema_filename Either the QSF Object Schema or the QSF Map Schema.
doc The xmlDoc read from the file using libxml2.
Ensure that you call the right schema_filename for the doc in question!

Incorrect validation will result in output to the terminal window.

Returns:
TRUE if the doc validates against the assigned schema, otherwise FALSE.

Definition at line 75 of file qsf-xml.c.

00076 {
00077     xmlSchemaParserCtxtPtr qsf_schema_file;
00078     xmlSchemaPtr qsf_schema;
00079     xmlSchemaValidCtxtPtr qsf_context;
00080     gchar *schema_path;
00081     gint result;
00082 
00083     g_return_val_if_fail(doc || schema_filename, FALSE);
00084     schema_path = g_strdup_printf("%s/%s", schema_dir, schema_filename);
00085     qsf_schema_file = xmlSchemaNewParserCtxt(schema_path);
00086     qsf_schema = xmlSchemaParse(qsf_schema_file);
00087     qsf_context = xmlSchemaNewValidCtxt(qsf_schema);
00088     result = xmlSchemaValidateDoc(qsf_context, doc);
00089     xmlSchemaFreeParserCtxt(qsf_schema_file);
00090     xmlSchemaFreeValidCtxt(qsf_context);
00091     xmlSchemaFree(qsf_schema);
00092     g_free(schema_path);
00093     if (result == 0)
00094     {
00095         return TRUE;
00096     }
00097     return FALSE;
00098 }

GList** qsf_map_prepare_list ( GList **  maps  ) 

Prepare the default list of maps.

Prepend the default maps to the supplied GList.

The GList remains the property of the caller.

Definition at line 143 of file qsf-backend.c.

00144 {
00145     *maps = g_list_prepend(*maps, "pilot-qsf-GnuCashInvoice.xml");
00146     *maps = g_list_prepend(*maps, "pilot-qsf-gncCustomer.xml");
00147     return maps;
00148 }

void qsf_node_foreach ( xmlNodePtr  parent,
qsf_nodeCB  cb,
struct qsf_node_iterate iter,
qsf_param params 
)

Iterate over the children of the parent node.

Only iterates over the immediate children of the parent - this function is not recursive.

Definition at line 114 of file qsf-xml.c.

00116 {
00117     xmlNodePtr cur_node;
00118 
00119     g_return_if_fail(iter->ns);
00120     iter->fcn = &cb;
00121     for (cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
00122     {
00123         cb(cur_node, iter->ns, params);
00124     }
00125 }

xmlDocPtr qsf_object_convert ( xmlDocPtr  mapDoc,
xmlNodePtr  qsf_root,
qsf_param params 
)

Convert between QSF objects.

This is the main workhorse of the conversion between QSF objects using maps.

Parameters:
mapDoc The map document, parsed by libxml2.
qsf_root The top node of the QSF object to be converted using the map.
params The QSF backend parameters.
Each calculation in the map is performed over the child nodes of the object tree. A new xmlDoc is created and this is made available to QOF to be loaded into the book.

Definition at line 838 of file qsf-xml-map.c.

00839 {
00840     /* mapDoc : map document. qsf_root: incoming QSF root node. */
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     /* prepare the intermediary document */
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     /* parse the incoming QSF */
00858     qsf_book_node_handler(qsf_root->children->next, params->qsf_ns, params);
00859     /* parse the map and calculate the values */
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     /* identify the entities of iterator type. */
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             /* cur_node describes the target object */
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     /* use for debugging */
00898     /*    xmlSaveFormatFileEnc("-", output_doc, "UTF-8", 1);*/
00899     LEAVE (" ");
00900     return output_doc;
00901 }

void qsf_object_node_handler ( xmlNodePtr  child,
xmlNsPtr  qsf_ns,
qsf_param params 
)

Despite the name, this function handles the QSF object book tag AND the object tags.

Used to parse object and map files.

Definition at line 344 of file qsf-xml.c.

00345 {
00346     struct qsf_node_iterate iter;
00347     qsf_objects *object_set;
00348     gchar *tail, *object_count_s;
00349     gint64 c;
00350 
00351     g_return_if_fail(child != NULL);
00352     g_return_if_fail(qsf_ns != NULL);
00353     params->qsf_ns = qsf_ns;
00354     if (qsf_is_element(child, qsf_ns, QSF_OBJECT_TAG))
00355     {
00356         params->qsf_parameter_hash = NULL;
00357         c = 0;
00358         object_set = g_new(qsf_objects, 1);
00359         params->object_set = object_set;
00360         object_set->object_count = 0;
00361         object_set->parameters = g_hash_table_new(g_str_hash, g_str_equal);
00362         object_set->object_type = g_strdup((gchar*)xmlGetProp(child,
00363                                            BAD_CAST QSF_OBJECT_TYPE));
00364         object_count_s = g_strdup((gchar*)xmlGetProp(child,
00365                                   BAD_CAST QSF_OBJECT_COUNT));
00366         c = (gint64)strtol(object_count_s, &tail, 0);
00367         object_set->object_count = (gint)c;
00368         g_free(object_count_s);
00369         params->qsf_object_list = g_list_prepend(params->qsf_object_list, object_set);
00370         iter.ns = qsf_ns;
00371         params->qsf_parameter_hash = object_set->parameters;
00372         qsf_node_foreach(child, qsf_parameter_handler, &iter, params);
00373     }
00374 }

void qsf_object_validation_handler ( xmlNodePtr  child,
xmlNsPtr  ns,
qsf_validator valid 
)

Checks all incoming objects for QOF registration.

Sums all existing objects in the QSF and counts the number of those objects that are also registered with QOF in the host application.

Definition at line 128 of file qsf-xml.c.

00129 {
00130     xmlNodePtr cur_node;
00131     xmlChar *object_declaration;
00132     guint count;
00133 
00134     count = 0;
00135     for (cur_node = child->children; cur_node != NULL;
00136             cur_node = cur_node->next)
00137     {
00138         if (qsf_is_element(cur_node, ns, QSF_OBJECT_TAG))
00139         {
00140             object_declaration = xmlGetProp(cur_node, BAD_CAST QSF_OBJECT_TYPE);
00141             count = g_hash_table_size(valid->validation_table);
00142             g_hash_table_insert(valid->validation_table, object_declaration, xmlNodeGetContent(cur_node));
00143             if (g_hash_table_size(valid->validation_table) > count)
00144             {
00145                 valid->valid_object_count++;
00146                 if (TRUE == qof_class_is_registered((QofIdTypeConst) object_declaration))
00147                 {
00148                     valid->qof_registered_count++;
00149                 }
00150             }
00151         }
00152     }
00153 }

gint qsf_strings_equal ( const xmlChar *  node_name,
gchar *  tag_name 
)

shorthand function

This may look repetitive but each one is used separately as well as in a block.

Definition at line 45 of file qsf-xml.c.

00046 {
00047     if (0 == qsf_compare_tag_strings(node_name, tag_name))
00048     {
00049         return 1;
00050     }
00051     return 0;
00052 }

void qsf_valid_foreach ( xmlNodePtr  parent,
qsf_validCB  cb,
struct qsf_node_iterate iter,
qsf_validator valid 
)

Validate the children of the parent node.

Note:
Slightly different to qsf_node_foreach because the validation can be run without qsf_param being initialized.

Definition at line 101 of file qsf-xml.c.

00103 {
00104     xmlNodePtr cur_node;
00105 
00106     iter->v_fcn = &cb;
00107     for (cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
00108     {
00109         cb(cur_node, iter->ns, valid);
00110     }
00111 }

KvpValue* string_to_kvp_value ( const gchar *  content,
KvpValueType  type 
)

Convert a string value into KvpValue.

Partner to kvp_value_to_string. Given the type of KvpValue required, attempts to convert the string into that type of value.

Parameters:
content A string representation of the value, ideally as output by kvp_value_to_string.
type KvpValueType of the intended KvpValue
Returns:
KvpValue* or NULL on failure.

Definition at line 1155 of file qsf-backend.c.

01156 {
01157     gchar        *tail;
01158     gint64      cm_i64;
01159     double      cm_double;
01160     gnc_numeric cm_numeric;
01161     GncGUID        *cm_guid;
01162     struct tm   kvp_time;
01163     time_t      kvp_time_t;
01164     Timespec    cm_date;
01165 
01166     switch (type)
01167     {
01168     case KVP_TYPE_GINT64:
01169         errno = 0;
01170         cm_i64 = strtoll(content, &tail, 0);
01171         if (errno == 0)
01172         {
01173             return kvp_value_new_gint64(cm_i64);
01174         }
01175         break;
01176     case KVP_TYPE_DOUBLE:
01177         errno = 0;
01178         cm_double = strtod(content, &tail);
01179         if (errno == 0)
01180         {
01181             return kvp_value_new_double(cm_double);
01182         }
01183         break;
01184     case KVP_TYPE_NUMERIC:
01185         string_to_gnc_numeric(content, &cm_numeric);
01186         return kvp_value_new_gnc_numeric(cm_numeric);
01187         break;
01188     case KVP_TYPE_STRING:
01189         return kvp_value_new_string(content);
01190         break;
01191     case KVP_TYPE_GUID:
01192         cm_guid = g_new(GncGUID, 1);
01193         if (TRUE == string_to_guid(content, cm_guid))
01194         {
01195             return kvp_value_new_guid(cm_guid);
01196         }
01197         break;
01198     case KVP_TYPE_TIMESPEC:
01199         strptime(content, QSF_XSD_TIME, &kvp_time);
01200         kvp_time_t = mktime(&kvp_time);
01201         timespecFromTime_t(&cm_date, kvp_time_t);
01202         return kvp_value_new_timespec(cm_date);
01203         break;
01204     case KVP_TYPE_BINARY:
01205 //              return kvp_value_new_binary(value->value.binary.data,
01206 //                                                                      value->value.binary.datasize);
01207         break;
01208     case KVP_TYPE_GLIST:
01209 //              return kvp_value_new_glist(value->value.list);
01210         break;
01211     case KVP_TYPE_FRAME:
01212 //              return kvp_value_new_frame(value->value.frame);
01213         break;
01214     case KVP_TYPE_GDATE:
01215     {
01216         GDate date;
01217         g_date_clear(&date, 1);
01218         g_date_set_parse(&date, content);
01219         return kvp_value_new_gdate(date);
01220     }
01221     }
01222     return NULL;
01223 }


Generated on Tue May 4 04:36:39 2010 for GnuCash by  doxygen 1.5.7.1