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

Generated on Fri May 12 17:57:20 2006 for QOF by  doxygen 1.4.4