QOF  0.8.7
Data Structures | Macros | Typedefs | Enumerations | Functions
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  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...
 
KvpValuestring_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.

  • When there is an existing QofSession, the qsf_param context will be available, so set error codes in the backend. Use the *_be functions.
  • When just determining the type of file, qsf_param is not necessary and no backend is available (it has not been selected yet). Use the twin function. e.g. in ::qsf_file_type()
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...
 

Detailed Description

Private QSF header - not for use by applications.

Author
Copyright (C) 2004-2005 Neil Williams linux.nosp@m.@cod.nosp@m.ehelp.nosp@m..co..nosp@m.uk

Definition in file qsf-xml.h.

Macro Definition 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 251 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 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.

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 229 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 154 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 147 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 303 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 307 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 158 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 270 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 293 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 240 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 260 of file qsf-xml.h.

#define MAP_ROOT_TAG   "qsf-map"

Top level root tag for QSF Maps

Definition at line 136 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 279 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 289 of file qsf-xml.h.

#define QSF_BOOK_COUNT   "count"

Sequential counter of each book in this file

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

#define QSF_BOOK_GUID   "book-guid"

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

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

#define QSF_BOOK_TAG   "book"

First level child: book tag - the QofBook.

Definition at line 94 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 322 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 358 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 334 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 qof-time.h

Definition at line 91 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 87 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 376 of file qsf-xml.h.

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

Name of the QSF Map Schema.

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

#define QSF_OBJECT_COUNT   "count"

Sequential counter for each QSF object in this file

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

#define QSF_OBJECT_KVP   "path"

The path to this KVP value in the entity frame.

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

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

Name of the QSF Object Schema.

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

#define QSF_OBJECT_TAG   "object"

Second level child: object tag

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

#define QSF_OBJECT_TYPE   "type"

QSF parameter name for object type specifiers

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

#define QSF_OBJECT_VALUE   "value"

The KVP Value.

Definition at line 129 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 366 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 70 of file qsf-xml.h.

#define QSF_ROOT_TAG   "qof-qsf"

The top level root tag

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

#define QSF_XML_BOOLEAN_TEST   "true"

needs to be lowercase for XML validation

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

#define QSF_XML_VERSION   "1.0"

The current XML version.

Definition at line 107 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 414 of file qsf-xml.h.

Typedef Documentation

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.

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

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 *)

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 684 of file qsf-xml.h.

Enumeration Type Documentation

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.

Enumerator
QSF_NO_OBJECT 

Init value.

QSF_DEFINED_OBJECT 

The object is unregistered but defined. Objects of this type must exist in the incoming QSF and must provide data for the calculation of registered objects.

QSF_REGISTERED_OBJECT 

Temporary value. The object is registered and defined - a calculation is needed but has not been found, yet.

QSF_CALCULATED_OBJECT 

The object is registered, defined and can be calculated.

QSF_INVALID_OBJECT 

Oops value.

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

467 {
enum QsfType
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.

42 {
44  QSF_UNDEF = 0,
46  IS_QSF_MAP,
48  IS_QSF_OBJ,
53 } QsfType;
QsfType
Definition: qsf-xml.h:41

Function Documentation

gboolean is_our_qsf_object ( const gchar *  path)

Validate a QSF file.

Parameters
pathAbsolute 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.

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

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

180 {
181  xmlDocPtr doc;
182  struct QsfNodeIterate qsfiter;
183  xmlNodePtr object_root;
184  QsfValidator valid;
185  gint table_count;
186 
187  g_return_val_if_fail ((path != NULL), FALSE);
188  doc = xmlParseFile (path);
189  if (doc == NULL)
190  {
191  return FALSE;
192  }
193  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
194  {
195  PINFO (" validation failed %s %s %s", QSF_SCHEMA_DIR,
196  QSF_OBJECT_SCHEMA, path);
197  return FALSE;
198  }
199  object_root = xmlDocGetRootElement (doc);
200  /* check that all objects in the file are already registered in QOF */
201  valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
202  valid.qof_registered_count = 0;
203  valid.valid_object_count = 0;
204  qsfiter.ns = object_root->ns;
206  &qsfiter, &valid);
207  table_count = g_hash_table_size (valid.object_table);
208  g_hash_table_destroy (valid.object_table);
209  xmlFreeDoc (doc);
210  if (table_count == valid.qof_registered_count)
211  {
212  return TRUE;
213  }
214  return FALSE;
215 }
void qsf_object_validation_handler(xmlNodePtr child, xmlNsPtr ns, QsfValidator *valid)
Checks all incoming objects for QOF registration.
Definition: qsf-xml.c:133
#define PINFO(format, args...)
Definition: qoflog.h:199
Validation metadata.
Definition: qsf-xml.h:558
void qsf_valid_foreach(xmlNodePtr parent, QsfValidCB cb, struct QsfNodeIterate *qsfiter, QsfValidator *valid)
Definition: qsf-xml.c:101
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
One iterator, two typedefs.
Definition: qsf-xml.h:689
gint qof_registered_count
Definition: qsf-xml.h:578
gint valid_object_count
Definition: qsf-xml.h:572
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
GHashTable * object_table
Definition: qsf-xml.h:565
gboolean is_our_qsf_object_be ( QsfParam params)

