QOF
0.7.5
|
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 | QsfObject_s |
Holds a description of the QofObject. More... | |
struct | QsfMetadata_s |
QSF Parameters. More... | |
struct | QsfValidates_s |
Validation metadata. More... | |
struct | QsfNodeIterate |
One iterator, two typedefs. More... | |
Macros | |
#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 GUID $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 QsfObject_s | QsfObject |
Holds a description of the QofObject. More... | |
typedef struct QsfMetadata_s | QsfParam |
QSF Parameters. More... | |
typedef struct QsfValidates_s | QsfValidator |
Validation metadata. More... | |
Enumerations | |
enum | QsfType { QSF_UNDEF = 0, IS_QSF_MAP, IS_QSF_OBJ, HAVE_QSF_MAP, OUR_QSF_OBJ } |
enum | QsfStatus { QSF_NO_OBJECT = 0, QSF_DEFINED_OBJECT, QSF_REGISTERED_OBJECT, QSF_CALCULATED_OBJECT, QSF_INVALID_OBJECT } |
Status of various object during mapping. More... | |
Functions | |
gint | qsf_compare_tag_strings (const xmlChar *node_name, gchar *tag_name) |
shorthand function More... | |
gint | qsf_strings_equal (const xmlChar *node_name, gchar *tag_name) |
shorthand function More... | |
gint | qsf_is_element (xmlNodePtr a, xmlNsPtr ns, gchar *c) |
shorthand function More... | |
gint | qsf_check_tag (QsfParam *params, gchar *qof_type) |
shorthand function More... | |
void | qsf_object_validation_handler (xmlNodePtr child, xmlNsPtr ns, QsfValidator *valid) |
Checks all incoming objects for QOF registration. More... | |
gboolean | qsf_is_valid (const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc) |
Compares an xmlDoc in memory against the schema file. More... | |
GList ** | qsf_map_prepare_list (GList **maps) |
Prepare the default list of maps. More... | |
void | qsf_book_node_handler (xmlNodePtr child, xmlNsPtr qsf_ns, QsfParam *params) |
Book and book-guid node handler. More... | |
KvpValue * | string_to_kvp_value (const gchar *content, KvpValueType type) |
Convert a string value into KvpValue. More... | |
void | qsf_valid_foreach (xmlNodePtr parent, QsfValidCB cb, struct QsfNodeIterate *qsfiter, QsfValidator *valid) |
void | qsf_node_foreach (xmlNodePtr parent, QsfNodeCB cb, struct QsfNodeIterate *qsfiter, QsfParam *params) |
xmlDocPtr | qsf_object_convert (xmlDocPtr mapDoc, xmlNodePtr qsf_root, QsfParam *params) |
Convert between QSF objects. More... | |
void | qsf_object_node_handler (xmlNodePtr child, xmlNsPtr qsf_ns, QsfParam *params) |
Why two sets of functions and typedefs? | |
These functions are in pairs, one to use in an existing session and one to use when deciding which backend should be selected for a new session.
| |
typedef void(* | QsfNodeCB )(xmlNodePtr, xmlNsPtr, QsfParam *) |
map and qsf object callback More... | |
typedef void(* | QsfValidCB )(xmlNodePtr, xmlNsPtr, QsfValidator *) |
validator callback More... | |
gboolean | is_qsf_object_be (QsfParam *params) |
Validate a QSF file and identify a suitable QSF map. More... | |
gboolean | is_qsf_object (const gchar *path) |
Validate a QSF file and identify a suitable QSF map. More... | |
gboolean | is_our_qsf_object_be (QsfParam *params) |
Validate a QSF file and determine type. More... | |
gboolean | is_our_qsf_object (const gchar *path) |
Validate a QSF file. More... | |
gboolean | is_qsf_map_be (QsfParam *params) |
Validate a QSF map file. More... | |
gboolean | is_qsf_map (const gchar *path) |
Validate a QSF map file. More... | |
gboolean | is_qsf_object_with_map_be (gchar *map_path, QsfParam *params) |
Validate a QSF file and a selected QSF map. More... | |
gboolean | is_qsf_object_with_map (const gchar *path, gchar *map_file) |
Validate a QSF file and a selected QSF map. More... | |
Private QSF header - not for use by applications.
Definition in file qsf-xml.h.
#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.
#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:
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]?
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 GUID 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 GUID for that specific entity. The map cannot contain the GUID as it is generic and used by multiple users.
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.
#define MAP_DEFINE_TAG "define" |
#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.
#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.
#define MAP_ENUM_TYPE "enum" |
#define MAP_ITERATE_ATTR "foreach" |
#define MAP_NAME_ATTR "name" |
#define MAP_OBJECT_ATTR "object" |
#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.
#define MAP_QOF_VERSION "qof_version" |
#define MAP_ROOT_TAG "qsf-map" |
#define MAP_TYPE_ATTR "type" |
#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.
#define QSF_BOOK_COUNT "count" |
#define QSF_BOOK_GUID "book-guid" |
#define QSF_BOOK_TAG "book" |
#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.
#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
#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.
#define QSF_DATE_LENGTH MAX_DATE_LENGTH |
#define QSF_DEFAULT_NS "http://qof.sourceforge.net/" |
#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.
#define QSF_MAP_SCHEMA "qsf-map.xsd.xml" |
#define QSF_OBJECT_COUNT "count" |
#define QSF_OBJECT_KVP "path" |
#define QSF_OBJECT_SCHEMA "qsf-object.xsd.xml" |
#define QSF_OBJECT_TAG "object" |
#define QSF_OBJECT_TYPE "type" |
#define QSF_OPTION "option" |
#define QSF_QOF_VERSION QOF_OBJECT_VERSION |
#define QSF_XML_BOOLEAN_TEST "true" |
#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.
typedef void(* QsfNodeCB)(xmlNodePtr, xmlNsPtr, QsfParam *) |
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.
typedef struct QsfObject_s QsfObject |
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 QsfMetadata_s QsfParam |
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 QsfValidates_s QsfValidator |
Validation metadata.
The validation is a separate parse with separate data. This is used to determine which backend should load the data.
typedef void(* QsfValidCB)(xmlNodePtr, xmlNsPtr, QsfValidator *) |
enum QsfStatus |
Status of various object during mapping.
When handling a map, the incoming QSF objects are not registered with this instance of QOF - they originate from another QOF user. Each object in a map needs to be defined. If the object is registered, the map is checked to locate a calculation that can be used to generate this object. If the object is not registered, the incoming QSF is checked to ensure it provides the object data for the calculation. If anything goes wrong, QSF_INVALID_OBJECT is used.
Maps can be unidirectional or bidirectional so QOF registration is used to determine which calculations should be used and which should be ignored.
All QSF_REGISTERED_OBJECT types need a calculation - if any types remain tagged as QSF_REGISTERED_OBJECT when the map validation is complete, the validation must fail. The only acceptable end values for QsfStatus are QSF_DEFINED_OBJECT, QSF_CALCULATED_OBJECT or QSF_INVALID_OBJECT.
enum QsfType |
gboolean is_our_qsf_object | ( | const gchar * | path | ) |
Validate a QSF file.
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 application without the need for a QSF map.
Definition at line 180 of file qsf-xml.c.
gboolean is_our_qsf_object_be | ( | QsfParam * | params | ) |
Validate a QSF file and determine type.
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.
Definition at line 243 of file qsf-xml.c.
gboolean is_qsf_map | ( | const gchar * | path | ) |
Validate a QSF map file.
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.
Definition at line 372 of file qsf-xml-map.c.
gboolean is_qsf_map_be | ( | QsfParam * | params | ) |
Validate a QSF map file.
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.
Definition at line 320 of file qsf-xml-map.c.
gboolean is_qsf_object | ( | const gchar * | path | ) |
Validate a QSF file and identify a suitable QSF map.
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.
Definition at line 219 of file qsf-xml.c.
gboolean is_qsf_object_be | ( | QsfParam * | params | ) |
Validate a QSF file and identify a suitable QSF map.
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.
Definition at line 299 of file qsf-xml.c.
gboolean is_qsf_object_with_map | ( | const gchar * | path, |
gchar * | map_file | ||
) |
Validate a QSF file and a selected QSF map.
path | Absolute or relative path to the selected QSF object file |
map_file | Name of the QSF map file, located in QSF_SCHEMA_DIR. |
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.
Definition at line 290 of file qsf-xml-map.c.
gboolean is_qsf_object_with_map_be | ( | gchar * | map_path, |
QsfParam * | params | ||
) |
Validate a QSF file and a selected QSF map.
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 QofErrorId codes.
Definition at line 240 of file qsf-xml-map.c.
void qsf_book_node_handler | ( | xmlNodePtr | child, |
xmlNsPtr | qsf_ns, | ||
QsfParam * | 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 GUID 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 424 of file qsf-xml.c.
gint qsf_check_tag | ( | QsfParam * | params, |
gchar * | qof_type | ||
) |
shorthand function
This may look repetitive but each one is used separately as well as in a block.
gint qsf_compare_tag_strings | ( | const xmlChar * | node_name, |
gchar * | tag_name | ||
) |
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.
gboolean qsf_is_valid | ( | const gchar * | schema_dir, |
const gchar * | schema_filename, | ||
xmlDocPtr | doc | ||
) |
Compares an xmlDoc in memory against the schema file.
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.
Definition at line 75 of file qsf-xml.c.
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 167 of file qsf-backend.c.
void qsf_node_foreach | ( | xmlNodePtr | parent, |
QsfNodeCB | cb, | ||
struct QsfNodeIterate * | qsfiter, | ||
QsfParam * | params | ||
) |
Iterate over the children of the parent node.
Only iterates over the immediate children of the parent - this function is not recursive.
xmlDocPtr qsf_object_convert | ( | xmlDocPtr | mapDoc, |
xmlNodePtr | qsf_root, | ||
QsfParam * | params | ||
) |
Convert between QSF objects.
This is the main workhorse of the conversion between QSF objects using maps.
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 954 of file qsf-xml-map.c.
void qsf_object_node_handler | ( | xmlNodePtr | child, |
xmlNsPtr | qsf_ns, | ||
QsfParam * | params | ||
) |
void qsf_object_validation_handler | ( | xmlNodePtr | child, |
xmlNsPtr | ns, | ||
QsfValidator * | valid | ||
) |
gint qsf_strings_equal | ( | const xmlChar * | node_name, |
gchar * | tag_name | ||
) |
void qsf_valid_foreach | ( | xmlNodePtr | parent, |
QsfValidCB | cb, | ||
struct QsfNodeIterate * | qsfiter, | ||
QsfValidator * | valid | ||
) |
Validate the children of the parent node.
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.
content | A string representation of the value, ideally as output by kvp_value_to_string. |
type | KvpValueType of the intended KvpValue |
Definition at line 1223 of file qsf-backend.c.