00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027
00028 #include <glib.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031
00032 #include "gnc-xml-helper.h"
00033 #include "sixtp.h"
00034 #include "sixtp-utils.h"
00035 #include "sixtp-parsers.h"
00036 #include "sixtp-utils.h"
00037 #include "sixtp-dom-parsers.h"
00038 #include "sixtp-dom-generators.h"
00039
00040 #include "gnc-xml.h"
00041 #include "io-gncxml-gen.h"
00042 #include "io-gncxml-v2.h"
00043
00044 #include "sixtp-dom-parsers.h"
00045 #include "AccountP.h"
00046 #include "Account.h"
00047
00048 static QofLogModule log_module = GNC_MOD_IO;
00049
00050 const gchar *account_version_string = "2.0.0";
00051
00052
00053 #define gnc_account_string "gnc:account"
00054 #define act_name_string "act:name"
00055 #define act_id_string "act:id"
00056 #define act_type_string "act:type"
00057 #define act_commodity_string "act:commodity"
00058 #define act_commodity_scu_string "act:commodity-scu"
00059 #define act_non_standard_scu_string "act:non-standard-scu"
00060 #define act_code_string "act:code"
00061 #define act_description_string "act:description"
00062 #define act_slots_string "act:slots"
00063 #define act_parent_string "act:parent"
00064 #define act_lots_string "act:lots"
00065
00066
00067 #define act_currency_string "act:currency"
00068 #define act_currency_scu_string "act:currency-scu"
00069 #define act_security_string "act:security"
00070 #define act_security_scu_string "act:security-scu"
00071
00072 xmlNodePtr
00073 gnc_account_dom_tree_create(Account *act,
00074 gboolean exporting,
00075 gboolean allow_incompat)
00076 {
00077 const char *str;
00078 kvp_frame *kf;
00079 xmlNodePtr ret;
00080 GList *lots, *n;
00081 Account *parent;
00082
00083 ENTER ("(account=%p)", act);
00084
00085 ret = xmlNewNode(NULL, BAD_CAST gnc_account_string);
00086 xmlSetProp(ret, BAD_CAST "version", BAD_CAST account_version_string);
00087
00088 xmlAddChild(ret, text_to_dom_tree(act_name_string,
00089 xaccAccountGetName(act)));
00090
00091 xmlAddChild(ret, guid_to_dom_tree(act_id_string, xaccAccountGetGUID(act)));
00092
00093 xmlAddChild(ret, text_to_dom_tree(
00094 act_type_string,
00095 xaccAccountTypeEnumAsString(xaccAccountGetType(act))));
00096
00097 xmlAddChild(ret, commodity_ref_to_dom_tree(act_commodity_string,
00098 xaccAccountGetCommodity(act)));
00099
00100 xmlAddChild(ret, int_to_dom_tree(act_commodity_scu_string,
00101 xaccAccountGetCommoditySCUi(act)));
00102
00103 if (xaccAccountGetNonStdSCU(act))
00104 xmlNewChild(ret, NULL, BAD_CAST act_non_standard_scu_string, NULL);
00105
00106 str = xaccAccountGetCode(act);
00107 if (str && strlen(str) > 0)
00108 {
00109 xmlAddChild(ret, text_to_dom_tree(act_code_string, str));
00110 }
00111
00112 str = xaccAccountGetDescription(act);
00113 if (str && strlen(str) > 0)
00114 {
00115 xmlAddChild(ret, text_to_dom_tree(act_description_string, str));
00116 }
00117
00118 kf = xaccAccountGetSlots(act);
00119 if(kf)
00120 {
00121 xmlNodePtr kvpnode = kvp_frame_to_dom_tree(act_slots_string, kf);
00122 if(kvpnode)
00123 {
00124 xmlAddChild(ret, kvpnode);
00125 }
00126 }
00127
00128 parent = gnc_account_get_parent(act);
00129 if (parent)
00130 {
00131 if (!gnc_account_is_root(parent) || allow_incompat)
00132 xmlAddChild(ret, guid_to_dom_tree(act_parent_string,
00133 xaccAccountGetGUID(parent)));
00134 }
00135
00136 lots = xaccAccountGetLotList (act);
00137 PINFO ("lot list=%p", lots);
00138 if (lots && !exporting)
00139 {
00140 xmlNodePtr toaddto = xmlNewChild(ret, NULL, BAD_CAST act_lots_string, NULL);
00141
00142 for (n = lots; n; n=n->next)
00143 {
00144 GNCLot * lot = n->data;
00145 xmlAddChild(toaddto, gnc_lot_dom_tree_create(lot));
00146 }
00147 }
00148 g_list_free(lots);
00149
00150 LEAVE("");
00151 return ret;
00152 }
00153
00154
00155
00156 struct account_pdata
00157 {
00158 Account *account;
00159 QofBook *book;
00160 };
00161
00162 static inline gboolean
00163 set_string(xmlNodePtr node, Account* act,
00164 void (*func)(Account *act, const gchar *txt))
00165 {
00166 gchar* txt = dom_tree_to_text(node);
00167 g_return_val_if_fail(txt, FALSE);
00168
00169 func(act, txt);
00170
00171 g_free(txt);
00172
00173 return TRUE;
00174 }
00175
00176 static gboolean
00177 account_name_handler (xmlNodePtr node, gpointer act_pdata)
00178 {
00179 struct account_pdata *pdata = act_pdata;
00180
00181 return set_string(node, pdata->account, xaccAccountSetName);
00182 }
00183
00184 static gboolean
00185 account_id_handler (xmlNodePtr node, gpointer act_pdata)
00186 {
00187 struct account_pdata *pdata = act_pdata;
00188 GUID *guid;
00189
00190 guid = dom_tree_to_guid(node);
00191 g_return_val_if_fail(guid, FALSE);
00192
00193 xaccAccountSetGUID(pdata->account, guid);
00194
00195 g_free(guid);
00196
00197 return TRUE;
00198 }
00199
00200 static gboolean
00201 account_type_handler (xmlNodePtr node, gpointer act_pdata)
00202 {
00203 struct account_pdata *pdata = act_pdata;
00204 GNCAccountType type = ACCT_TYPE_INVALID;
00205 char *string;
00206
00207 string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
00208 xaccAccountStringToType(string, &type);
00209 xmlFree (string);
00210
00211 xaccAccountSetType(pdata->account, type);
00212
00213 return TRUE;
00214 }
00215
00216 static gboolean
00217 account_commodity_handler (xmlNodePtr node, gpointer act_pdata)
00218 {
00219 struct account_pdata *pdata = act_pdata;
00220 gnc_commodity *ref;
00221
00222
00223 ref = dom_tree_to_commodity_ref(node, pdata->book);
00224 xaccAccountSetCommodity(pdata->account, ref);
00225
00226 return TRUE;
00227 }
00228
00229 static gboolean
00230 account_commodity_scu_handler (xmlNodePtr node, gpointer act_pdata)
00231 {
00232 struct account_pdata *pdata = act_pdata;
00233 gint64 val;
00234
00235 dom_tree_to_integer(node, &val);
00236 xaccAccountSetCommoditySCU(pdata->account, val);
00237
00238 return TRUE;
00239 }
00240
00241 static gboolean
00242 account_non_standard_scu_handler (xmlNodePtr node, gpointer act_pdata)
00243 {
00244 struct account_pdata *pdata = act_pdata;
00245
00246 xaccAccountSetNonStdSCU(pdata->account, TRUE);
00247
00248 return TRUE;
00249 }
00250
00251
00252
00253
00254
00255 static gboolean
00256 deprecated_account_currency_handler (xmlNodePtr node, gpointer act_pdata)
00257 {
00258 struct account_pdata *pdata = act_pdata;
00259 gnc_commodity *ref;
00260
00261 PWARN("Obsolete xml tag will not be preserved.");
00262 ref = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
00263 DxaccAccountSetCurrency(pdata->account, ref);
00264
00265 return TRUE;
00266 }
00267
00268 static gboolean
00269 deprecated_account_currency_scu_handler (xmlNodePtr node, gpointer act_pdata)
00270 {
00271 PWARN("Obsolete xml tag will not be preserved.");
00272 return TRUE;
00273 }
00274
00275 static gboolean
00276 deprecated_account_security_handler (xmlNodePtr node, gpointer act_pdata)
00277 {
00278 struct account_pdata *pdata = act_pdata;
00279 gnc_commodity *ref;
00280
00281 PWARN("Obsolete xml tag will not be preserved.");
00282 if (!xaccAccountGetCommodity(pdata->account)) {
00283 ref = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
00284 xaccAccountSetCommodity(pdata->account, ref);
00285 }
00286
00287 return TRUE;
00288 }
00289
00290 static gboolean
00291 deprecated_account_security_scu_handler (xmlNodePtr node, gpointer act_pdata)
00292 {
00293 struct account_pdata *pdata = act_pdata;
00294 gint64 val;
00295
00296 PWARN("Obsolete xml tag will not be preserved.");
00297 if (!xaccAccountGetCommoditySCU(pdata->account)) {
00298 dom_tree_to_integer(node, &val);
00299 xaccAccountSetCommoditySCU(pdata->account, val);
00300 }
00301
00302 return TRUE;
00303 }
00304
00305
00306
00307 static gboolean
00308 account_slots_handler (xmlNodePtr node, gpointer act_pdata)
00309 {
00310 struct account_pdata *pdata = act_pdata;
00311
00312 return dom_tree_to_kvp_frame_given
00313 (node, xaccAccountGetSlots (pdata->account));
00314 }
00315
00316 static gboolean
00317 account_parent_handler (xmlNodePtr node, gpointer act_pdata)
00318 {
00319 struct account_pdata *pdata = act_pdata;
00320 Account *parent;
00321 GUID *gid;
00322
00323 gid = dom_tree_to_guid(node);
00324 g_return_val_if_fail(gid, FALSE);
00325
00326 parent = xaccAccountLookup(gid, pdata->book);
00327 if (!parent)
00328 {
00329 g_free (gid);
00330 g_return_val_if_fail(parent, FALSE);
00331 }
00332
00333 gnc_account_append_child(parent, pdata->account);
00334
00335 g_free (gid);
00336
00337 return TRUE;
00338 }
00339
00340 static gboolean
00341 account_code_handler(xmlNodePtr node, gpointer act_pdata)
00342 {
00343 struct account_pdata *pdata = act_pdata;
00344
00345 return set_string(node, pdata->account, xaccAccountSetCode);
00346 }
00347
00348 static gboolean
00349 account_description_handler(xmlNodePtr node, gpointer act_pdata)
00350 {
00351 struct account_pdata *pdata = act_pdata;
00352
00353 return set_string(node, pdata->account, xaccAccountSetDescription);
00354 }
00355
00356 static gboolean
00357 account_lots_handler(xmlNodePtr node, gpointer act_pdata)
00358 {
00359 struct account_pdata *pdata = act_pdata;
00360 xmlNodePtr mark;
00361
00362 g_return_val_if_fail(node, FALSE);
00363 g_return_val_if_fail(node->xmlChildrenNode, FALSE);
00364
00365 for(mark = node->xmlChildrenNode; mark; mark = mark->next)
00366 {
00367 GNCLot *lot;
00368
00369 if(safe_strcmp("text", (char*) mark->name) == 0)
00370 continue;
00371
00372 lot = dom_tree_to_lot(mark, pdata->book);
00373
00374 if(lot)
00375 {
00376 xaccAccountInsertLot (pdata->account, lot);
00377 }
00378 else
00379 {
00380 return FALSE;
00381 }
00382 }
00383 return TRUE;
00384 }
00385
00386 static struct dom_tree_handler account_handlers_v2[] = {
00387 { act_name_string, account_name_handler, 1, 0 },
00388 { act_id_string, account_id_handler, 1, 0 },
00389 { act_type_string, account_type_handler, 1, 0 },
00390 { act_commodity_string, account_commodity_handler, 0, 0 },
00391 { act_commodity_scu_string, account_commodity_scu_handler, 0, 0 },
00392 { act_non_standard_scu_string, account_non_standard_scu_handler, 0, 0 },
00393 { act_code_string, account_code_handler, 0, 0 },
00394 { act_description_string, account_description_handler, 0, 0},
00395 { act_slots_string, account_slots_handler, 0, 0 },
00396 { act_parent_string, account_parent_handler, 0, 0 },
00397 { act_lots_string, account_lots_handler, 0, 0 },
00398
00399
00400
00401
00402 { act_currency_string, deprecated_account_currency_handler, 0, 0 },
00403 { act_currency_scu_string, deprecated_account_currency_scu_handler, 0, 0 },
00404 { act_security_string, deprecated_account_security_handler, 0, 0 },
00405 { act_security_scu_string, deprecated_account_security_scu_handler, 0, 0 },
00406 { NULL, 0, 0, 0 }
00407 };
00408
00409 static gboolean
00410 gnc_account_end_handler(gpointer data_for_children,
00411 GSList* data_from_children, GSList* sibling_data,
00412 gpointer parent_data, gpointer global_data,
00413 gpointer *result, const gchar *tag)
00414 {
00415 int successful;
00416 Account *acc, *parent, *root;
00417 xmlNodePtr tree = (xmlNodePtr)data_for_children;
00418 gxpf_data *gdata = (gxpf_data*)global_data;
00419 QofBook *book = gdata->bookdata;
00420 int type;
00421
00422 successful = TRUE;
00423
00424 if(parent_data)
00425 {
00426 return TRUE;
00427 }
00428
00429
00430
00431 if(!tag)
00432 {
00433 return TRUE;
00434 }
00435
00436 g_return_val_if_fail(tree, FALSE);
00437
00438 acc = dom_tree_to_account(tree, book);
00439 if(acc != NULL)
00440 {
00441 gdata->cb(tag, gdata->parsedata, acc);
00442
00443
00444
00445
00446
00447 xaccAccountBeginEdit(acc);
00448
00449
00450
00451
00452 parent = gnc_account_get_parent(acc);
00453 if (parent == NULL) {
00454 type = xaccAccountGetType(acc);
00455 if (type != ACCT_TYPE_ROOT) {
00456 root = gnc_book_get_root_account(book);
00457 if (root == NULL) {
00458 root = gnc_account_create_root(book);
00459 }
00460 gnc_account_append_child(root, acc);
00461 }
00462 }
00463 }
00464
00465 xmlFreeNode(tree);
00466
00467 return acc != NULL;
00468 }
00469
00470 Account*
00471 dom_tree_to_account (xmlNodePtr node, QofBook *book)
00472 {
00473 struct account_pdata act_pdata;
00474 Account *accToRet;
00475 gboolean successful;
00476
00477 accToRet = xaccMallocAccount(book);
00478 xaccAccountBeginEdit(accToRet);
00479
00480 act_pdata.account = accToRet;
00481 act_pdata.book = book;
00482
00483 successful = dom_tree_generic_parse (node, account_handlers_v2,
00484 &act_pdata);
00485 if (successful) {
00486 xaccAccountCommitEdit (accToRet);
00487 } else {
00488 PERR ("failed to parse account tree");
00489 xaccAccountDestroy (accToRet);
00490 accToRet = NULL;
00491 }
00492
00493 return accToRet;
00494 }
00495
00496 sixtp*
00497 gnc_account_sixtp_parser_create(void)
00498 {
00499 return sixtp_dom_parser_new(gnc_account_end_handler, NULL, NULL);
00500 }
00501
00502