Validate a QSF file and determine type.

Parameters
paramsPointer 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 242 of file qsf-xml.c.

243 {
244  xmlDocPtr doc;
245  struct QsfNodeIterate qsfiter;
246  xmlNodePtr object_root;
247  QsfValidator valid;
248  gint table_count;
249 
250  g_return_val_if_fail ((params != NULL), FALSE);
251  if (params->filepath == NULL)
252  {
253  qof_error_set_be (params->be, qof_error_register
254  (_("The QSF XML file '%s' could not be found."), TRUE));
255  return FALSE;
256  }
257  if (params->file_type != QSF_UNDEF)
258  {
259  return FALSE;
260  }
261  doc = xmlParseFile (params->filepath);
262  if (doc == NULL)
263  {
264  qof_error_set_be (params->be, qof_error_register
265  (_("There was an error parsing the file '%s'."), TRUE));
266  return FALSE;
267  }
268  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
269  {
270  qof_error_set_be (params->be, qof_error_register
271  (_("Invalid QSF Object file! The QSF object file '%s' "
272  " failed to validate against the QSF object schema. "
273  "The XML structure of the file is either not well-formed "
274  "or the file contains illegal data."), TRUE));
275  xmlFreeDoc (doc);
276  return FALSE;
277  }
278  params->file_type = IS_QSF_OBJ;
279  object_root = xmlDocGetRootElement (doc);
280  xmlFreeDoc (doc);
281  valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
282  valid.qof_registered_count = 0;
283  qsfiter.ns = object_root->ns;
285  &qsfiter, &valid);
286  table_count = g_hash_table_size (valid.object_table);
287  if (table_count == valid.qof_registered_count)
288  {
289  g_hash_table_destroy (valid.object_table);
290  return TRUE;
291  }
292  g_hash_table_destroy (valid.object_table);
293  qof_error_set_be (params->be, params->err_nomap);
294  return FALSE;
295 }
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:73
void qsf_object_validation_handler(xmlNodePtr child, xmlNsPtr ns, QsfValidator *valid)
Checks all incoming objects for QOF registration.
Definition: qsf-xml.c:133
Validation metadata.
Definition: qsf-xml.h:558
void qsf_valid_foreach(xmlNodePtr parent, QsfValidCB cb, struct QsfNodeIterate *qsfiter, QsfValidator *valid)
Definition: qsf-xml.c:101
QsfType file_type
Definition: qsf-xml.h:472
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
QofBackend * be
Definition: qsf-xml.h:519
One iterator, two typedefs.
Definition: qsf-xml.h:689
gint qof_registered_count
Definition: qsf-xml.h:578
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
gchar * filepath
Definition: qsf-xml.h:533
GHashTable * object_table
Definition: qsf-xml.h:565
gboolean is_qsf_map ( const gchar *  path)

Validate a QSF map file.

Parameters
pathAbsolute 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 370 of file qsf-xml-map.c.

371 {
372  xmlDocPtr doc;
373  struct QsfNodeIterate qsfiter;
374  QsfValidator valid;
375  xmlNodePtr map_root;
376  xmlNsPtr map_ns;
377 
378  g_return_val_if_fail ((path != NULL), FALSE);
379  if (path == NULL)
380  {
381  return FALSE;
382  }
383  doc = xmlParseFile (path);
384  if (doc == NULL)
385  {
386  return FALSE;
387  }
388  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
389  {
390  return FALSE;
391  }
392  map_root = xmlDocGetRootElement (doc);
393  map_ns = map_root->ns;
394  qsfiter.ns = map_ns;
395  valid.error_state = QOF_SUCCESS;
396  valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
397  qsf_valid_foreach (map_root, qsf_map_validation_handler,
398  &qsfiter, &valid);
399  if (valid.error_state != QOF_SUCCESS)
400  {
401  g_hash_table_destroy (valid.map_table);
402  return FALSE;
403  }
404  g_hash_table_destroy (valid.map_table);
405  return TRUE;
406 }
Validation metadata.
Definition: qsf-xml.h:558
void qsf_valid_foreach(xmlNodePtr parent, QsfValidCB cb, struct QsfNodeIterate *qsfiter, QsfValidator *valid)
Definition: qsf-xml.c:101
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
One iterator, two typedefs.
Definition: qsf-xml.h:689
#define QOF_SUCCESS
Definition: qoferror.h:124
#define QSF_MAP_SCHEMA
Definition: qsf-xml.h:423
gboolean is_qsf_map_be ( QsfParam params)

Validate a QSF map file.

Parameters
paramsPointer 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 318 of file qsf-xml-map.c.

