qofobject.c

00001 /********************************************************************\
00002  * qofobject.c -- the Core Object Registration/Lookup Interface     *
00003  * This program is free software; you can redistribute it and/or    *
00004  * modify it under the terms of the GNU General Public License as   *
00005  * published by the Free Software Foundation; either version 2 of   *
00006  * the License, or (at your option) any later version.              *
00007  *                                                                  *
00008  * This program is distributed in the hope that it will be useful,  *
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00011  * GNU General Public License for more details.                     *
00012  *                                                                  *
00013  * You should have received a copy of the GNU General Public License*
00014  * along with this program; if not, contact:                        *
00015  *                                                                  *
00016  * Free Software Foundation           Voice:  +1-617-542-5942       *
00017  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00018  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00019  *                                                                  *
00020 \********************************************************************/
00021 /*
00022  * qofobject.c -- the Core Object Object Registry
00023  * Copyright (C) 2001 Derek Atkins
00024  * Author: Derek Atkins <warlord@MIT.EDU>
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     /* Remember this book for later */
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     /* Remove it from the list */
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 /* INITIALIZATION and PRIVATE FUNCTIONS */
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 /* Register new types of object objects.
00273  * Return TRUE if successful,
00274  * return FALSE if it fails, invalid arguments, or if the object
00275  * already exists
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     /* Now initialize all the known books */
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     /* If it doesn't already exist, create a new table for this backend */
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     /* Now insert the data */
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     /* Call the callback for this data type */
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 /* ========================= END OF FILE =================== */

Generated on Thu Jan 31 22:50:26 2008 for QOF by  doxygen 1.5.4