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  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00018  * Boston, MA  02111-1307,  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 "gnc-trace.h"
00032 #include "gnc-engine-util.h"
00033 #include "qofobject.h"
00034 #include "qofobject-p.h"
00035 #include "qofbook.h"
00036 
00037 static QofLogModule log_module = QOF_MOD_OBJECT;
00038 
00039 static gboolean object_is_initialized = FALSE;
00040 static GList *object_modules = NULL;
00041 static GList *book_list = NULL;
00042 static GHashTable *backend_data = NULL;
00043 
00044 gpointer
00045 qof_object_new_instance (QofIdTypeConst type_name, QofBook *book)
00046 {
00047   const QofObject *obj;
00048 
00049   if (!type_name) return NULL;
00050 
00051   obj = qof_object_lookup (type_name);
00052   if (!obj) return NULL;
00053 
00054   if (obj->create) 
00055     return (obj->create (book));
00056 
00057   return NULL;
00058 }
00059 
00060 void qof_object_book_begin (QofBook *book)
00061 {
00062   GList *l;
00063 
00064   if (!book) return;
00065   ENTER (" ");
00066   for (l = object_modules; l; l = l->next) {
00067     QofObject *obj = l->data;
00068     if (obj->book_begin)
00069       obj->book_begin (book);
00070   }
00071 
00072   /* Remember this book for later */
00073   book_list = g_list_prepend (book_list, book);
00074   LEAVE (" ");
00075 }
00076 
00077 void qof_object_book_end (QofBook *book)
00078 {
00079   GList *l;
00080 
00081   if (!book) return;
00082   ENTER (" ");
00083   for (l = object_modules; l; l = l->next) {
00084     QofObject *obj = l->data;
00085     if (obj->book_end)
00086       obj->book_end (book);
00087   }
00088 
00089   /* Remove it from the list */
00090   book_list = g_list_remove (book_list, book);
00091   LEAVE (" ");
00092 }
00093 
00094 gboolean 
00095 qof_object_is_dirty (QofBook *book)
00096 {
00097   GList *l;
00098 
00099   if (!book) return FALSE;
00100   for (l = object_modules; l; l = l->next) 
00101   {
00102     QofObject *obj = l->data;
00103     if (obj->is_dirty)
00104     {
00105       QofCollection *col;
00106       col = qof_book_get_collection (book, obj->e_type);
00107       if (obj->is_dirty (col)) return TRUE;
00108     }
00109   }
00110   return FALSE;
00111 }
00112 
00113 void 
00114 qof_object_mark_clean (QofBook *book)
00115 {
00116   GList *l;
00117 
00118   if (!book) return;
00119   for (l = object_modules; l; l = l->next) 
00120   {
00121     QofObject *obj = l->data;
00122     if (obj->mark_clean)
00123     {
00124       QofCollection *col;
00125       col = qof_book_get_collection (book, obj->e_type);
00126       (obj->mark_clean) (col);
00127     }
00128   }
00129 }
00130 
00131 void qof_object_foreach_type (QofForeachTypeCB cb, gpointer user_data)
00132 {
00133   GList *l;
00134 
00135   if (!cb) return;
00136 
00137   for (l = object_modules; l; l = l->next) {
00138     QofObject *obj = l->data;
00139     (cb) (obj, user_data);
00140   }
00141 }
00142 
00143 void 
00144 qof_object_foreach (QofIdTypeConst type_name, QofBook *book, 
00145                     QofEntityForeachCB cb, gpointer user_data)
00146 {
00147   QofCollection *col;
00148   const QofObject *obj;
00149 
00150   if (!book || !type_name) return;
00151   ENTER ("type=%s", type_name);
00152 
00153   obj = qof_object_lookup (type_name);
00154   if (!obj)
00155   {
00156     PERR ("No object of type %s", type_name);
00157     return;
00158   }
00159   col = qof_book_get_collection (book, obj->e_type);
00160   PINFO ("lookup obj=%p for type=%s", obj, type_name);
00161   if (!obj) return;
00162 
00163   PINFO ("type=%s foreach=%p", type_name, obj->foreach);
00164   if (obj->foreach) 
00165   {
00166     obj->foreach (col, cb, user_data);
00167   }
00168   LEAVE ("type=%s", type_name);
00169 
00170   return;
00171 }
00172 
00173 const char *
00174 qof_object_printable (QofIdTypeConst type_name, gpointer obj)
00175 {
00176   const QofObject *b_obj;
00177 
00178   if (!type_name || !obj) return NULL;
00179 
00180   b_obj = qof_object_lookup (type_name);
00181   if (!b_obj) return NULL;
00182 
00183   if (b_obj->printable)
00184     return (b_obj->printable (obj));
00185 
00186   return NULL;
00187 }
00188 
00189 const char * qof_object_get_type_label (QofIdTypeConst type_name)
00190 {
00191   const QofObject *obj;
00192 
00193   if (!type_name) return NULL;
00194 
00195   obj = qof_object_lookup (type_name);
00196   if (!obj) return NULL;
00197 
00198   return (obj->type_label);
00199 }
00200 
00201 static gboolean clear_table (gpointer key, gpointer value, gpointer user_data)
00202 {
00203   g_hash_table_destroy (value);
00204   return TRUE;
00205 }
00206 
00207 /* INITIALIZATION and PRIVATE FUNCTIONS */
00208 
00209 void qof_object_initialize (void)
00210 {
00211   if (object_is_initialized) return;
00212   backend_data = g_hash_table_new (g_str_hash, g_str_equal);
00213   object_is_initialized = TRUE;
00214 }
00215 
00216 void qof_object_shutdown (void)
00217 {
00218   g_return_if_fail (object_is_initialized == TRUE);
00219 
00220   g_hash_table_foreach_remove (backend_data, clear_table, NULL);
00221   g_hash_table_destroy (backend_data);
00222   backend_data = NULL;
00223 
00224   g_list_free (object_modules);
00225   object_modules = NULL;
00226   g_list_free (book_list);
00227   book_list = NULL;
00228   object_is_initialized = FALSE;
00229 }
00230 
00231 /* Register new types of object objects.
00232  * Return TRUE if successful,
00233  * return FALSE if it fails, invalid arguments, or if the object
00234  * already exists
00235  */
00236 gboolean qof_object_register (const QofObject *object)
00237 {
00238   g_return_val_if_fail (object_is_initialized, FALSE);
00239 
00240   if (!object) return FALSE;
00241   g_return_val_if_fail (object->interface_version == QOF_OBJECT_VERSION, FALSE);
00242 
00243   if (g_list_index (object_modules, (gpointer)object) == -1)
00244     object_modules = g_list_prepend (object_modules, (gpointer)object);
00245   else
00246     return FALSE;
00247 
00248   /* Now initialize all the known books */
00249   if (object->book_begin && book_list) {
00250     GList *node;
00251     for (node = book_list; node; node = node->next)
00252       object->book_begin (node->data);
00253   }
00254 
00255   return TRUE;
00256 }
00257 
00258 const QofObject * qof_object_lookup (QofIdTypeConst name)
00259 {
00260   GList *iter;
00261   const QofObject *obj;
00262 
00263   g_return_val_if_fail (object_is_initialized, NULL);
00264 
00265   if (!name) return NULL;
00266 
00267   for (iter = object_modules; iter; iter = iter->next) {
00268     obj = iter->data;
00269     if (!safe_strcmp (obj->e_type, name))
00270       return obj;
00271   }
00272   return NULL;
00273 }
00274 
00275 gboolean qof_object_register_backend (QofIdTypeConst type_name,
00276                                    const char *backend_name,
00277                                    gpointer be_data)
00278 {
00279   GHashTable *ht;
00280   g_return_val_if_fail (object_is_initialized, FALSE);
00281 
00282   if (!type_name || *type_name == '\0' ||
00283       !backend_name || *backend_name == '\0' ||
00284       !be_data)
00285     return FALSE;
00286 
00287   ht = g_hash_table_lookup (backend_data, backend_name);
00288 
00289   /* If it doesn't already exist, create a new table for this backend */
00290   if (!ht) {
00291     ht = g_hash_table_new (g_str_hash, g_str_equal);
00292     g_hash_table_insert (backend_data, (char *)backend_name, ht);
00293   }
00294 
00295   /* Now insert the data */
00296   g_hash_table_insert (ht, (char *)type_name, be_data);
00297 
00298   return TRUE;
00299 }
00300 
00301 gpointer qof_object_lookup_backend (QofIdTypeConst type_name,
00302                                  const char *backend_name)
00303 {
00304   GHashTable *ht;
00305 
00306   if (!type_name || *type_name == '\0' ||
00307       !backend_name || *backend_name == '\0')
00308     return NULL;
00309 
00310   ht = g_hash_table_lookup (backend_data, (char *)backend_name);
00311   if (!ht)
00312     return NULL;
00313 
00314   return g_hash_table_lookup (ht, (char *)type_name);
00315 }
00316 
00317 struct foreach_data {
00318   QofForeachBackendTypeCB        cb;
00319   gpointer                 user_data;
00320 };
00321 
00322 static void foreach_backend (gpointer key, gpointer be_item, gpointer arg)
00323 {
00324   char *data_type = key;
00325   struct foreach_data *cb_data = arg;
00326 
00327   g_return_if_fail (key && be_item && arg);
00328 
00329   /* Call the callback for this data type */
00330   (cb_data->cb) (data_type, be_item, cb_data->user_data);
00331 }
00332 
00333 void qof_object_foreach_backend (const char *backend_name,
00334                                  QofForeachBackendTypeCB cb,
00335                                  gpointer user_data)
00336 {
00337   GHashTable *ht;
00338   struct foreach_data cb_data;
00339 
00340   if (!backend_name || *backend_name == '\0' || !cb)
00341     return;
00342 
00343   ht = g_hash_table_lookup (backend_data, (char *)backend_name);
00344   if (!ht)
00345     return;
00346 
00347   cb_data.cb = cb;
00348   cb_data.user_data = user_data;
00349 
00350   g_hash_table_foreach (ht, foreach_backend, &cb_data);
00351 }
00352 
00353 /* ========================= END OF FILE =================== */

Generated on Fri Oct 21 15:49:55 2005 for QOF by  doxygen 1.4.5