319 {
320  xmlDocPtr doc;
321  struct QsfNodeIterate qsfiter;
322  QsfValidator valid;
323  xmlNodePtr map_root;
324  xmlNsPtr map_ns;
325  gchar *path;
326 
327  g_return_val_if_fail ((params != NULL), FALSE);
328  path = g_strdup (params->filepath);
329  if (path == NULL)
330  {
331  qof_error_set_be (params->be, qof_error_register
332  (_("The QSF XML file '%s' could not be found."), TRUE));
333  return FALSE;
334  }
335  doc = xmlParseFile (path);
336  if (doc == NULL)
337  {
338  qof_error_set_be (params->be, qof_error_register
339  (_("There was an error parsing the file '%s'."), TRUE));
340  return FALSE;
341  }
342  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc))
343  {
344  qof_error_set_be (params->be,
346  _("Invalid QSF Map file! The QSF map file "
347  "failed to validate against the QSF map schema. "
348  "The XML structure of the file is either not well-formed "
349  "or the file contains illegal data."), FALSE));
350  return FALSE;
351  }
352  map_root = xmlDocGetRootElement (doc);
353  map_ns = map_root->ns;
354  qsfiter.ns = map_ns;
355  valid.object_table = g_hash_table_new (g_str_hash, g_str_equal);
356  valid.map_table = g_hash_table_new (g_str_hash, g_str_equal);
357  valid.error_state = QOF_SUCCESS;
358  qsf_valid_foreach (map_root, qsf_map_validation_handler,
359  &qsfiter, &valid);
360  if (valid.error_state != QOF_SUCCESS)
361  {
362  g_hash_table_destroy (valid.object_table);
363  return FALSE;
364  }
365  g_hash_table_destroy (valid.object_table);
366  return TRUE;
367 }
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:73
Validation metadata.
Definition: qsf-xml.h:558
void qsf_valid_foreach(xmlNodePtr parent, QsfValidCB cb, struct QsfNodeIterate *qsfiter, QsfValidator *valid)
Definition: qsf-xml.c:101
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
QofBackend * be
Definition: qsf-xml.h:519
One iterator, two typedefs.
Definition: qsf-xml.h:689
#define QOF_SUCCESS
Definition: qoferror.h:124
gchar * filepath
Definition: qsf-xml.h:533
#define QSF_MAP_SCHEMA
Definition: qsf-xml.h:423
gboolean is_qsf_object ( const gchar *  path)

Validate a QSF file and identify a suitable QSF map.

Parameters
pathAbsolute 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 218 of file qsf-xml.c.

219 {
220  xmlDocPtr doc;
221 
222  g_return_val_if_fail ((path != NULL), FALSE);
223  if (path == NULL)
224  {
225  return FALSE;
226  }
227  doc = xmlParseFile (path);
228  if (doc == NULL)
229  {
230  return FALSE;
231  }
232  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
233  {
234  return FALSE;
235  }
236  /* Note cannot test against a map here, so if the file is valid QSF,
237  accept it and work out the details later. */
238  return TRUE;
239 }
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
gboolean is_qsf_object_be ( QsfParam params)

Validate a QSF file and identify a suitable QSF map.

Parameters
paramsPointer 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 298 of file qsf-xml.c.

299 {
300  gboolean result;
301  xmlDocPtr doc;
302  GList *maps;
303  gchar *path;
304 
305  g_return_val_if_fail ((params != NULL), FALSE);
306  path = g_strdup (params->filepath);
307  if (path == NULL)
308  {
309  qof_error_set_be (params->be, qof_error_register
310  (_("The QSF XML file '%s' could not be found."), TRUE));
311  return FALSE;
312  }
313  /* skip validation if is_our_qsf_object has already been called. */
314 /* if (ERR_QSF_INVALID_OBJ == qof_backend_get_error (params->be))
315  {
316  return FALSE;
317  }*/
318  if (params->file_type == QSF_UNDEF)
319  {
320  doc = xmlParseFile (path);
321  if (doc == NULL)
322  {
323  qof_error_set_be (params->be, qof_error_register
324  (_("There was an error parsing the file '%s'."), TRUE));
325  return FALSE;
326  }
327  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
328  {
329  qof_error_set_be (params->be, qof_error_register
330  (_("Invalid QSF Object file! The QSF object file '%s' "
331  " failed to validate against the QSF object schema. "
332  "The XML structure of the file is either not well-formed "
333  "or the file contains illegal data."), TRUE));
334  return FALSE;
335  }
336  }
337  result = FALSE;
338  /* retrieve list of maps from config frame. */
339  for (maps = params->map_files; maps; maps = maps->next)
340  {
341  QofErrorId err;
342  result = is_qsf_object_with_map_be (maps->data, params);
343  err = qof_error_check_be (params->be);
344  if ((err == QOF_SUCCESS) && result)
345  {
346  params->map_path = maps->data;
347  PINFO ("map chosen = %s", params->map_path);
348  break;
349  }
350  }
351  return result;
352 }
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:73
#define PINFO(format, args...)
Definition: qoflog.h:199
QsfType file_type
Definition: qsf-xml.h:472
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
gint32 QofErrorId
The ID of this error.
Definition: qofbackend.h:54
QofBackend * be
Definition: qsf-xml.h:519
QofErrorId qof_error_check_be(QofBackend *be)
Check for errors.
Definition: qoferror.c:204
gchar * map_path
Definition: qsf-xml.h:535
#define QOF_SUCCESS
Definition: qoferror.h:124
gboolean is_qsf_object_with_map_be(gchar *map_path, QsfParam *params)
Validate a QSF file and a selected QSF map.
Definition: qsf-xml-map.c:238
GList * map_files
Definition: qsf-xml.h:545
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
gchar * filepath
Definition: qsf-xml.h:533
gboolean is_qsf_object_with_map ( const gchar *  path,
gchar *  map_file 
)

