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
00027 #include "config.h"
00028
00029 #include <glib.h>
00030
00031 #include "qof.h"
00032 #include "qofobject-p.h"
00033
00034 static QofLogModule log_module = QOF_MOD_OBJECT;
00035
00036 static gboolean object_is_initialized = FALSE;
00037 static GList *object_modules = NULL;
00038 static GList *book_list = NULL;
00039 static GHashTable *backend_data = NULL;
00040
00041 gpointer
00042 qof_object_new_instance (QofIdTypeConst type_name, QofBook * book)
00043 {
00044 const QofObject *obj;
00045
00046 if (!type_name)
00047 return NULL;
00048
00049 obj = qof_object_lookup (type_name);
00050 if (!obj)
00051 return NULL;
00052
00053 if (obj->create)
00054 return (obj->create (book));
00055
00056 return NULL;
00057 }
00058
00059 void
00060 qof_object_book_begin (QofBook * book)
00061 {
00062 GList *l;
00063
00064 if (!book)
00065 return;
00066 ENTER (" ");
00067 for (l = object_modules; l; l = l->next)
00068 {
00069 QofObject *obj = l->data;
00070 if (obj->book_begin)
00071 obj->book_begin (book);
00072 }
00073
00074
00075 book_list = g_list_prepend (book_list, book);
00076 LEAVE (" ");
00077 }
00078
00079 void
00080 qof_object_book_end (QofBook * book)
00081 {
00082 GList *l;
00083
00084 if (!book)
00085 return;
00086 ENTER (" ");
00087 for (l = object_modules; l; l = l->next)
00088 {
00089 QofObject *obj = l->data;
00090 if (obj->book_end)
00091 obj->book_end (book);
00092 }
00093
00094
00095 book_list = g_list_remove (book_list, book);
00096 LEAVE (" ");
00097 }
00098
00099 gboolean
00100 qof_object_is_dirty (QofBook * book)
00101 {
00102 GList *l;
00103
00104 if (!book)
00105 return FALSE;
00106 for (l = object_modules; l; l = l->next)
00107 {
00108 QofObject *obj = l->data;
00109 if (obj->is_dirty)
00110 {
00111 QofCollection *col;
00112 col = qof_book_get_collection (book, obj->e_type);
00113 if (obj->is_dirty (col))
00114 return TRUE;
00115 }
00116 }
00117 return FALSE;
00118 }
00119
00120 void
00121 qof_object_mark_clean (QofBook * book)
00122 {
00123 GList *l;
00124
00125 if (!book)
00126 return;
00127 for (l = object_modules; l; l = l->next)
00128 {
00129 QofObject *obj = l->data;
00130 if (obj->mark_clean)
00131 {
00132 QofCollection *col;
00133 col = qof_book_get_collection (book, obj->e_type);
00134 (obj->mark_clean) (col);
00135 }
00136 }
00137 }
00138
00139 void
00140 qof_object_foreach_type (QofForeachTypeCB cb, gpointer user_data)
00141 {
00142 GList *l;
00143
00144 if (!cb)
00145 return;
00146
00147 for (l = object_modules; l; l = l->next)
00148 {
00149 QofObject *obj = l->data;
00150 (cb) (obj, user_data);
00151 }
00152 }
00153
00154 gboolean
00155 qof_object_compliance (QofIdTypeConst type_name, gboolean warn)
00156 {
00157 const QofObject *obj;
00158
00159 obj = qof_object_lookup (type_name);
00160 if ((obj->create == NULL) || (obj->foreach == NULL))
00161 {
00162 if (warn)
00163 {
00164 PINFO (" Object type %s is not fully QOF compliant",
00165 obj->e_type);
00166 }
00167 return FALSE;
00168 }
00169 return TRUE;
00170 }
00171
00172
00173 void
00174 qof_object_foreach (QofIdTypeConst type_name, QofBook * book,
00175 QofEntityForeachCB cb, gpointer user_data)
00176 {
00177 QofCollection *col;
00178 const QofObject *obj;
00179
00180 if (!book || !type_name)
00181 {
00182 return;
00183 }
00184 PINFO ("type=%s", type_name);
00185
00186 obj = qof_object_lookup (type_name);
00187 if (!obj)
00188 {
00189 PERR ("No object of type %s", type_name);
00190 return;
00191 }
00192 col = qof_book_get_collection (book, obj->e_type);
00193 if (!obj)
00194 {
00195 return;
00196 }
00197 if (obj->foreach)
00198 {
00199 obj->foreach (col, cb, user_data);
00200 }
00201 return;
00202 }
00203
00204 const gchar *
00205 qof_object_printable (QofIdTypeConst type_name, gpointer obj)
00206 {
00207 const QofObject *b_obj;
00208
00209 if (!type_name || !obj)
00210 return NULL;
00211
00212 b_obj = qof_object_lookup (type_name);
00213 if (!b_obj)
00214 return NULL;
00215
00216 if (b_obj->printable)
00217 return (b_obj->printable (obj));
00218
00219 return NULL;
00220 }
00221
00222 const gchar *
00223 qof_object_get_type_label (QofIdTypeConst type_name)
00224 {
00225 const QofObject *obj;
00226
00227 if (!type_name)
00228 return NULL;
00229
00230 obj = qof_object_lookup (type_name);
00231 if (!obj)
00232 return NULL;
00233
00234 return (obj->type_label);
00235 }
00236
00237 static gboolean
00238 clear_table (gpointer key __attribute__ ((unused)), gpointer value,
00239 gpointer user_data __attribute__ ((unused)))
00240 {
00241 g_hash_table_destroy (value);
00242 return TRUE;
00243 }
00244
00245
00246
00247 void
00248 qof_object_initialize (void)
00249 {
00250 if (object_is_initialized)
00251 return;
00252 backend_data = g_hash_table_new (g_str_hash, g_str_equal);
00253 object_is_initialized = TRUE;
00254 }
00255
00256 void
00257 qof_object_shutdown (void)
00258 {
00259 g_return_if_fail (object_is_initialized == TRUE);
00260
00261 g_hash_table_foreach_remove (backend_data, clear_table, NULL);
00262 g_hash_table_destroy (backend_data);
00263 backend_data = NULL;
00264
00265 g_list_free (object_modules);
00266 object_modules = NULL;
00267 g_list_free (book_list);
00268 book_list = NULL;
00269 object_is_initialized = FALSE;
00270 }
00271
00272
00273
00274
00275
00276
00277 gboolean
00278 qof_object_register (const QofObject * object)
00279 {
00280 g_return_val_if_fail (object_is_initialized, FALSE);
00281
00282 if (!object)
00283 return FALSE;
00284 g_return_val_if_fail (object->interface_version == QOF_OBJECT_VERSION,
00285 FALSE);
00286
00287 if (g_list_index (object_modules, (gpointer) object) == -1)
00288 object_modules =
00289 g_list_prepend (object_modules, (gpointer) object);
00290 else
00291 return FALSE;
00292
00293
00294 if (object->book_begin && book_list)
00295 {
00296 GList *node;
00297 for (node = book_list; node; node = node->next)
00298 object->book_begin (node->data);
00299 }
00300
00301 return TRUE;
00302 }
00303
00304 const QofObject *
00305 qof_object_lookup (QofIdTypeConst name)
00306 {
00307 GList *qiter;
00308 const QofObject *obj;
00309
00310 g_return_val_if_fail (object_is_initialized, NULL);
00311
00312 if (!name)
00313 return NULL;
00314
00315 for (qiter = object_modules; qiter; qiter = qiter->next)
00316 {
00317 obj = qiter->data;
00318 if (!safe_strcmp (obj->e_type, name))
00319 return obj;
00320 }
00321 return NULL;
00322 }
00323
00324 gboolean
00325 qof_object_register_backend (QofIdTypeConst type_name,
00326 const gchar * backend_name, gpointer be_data)
00327 {
00328 GHashTable *ht;
00329 g_return_val_if_fail (object_is_initialized, FALSE);
00330
00331 if (!type_name || *type_name == '\0' ||
00332 !backend_name || *backend_name == '\0' || !be_data)
00333 return FALSE;
00334
00335 ht = g_hash_table_lookup (backend_data, backend_name);
00336
00337
00338 if (!ht)
00339 {
00340 ht = g_hash_table_new (g_str_hash, g_str_equal);
00341 g_hash_table_insert (backend_data, (gchar *) backend_name, ht);
00342 }
00343
00344
00345 g_hash_table_insert (ht, (gchar *) type_name, be_data);
00346
00347 return TRUE;
00348 }
00349
00350 gpointer
00351 qof_object_lookup_backend (QofIdTypeConst type_name,
00352 const gchar * backend_name)
00353 {
00354 GHashTable *ht;
00355
00356 if (!type_name || *type_name == '\0' ||
00357 !backend_name || *backend_name == '\0')
00358 return NULL;
00359
00360 ht = g_hash_table_lookup (backend_data, (gchar *) backend_name);
00361 if (!ht)
00362 return NULL;
00363
00364 return g_hash_table_lookup (ht, (gchar *) type_name);
00365 }
00366
00367 struct foreach_data
00368 {
00369 QofForeachBackendTypeCB cb;
00370 gpointer user_data;
00371 };
00372
00373 static void
00374 foreach_backend (gpointer key, gpointer be_item, gpointer arg)
00375 {
00376 gchar *data_type = key;
00377 struct foreach_data *cb_data = arg;
00378
00379 g_return_if_fail (key && be_item && arg);
00380
00381
00382 (cb_data->cb) (data_type, be_item, cb_data->user_data);
00383 }
00384
00385 void
00386 qof_object_foreach_backend (const gchar * backend_name,
00387 QofForeachBackendTypeCB cb, gpointer user_data)
00388 {
00389 GHashTable *ht;
00390 struct foreach_data cb_data;
00391
00392 if (!backend_name || *backend_name == '\0' || !cb)
00393 return;
00394
00395 ht = g_hash_table_lookup (backend_data, (gchar *) backend_name);
00396 if (!ht)
00397 return;
00398
00399 cb_data.cb = cb;
00400 cb_data.user_data = user_data;
00401
00402 g_hash_table_foreach (ht, foreach_backend, &cb_data);
00403 }
00404
00405