Validate a QSF file and a selected QSF map.

Parameters
pathAbsolute or relative path to the selected QSF object file
map_fileName 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.

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

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

289 {
290  xmlDocPtr doc, map_doc;
291  QofErrorId result;
292  gchar *map_path;
293 
294  map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
295  if (path == NULL)
296  {
297  return FALSE;
298  }
299  doc = xmlParseFile (path);
300  if (doc == NULL)
301  {
302  return FALSE;
303  }
304  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
305  {
306  return FALSE;
307  }
308  if (map_path == NULL)
309  {
310  return FALSE;
311  }
312  map_doc = xmlParseFile (map_path);
313  result = check_qsf_object_with_map_internal (map_doc, doc);
314  return (result == QOF_SUCCESS) ? TRUE : FALSE;
315 }
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
gint32 QofErrorId
The ID of this error.
Definition: qofbackend.h:54
#define QOF_SUCCESS
Definition: qoferror.h:124
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
gboolean is_qsf_object_with_map_be ( gchar *  map_path,
QsfParam params 
)

Validate a QSF file and a selected QSF map.

Parameters
map_pathAbsolute or relative path to the selected QSF map file
paramsPointer 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.

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

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

239 {
240  xmlDocPtr doc, map_doc;
241  QofErrorId result;
242  gchar *path, *map_path;
243 
244  g_return_val_if_fail ((params != NULL), FALSE);
245  path = g_strdup (params->filepath);
246  map_path = g_strdup_printf ("%s/%s", QSF_SCHEMA_DIR, map_file);
247  PINFO (" checking map file '%s'", map_path);
248  if (path == NULL)
249  {
250  qof_error_set_be (params->be, qof_error_register
251  (_("The QSF XML file '%s' could not be found."), TRUE));
252  return FALSE;
253  }
254  doc = xmlParseFile (path);
255  if (doc == NULL)
256  {
257  qof_error_set_be (params->be, qof_error_register
258  (_("There was an error parsing the file '%s'."), TRUE));
259  return FALSE;
260  }
261  if (TRUE != qsf_is_valid (QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
262  {
263  qof_error_set_be (params->be, qof_error_register
264  (_("Invalid QSF Object file! The QSF object file '%s' "
265  " failed to validate against the QSF object schema. "
266  "The XML structure of the file is either not well-formed "
267  "or the file contains illegal data."), TRUE));
268  return FALSE;
269  }
270  if (map_path == NULL)
271  {
272  qof_error_set_be (params->be, qof_error_register
273  (_("The QSF map file '%s' could not be found."), TRUE));
274  return FALSE;
275  }
276  map_doc = xmlParseFile (map_path);
277  if (map_doc == NULL)
278  {
279  qof_error_set_be (params->be, qof_error_register
280  (_("There was an error parsing the file '%s'."), TRUE));
281  return FALSE;
282  }
283  result = check_qsf_object_with_map_internal (map_doc, doc);
284  return (result == QOF_SUCCESS) ? TRUE : FALSE;
285 }
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:73
#define PINFO(format, args...)
Definition: qoflog.h:199
gboolean qsf_is_valid(const gchar *schema_dir, const gchar *schema_filename, xmlDocPtr doc)
Compares an xmlDoc in memory against the schema file.
Definition: qsf-xml.c:74
gint32 QofErrorId
The ID of this error.
Definition: qofbackend.h:54
QofBackend * be
Definition: qsf-xml.h:519
#define QOF_SUCCESS
Definition: qoferror.h:124
#define QSF_OBJECT_SCHEMA
Definition: qsf-xml.h:420
gchar * filepath
Definition: qsf-xml.h:533
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 423 of file qsf-xml.c.

424 {
425  gchar *book_count_s, *tail;
426  gint book_count;
427  xmlNodePtr child_node;
428  struct QsfNodeIterate qsfiter;
429  gchar *buffer;
430  GUID book_guid;
431 
432  g_return_if_fail (child);
433  g_return_if_fail (params);
434  ENTER (" child=%s", child->name);
435  if (qsf_is_element (child, ns, QSF_BOOK_TAG))
436  {
437  book_count_s =
438  (gchar *) xmlGetProp (child, BAD_CAST QSF_BOOK_COUNT);
439  if (book_count_s)
440  {
441  book_count = (gint) strtol (book_count_s, &tail, 0);
442  /* More than one book not currently supported. */
443  g_free (book_count_s);
444  g_return_if_fail (book_count == 1);
445  }
446  qsfiter.ns = ns;
447  child_node = child->children->next;
448  if (qsf_is_element (child_node, ns, QSF_BOOK_GUID))
449  {
450  DEBUG (" trying to set book GUID");
451  buffer = (gchar*) xmlNodeGetContent (child_node);
452  g_return_if_fail (TRUE == string_to_guid (buffer, &book_guid));
453  qof_entity_set_guid ((QofEntity *) params->book, &book_guid);
454  xmlNewChild (params->output_node, params->qsf_ns,
455  BAD_CAST QSF_BOOK_GUID, BAD_CAST buffer);
456  xmlFree (buffer);
457  }
458  qsf_node_foreach (child, qsf_object_node_handler, &qsfiter, params);
459  }
460  LEAVE (" ");
461 }
xmlNsPtr qsf_ns
Definition: qsf-xml.h:507
gboolean string_to_guid(const gchar *string, GUID *guid)
#define QSF_BOOK_COUNT
Definition: qsf-xml.h:99
#define LEAVE(format, args...)
Definition: qoflog.h:227
One iterator, two typedefs.
Definition: qsf-xml.h:689
#define QSF_BOOK_TAG
Definition: qsf-xml.h:94
void qsf_node_foreach(xmlNodePtr parent, QsfNodeCB cb, struct QsfNodeIterate *qsfiter, QsfParam *params)
Definition: qsf-xml.c:115
#define DEBUG(format, args...)
Definition: qoflog.h:208
QofBook * book
Definition: qsf-xml.h:529
Definition: guid.h:53
gint qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
shorthand function
Definition: qsf-xml.c:54
xmlNodePtr output_node
Definition: qsf-xml.h:499
void qof_entity_set_guid(QofEntity *ent, const GUID *guid)
Definition: qofid.c:92
#define ENTER(format, args...)
Definition: qoflog.h:217
void qsf_object_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, QsfParam *params)
Definition: qsf-xml.c:384
#define QSF_BOOK_GUID
Definition: qsf-xml.h:97
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.

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

69 {
70  return qsf_is_element (params->child_node, params->qsf_ns, qof_type);
71 }
xmlNsPtr qsf_ns
Definition: qsf-xml.h:507
xmlNodePtr child_node
Definition: qsf-xml.h:493
gint qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
shorthand function
Definition: qsf-xml.c:54
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 38 of file qsf-xml.c.

39 {
40  return xmlStrcmp (node_name, (const xmlChar *) tag_name);
41 }
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 54 of file qsf-xml.c.

55 {
56  g_return_val_if_fail (a != NULL, 0);
57  g_return_val_if_fail (ns != NULL, 0);
58  g_return_val_if_fail (c != NULL, 0);
59  if ((a->ns == ns) && (a->type == XML_ELEMENT_NODE) &&
60  qsf_strings_equal (a->name, c))
61  {
62  return 1;
63  }
64  return 0;
65 }
gint qsf_strings_equal(const xmlChar *node_name, gchar *tag_name)
shorthand function
Definition: qsf-xml.c:44
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_dirset at compile time to $prefix/share/qsf/
schema_filenameEither the QSF Object Schema or the QSF Map Schema.
docThe 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 74 of file qsf-xml.c.

76 {
77  xmlSchemaParserCtxtPtr qsf_schema_file;
78  xmlSchemaPtr qsf_schema;
79  xmlSchemaValidCtxtPtr qsf_context;
80  gchar *schema_path;
81  gint result;
82 
83  g_return_val_if_fail (doc || schema_filename, FALSE);
84  schema_path = g_strdup_printf ("%s/%s", schema_dir, schema_filename);
85  qsf_schema_file = xmlSchemaNewParserCtxt (schema_path);
86  qsf_schema = xmlSchemaParse (qsf_schema_file);
87  qsf_context = xmlSchemaNewValidCtxt (qsf_schema);
88  result = xmlSchemaValidateDoc (qsf_context, doc);
89  xmlSchemaFreeParserCtxt (qsf_schema_file);
90  xmlSchemaFreeValidCtxt (qsf_context);
91  xmlSchemaFree (qsf_schema);
92  g_free (schema_path);
93  if (result == 0)
94  {
95  return TRUE;
96  }
97  return FALSE;
98 }
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.

Todo:
Automate this once map support is stable

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

168 {
169  /* Add new map filenames here. */
171  *maps = g_list_prepend (*maps, "pilot-qsf-GnuCashInvoice.xml");
172  *maps = g_list_prepend (*maps, "pilot-qsf-gncCustomer.xml");
173  return maps;
174 }
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.

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

117 {
118  xmlNodePtr cur_node;
119 
120  if (!parent)
121  return;
122  g_return_if_fail (params);
123  g_return_if_fail (qsfiter->ns);
124  qsfiter->fcn = &cb;
125  for (cur_node = parent->children; cur_node != NULL;
126  cur_node = cur_node->next)
127  {
128  cb (cur_node, qsfiter->ns, params);
129  }
130 }
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.

Parameters
mapDocThe map document, parsed by libxml2.
qsf_rootThe top node of the QSF object to be converted using the map.
paramsThe 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 952 of file qsf-xml-map.c.

954 {
955  /* mapDoc : map document. qsf_root: incoming QSF root node. */
956  struct QsfNodeIterate qsfiter;
957  xmlDocPtr output_doc;
958  xmlNode *cur_node;
959  xmlNode *map_root, *output_root;
960 
961  g_return_val_if_fail ((mapDoc && qsf_root && params), NULL);
962  ENTER (" root=%s", qsf_root->name);
963  /* prepare the intermediary document */
964  qsfiter.ns = params->qsf_ns;
965  output_doc = xmlNewDoc (BAD_CAST QSF_XML_VERSION);
966  output_root = xmlNewNode (NULL, BAD_CAST QSF_ROOT_TAG);
967  xmlDocSetRootElement (output_doc, output_root);
968  xmlSetNs (output_root, params->qsf_ns);
969  params->output_node = xmlNewChild (output_root, params->qsf_ns,
970  BAD_CAST QSF_BOOK_TAG, NULL);
971  xmlNewProp (params->output_node, BAD_CAST QSF_BOOK_COUNT,
972  BAD_CAST "1");
973  /* parse the incoming QSF */
974  qsf_book_node_handler (qsf_root->children->next, params->qsf_ns,
975  params);
976  /* parse the map and calculate the values */
977  map_root = xmlDocGetRootElement (mapDoc);
978  params->foreach_limit = 0;
979  qsfiter.ns = params->map_ns;
980  /* sets qof_foreach iterator, defines and defaults. */
981  qsf_node_foreach (map_root, qsf_map_top_node_handler, &qsfiter, params);
982  /* identify the entities of iterator type. */
983  qsfiter.ns = params->qsf_ns;
984  qsf_node_foreach (qsf_root->children->next, iterator_cb, &qsfiter,
985  params);
986  PINFO (" counted %d records", params->foreach_limit);
987  params->count = 0;
988  for (cur_node = map_root->children; cur_node != NULL;
989  cur_node = cur_node->next)
990  {
991  params->convert_node = cur_node;
992  if (qsf_is_element (cur_node, params->map_ns, MAP_OBJECT_TAG))
993  {
994  gint i;
995 
996  params->lister = NULL;
997  PINFO (" found an object tag. starting calculation");
998  /* cur_node describes the target object */
999  if (!qof_class_is_registered ((gchar*)
1000  xmlGetProp (cur_node, BAD_CAST MAP_TYPE_ATTR)))
1001  {
1002  continue;
1003  }
1004  qsf_add_object_tag (params, params->count);
1005  params->count++;
1006  qsfiter.ns = params->map_ns;
1007  PINFO (" params->foreach_limit=%d", params->foreach_limit);
1008  for (i = -1; i < params->foreach_limit; i++)
1009  {
1010  qsf_node_foreach (cur_node, qsf_map_object_handler,
1011  &qsfiter, params);
1012  params->qsf_object_list =
1013  g_list_next (params->qsf_object_list);
1014  params->count++;
1015  }
1016  }
1017  }
1018  params->file_type = OUR_QSF_OBJ;
1019  /* use for debugging */
1020  xmlSaveFormatFileEnc ("-", output_doc, "UTF-8", 1);
1021  LEAVE (" ");
1022  return output_doc;
1023 }
xmlNsPtr qsf_ns
Definition: qsf-xml.h:507
#define PINFO(format, args...)
Definition: qoflog.h:199
gboolean qof_class_is_registered(QofIdTypeConst obj_name)
Definition: qofclass.c:133
#define QSF_ROOT_TAG
Definition: qsf-xml.h:81
gint count
Definition: qsf-xml.h:476
QsfType file_type
Definition: qsf-xml.h:472
#define MAP_TYPE_ATTR
Definition: qsf-xml.h:279
gint foreach_limit
Definition: qsf-xml.h:515
#define QSF_BOOK_COUNT
Definition: qsf-xml.h:99
#define LEAVE(format, args...)
Definition: qoflog.h:227
One iterator, two typedefs.
Definition: qsf-xml.h:689
#define QSF_BOOK_TAG
Definition: qsf-xml.h:94
GList * qsf_object_list
Definition: qsf-xml.h:478
xmlNodePtr convert_node
Definition: qsf-xml.h:495
void qsf_node_foreach(xmlNodePtr parent, QsfNodeCB cb, struct QsfNodeIterate *qsfiter, QsfParam *params)
Definition: qsf-xml.c:115
xmlNodePtr lister
Definition: qsf-xml.h:505
gint qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
shorthand function
Definition: qsf-xml.c:54
xmlNodePtr output_node
Definition: qsf-xml.h:499
void qsf_book_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, QsfParam *params)
Book and book-guid node handler.
Definition: qsf-xml.c:423
#define MAP_OBJECT_TAG
Definition: qsf-xml.h:240
#define ENTER(format, args...)
Definition: qoflog.h:217
#define QSF_XML_VERSION
Definition: qsf-xml.h:107
void qsf_object_node_handler ( xmlNodePtr  child,
xmlNsPtr  qsf_ns,
QsfParam 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 384 of file qsf-xml.c.

386 {
387  struct QsfNodeIterate qsfiter;
388  QsfObject *object_set;
389  gchar *tail, *object_count_s;
390  gint64 c;
391 
392  g_return_if_fail (child != NULL);
393  g_return_if_fail (qsf_ns != NULL);
394  params->qsf_ns = qsf_ns;
395  if (qsf_is_element (child, qsf_ns, QSF_OBJECT_TAG))
396  {
397  params->qsf_parameter_hash = NULL;
398  c = 0;
399  object_set = g_new (QsfObject, 1);
400  params->object_set = object_set;
401  object_set->object_count = 0;
402  object_set->parameters =
403  g_hash_table_new (g_str_hash, g_str_equal);
404  object_set->object_type = ((gchar *) xmlGetProp (child,
405  BAD_CAST QSF_OBJECT_TYPE));
406  object_count_s = ((gchar *) xmlGetProp (child,
407  BAD_CAST QSF_OBJECT_COUNT));
408  if (object_count_s)
409  {
410  c = (gint64) strtol (object_count_s, &tail, 0);
411  object_set->object_count = (gint) c;
412  g_free (object_count_s);
413  }
414  params->qsf_object_list =
415  g_list_prepend (params->qsf_object_list, object_set);
416  qsfiter.ns = qsf_ns;
417  params->qsf_parameter_hash = object_set->parameters;
418  qsf_node_foreach (child, qsf_parameter_handler, &qsfiter, params);
419  }
420 }
xmlNsPtr qsf_ns
Definition: qsf-xml.h:507
#define QSF_OBJECT_COUNT
Definition: qsf-xml.h:105
#define QSF_OBJECT_TAG
Definition: qsf-xml.h:101
#define QSF_OBJECT_TYPE
Definition: qsf-xml.h:103
One iterator, two typedefs.
Definition: qsf-xml.h:689
GList * qsf_object_list
Definition: qsf-xml.h:478
void qsf_node_foreach(xmlNodePtr parent, QsfNodeCB cb, struct QsfNodeIterate *qsfiter, QsfParam *params)
Definition: qsf-xml.c:115
GHashTable * qsf_parameter_hash
Definition: qsf-xml.h:484
gint qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
shorthand function
Definition: qsf-xml.c:54
Holds a description of the QofObject.
Definition: qsf-xml.h:63
QsfObject * object_set
Definition: qsf-xml.h:474
void qsf_object_validation_handler ( xmlNodePtr  child,
xmlNsPtr  ns,
QsfValidator 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 133 of file qsf-xml.c.

135 {
136  xmlNodePtr cur_node;
137  xmlChar *object_declaration;
138  guint count;
139  QsfStatus type;
140  gboolean is_registered;
141 
142  count = 0;
143  type = QSF_NO_OBJECT;
144  is_registered = FALSE;
145  for (cur_node = child->children; cur_node != NULL;
146  cur_node = cur_node->next)
147  {
148  if (qsf_is_element (cur_node, ns, QSF_OBJECT_TAG))
149  {
150  object_declaration =
151  xmlGetProp (cur_node, BAD_CAST QSF_OBJECT_TYPE);
152  is_registered = qof_class_is_registered ((gchar*)object_declaration);
153  if (is_registered)
154  {
155  type = QSF_REGISTERED_OBJECT;
156  }
157  else
158  {
159  type = QSF_DEFINED_OBJECT;
160  }
161  xmlFree (object_declaration);
162  count = g_hash_table_size (valid->object_table);
163  g_hash_table_insert (valid->object_table, object_declaration,
164  GINT_TO_POINTER (type));
165  /* if insert was successful - i.e. object is unique so far */
166  if (g_hash_table_size (valid->object_table) > count)
167  {
168  valid->valid_object_count++;
169  if (is_registered)
170  {
171  valid->qof_registered_count++;
172  }
173  }
174  }
175  }
176 }
gboolean qof_class_is_registered(QofIdTypeConst obj_name)
Definition: qofclass.c:133
#define QSF_OBJECT_TAG
Definition: qsf-xml.h:101
#define QSF_OBJECT_TYPE
Definition: qsf-xml.h:103
gint qof_registered_count
Definition: qsf-xml.h:578
QsfStatus
Status of various object during mapping.
Definition: qsf-xml.h:446
gint valid_object_count
Definition: qsf-xml.h:572
gint qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
shorthand function
Definition: qsf-xml.c:54
GHashTable * object_table
Definition: qsf-xml.h:565
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 44 of file qsf-xml.c.

45 {
46  if (0 == qsf_compare_tag_strings (node_name, tag_name))
47  {
48  return 1;
49  }
50  return 0;
51 }
gint qsf_compare_tag_strings(const xmlChar *node_name, gchar *tag_name)
shorthand function
Definition: qsf-xml.c:38
void qsf_valid_foreach ( xmlNodePtr  parent,
QsfValidCB  cb,
struct QsfNodeIterate qsfiter,
QsfValidator 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.

103 {
104  xmlNodePtr cur_node;
105 
106  qsfiter->v_fcn = &cb;
107  for (cur_node = parent->children; cur_node != NULL;
108  cur_node = cur_node->next)
109  {
110  cb (cur_node, qsfiter->ns, valid);
111  }
112 }
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
contentA string representation of the value, ideally as output by kvp_value_to_string.
typeKvpValueType of the intended KvpValue
Returns
KvpValue* or NULL on failure.

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

1165 {
1166  gchar *tail;
1167  gint64 cm_i64;
1168  gdouble cm_double;
1169  QofNumeric cm_numeric;
1170  GUID *cm_guid;
1171 
1172  switch (type)
1173  {
1174  case KVP_TYPE_GINT64:
1175  {
1176  errno = 0;
1177  cm_i64 = strtoll (content, &tail, 0);
1178  if (errno == 0)
1179  {
1180  return kvp_value_new_gint64 (cm_i64);
1181  }
1182  break;
1183  }
1184  case KVP_TYPE_DOUBLE:
1185  {
1186  errno = 0;
1187  cm_double = strtod (content, &tail);
1188  if (errno == 0)
1189  return kvp_value_new_double (cm_double);
1190  break;
1191  }
1192  case KVP_TYPE_NUMERIC:
1193  {
1194  qof_numeric_from_string (content, &cm_numeric);
1195  return kvp_value_new_numeric (cm_numeric);
1196  break;
1197  }
1198  case KVP_TYPE_STRING:
1199  {
1200  return kvp_value_new_string (content);
1201  break;
1202  }
1203  case KVP_TYPE_GUID:
1204  {
1205  cm_guid = g_new0 (GUID, 1);
1206  if (TRUE == string_to_guid (content, cm_guid))
1207  return kvp_value_new_guid (cm_guid);
1208  break;
1209  }
1210  case KVP_TYPE_TIME :
1211  {
1212  QofDate *qd;
1213  QofTime *qt;
1214  KvpValue *retval;
1215 
1216  qd = qof_date_parse (content, QOF_DATE_FORMAT_UTC);
1217  if(qd)
1218  {
1219  qt = qof_date_to_qtime (qd);
1220  retval = kvp_value_new_time (qt);
1221  qof_date_free (qd);
1222  qof_time_free (qt);
1223  return retval;
1224  }
1225  else
1226  PERR (" failed to parse date");
1227  }
1228  case KVP_TYPE_BOOLEAN :
1229  {
1230  gboolean val;
1231  val = qof_util_bool_to_int (content);
1232  return kvp_value_new_boolean (val);
1233  }
1234  case KVP_TYPE_BINARY:
1235 // return kvp_value_new_binary(value->value.binary.data,
1236 // value->value.binary.datasize);
1237  break;
1238  case KVP_TYPE_GLIST:
1239 // return kvp_value_new_glist(value->value.list);
1240  break;
1241  case KVP_TYPE_FRAME:
1242 // return kvp_value_new_frame(value->value.frame);
1243  break;
1244  }
1245  return NULL;
1246 }
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
#define PERR(format, args...)
Definition: qoflog.h:183
void qof_date_free(QofDate *date)
Definition: qofdate.c:642
gboolean string_to_guid(const gchar *string, GUID *guid)
Unique identifier.
Definition: kvpframe.h:118
KvpValue * kvp_value_new_boolean(gboolean value)
Definition: kvpframe.c:1223
gint qof_util_bool_to_int(const gchar *val)
Definition: qofutil.c:252
QofTime * qof_date_to_qtime(const QofDate *qd)
Definition: qofdate.c:926
Full range replacement for struct tm.
Definition: qofdate.h:138
128bit denominator/numerator maths.
Definition: kvpframe.h:106
QofDate * qof_date_parse(const gchar *str, QofDateFormat df)
Convert a timestamp to a QofTime.
Definition: qofdate.c:557
struct _KvpValue KvpValue
Definition: kvpframe.h:78
gboolean qof_numeric_from_string(const gchar *str, QofNumeric *n)
Definition: qofnumeric.c:1116
void qof_time_free(QofTime *qt)
Free a QofTime when no longer required.
Definition: qoftime.c:56
64bit integer
Definition: kvpframe.h:94
Definition: guid.h:53
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
Simple boolean type.
Definition: kvpframe.h:136
standard C string
Definition: kvpframe.h:112
standard C double type
Definition: kvpframe.h:100
64bit time/date handling.
Definition: kvpframe.h:124