QOF
0.8.0
|
00001 /********************************************************************\ 00002 * qofclass.c -- provide QOF parameterized data objects * 00003 * Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> * 00004 * Copyright 2008 Neil Williams <linux@codehelp.co.uk> * 00005 * * 00006 * This program is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU General Public License as * 00008 * published by the Free Software Foundation; either version 2 of * 00009 * the License, or (at your option) any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License* 00017 * along with this program; if not, contact: * 00018 * * 00019 * Free Software Foundation Voice: +1-617-542-5942 * 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00021 * Boston, MA 02110-1301, USA gnu@gnu.org * 00022 * * 00023 \********************************************************************/ 00024 00025 #include "config.h" 00026 00027 #include <glib.h> 00028 00029 #include "qof.h" 00030 #include "qofclass-p.h" 00031 00032 static QofLogModule log_module = QOF_MOD_CLASS; 00033 00034 static GHashTable *classTable = NULL; 00035 static GHashTable *sortTable = NULL; 00036 static gboolean initialized = FALSE; 00037 00038 static gboolean 00039 clear_table (gpointer key __attribute__ ((unused)), gpointer value, 00040 gpointer user_data __attribute__ ((unused))) 00041 { 00042 g_hash_table_destroy (value); 00043 return TRUE; 00044 } 00045 00046 /* *******************************************************************/ 00047 /* PRIVATE FUNCTIONS */ 00048 00049 static gboolean 00050 check_init (void) 00051 { 00052 if (initialized) 00053 return TRUE; 00054 00055 PERR ("You must call qof_class_init() before using qof_class."); 00056 return FALSE; 00057 } 00058 00059 void 00060 qof_class_init (void) 00061 { 00062 if (initialized) 00063 return; 00064 initialized = TRUE; 00065 00066 classTable = g_hash_table_new (g_str_hash, g_str_equal); 00067 sortTable = g_hash_table_new (g_str_hash, g_str_equal); 00068 } 00069 00070 void 00071 qof_class_shutdown (void) 00072 { 00073 if (!initialized) 00074 return; 00075 initialized = FALSE; 00076 00077 g_hash_table_foreach_remove (classTable, clear_table, NULL); 00078 g_hash_table_destroy (classTable); 00079 g_hash_table_destroy (sortTable); 00080 } 00081 00082 QofSortFunc 00083 qof_class_get_default_sort (QofIdTypeConst obj_name) 00084 { 00085 if (!obj_name) 00086 return NULL; 00087 return g_hash_table_lookup (sortTable, obj_name); 00088 } 00089 00090 /* *******************************************************************/ 00091 /* PUBLISHED API FUNCTIONS */ 00092 00093 void 00094 qof_class_register (QofIdTypeConst obj_name, 00095 QofSortFunc default_sort_function, const QofParam * params) 00096 { 00097 GHashTable *ht; 00098 int i; 00099 00100 if (!obj_name) 00101 return; 00102 if (!check_init ()) 00103 return; 00104 00105 if (default_sort_function) 00106 { 00107 g_hash_table_insert (sortTable, (gchar *) obj_name, 00108 default_sort_function); 00109 } 00110 00111 ht = g_hash_table_lookup (classTable, obj_name); 00112 00113 /* If it doesn't already exist, create a new table for this object */ 00114 if (!ht) 00115 { 00116 ht = g_hash_table_new (g_str_hash, g_str_equal); 00117 g_hash_table_insert (classTable, (gchar *) obj_name, ht); 00118 } 00119 00120 /* At least right now, we allow dummy, parameterless objects, 00121 * for testing purposes. Although I suppose that should be 00122 * an error.. */ 00123 /* Now insert all the parameters */ 00124 if (params) 00125 { 00126 for (i = 0; params[i].param_name; i++) 00127 g_hash_table_insert (ht, 00128 (char *) params[i].param_name, (gpointer) & (params[i])); 00129 } 00130 } 00131 00132 gboolean 00133 qof_class_is_registered (QofIdTypeConst obj_name) 00134 { 00135 if (!obj_name) 00136 return FALSE; 00137 if (!check_init ()) 00138 return FALSE; 00139 00140 if (g_hash_table_lookup (classTable, obj_name)) 00141 return TRUE; 00142 00143 return FALSE; 00144 } 00145 00146 const QofParam * 00147 qof_class_get_parameter (QofIdTypeConst obj_name, const gchar *parameter) 00148 { 00149 GHashTable *ht; 00150 00151 g_return_val_if_fail (obj_name, NULL); 00152 g_return_val_if_fail (parameter, NULL); 00153 if (!check_init ()) 00154 return NULL; 00155 00156 ht = g_hash_table_lookup (classTable, obj_name); 00157 if (!ht) 00158 { 00159 PWARN ("no object of type %s", obj_name); 00160 return NULL; 00161 } 00162 00163 return (g_hash_table_lookup (ht, parameter)); 00164 } 00165 00166 QofAccessFunc 00167 qof_class_get_parameter_getter (QofIdTypeConst obj_name, 00168 const gchar *parameter) 00169 { 00170 const QofParam *prm; 00171 00172 g_return_val_if_fail (obj_name, NULL); 00173 g_return_val_if_fail (parameter, NULL); 00174 00175 prm = qof_class_get_parameter (obj_name, parameter); 00176 if (prm) 00177 return prm->param_getfcn; 00178 00179 return NULL; 00180 } 00181 00182 QofSetterFunc 00183 qof_class_get_parameter_setter (QofIdTypeConst obj_name, 00184 const gchar *parameter) 00185 { 00186 const QofParam *prm; 00187 00188 g_return_val_if_fail (obj_name, NULL); 00189 g_return_val_if_fail (parameter, NULL); 00190 00191 prm = qof_class_get_parameter (obj_name, parameter); 00192 if (prm) 00193 return prm->param_setfcn; 00194 00195 return NULL; 00196 } 00197 00198 QofType 00199 qof_class_get_parameter_type (QofIdTypeConst obj_name, 00200 const gchar *param_name) 00201 { 00202 const QofParam *prm; 00203 00204 if (!obj_name || !param_name) 00205 return NULL; 00206 00207 prm = qof_class_get_parameter (obj_name, param_name); 00208 if (!prm) 00209 return NULL; 00210 00211 return (prm->param_type); 00212 } 00213 00214 /* ================================================================ */ 00215 00216 struct class_iterate 00217 { 00218 QofClassForeachCB fcn; 00219 gpointer data; 00220 }; 00221 00222 static void 00223 class_foreach_cb (gpointer key __attribute__ ((unused)), 00224 gpointer item __attribute__ ((unused)), 00225 gpointer arg) 00226 { 00227 struct class_iterate *qiter = arg; 00228 QofIdTypeConst id = key; 00229 00230 qiter->fcn (id, qiter->data); 00231 } 00232 00233 void 00234 qof_class_foreach (QofClassForeachCB cb, gpointer user_data) 00235 { 00236 struct class_iterate qiter; 00237 00238 if (!cb) 00239 return; 00240 if (!classTable) 00241 return; 00242 00243 qiter.fcn = cb; 00244 qiter.data = user_data; 00245 00246 g_hash_table_foreach (classTable, class_foreach_cb, &qiter); 00247 } 00248 00249 /* ================================================================ */ 00250 00251 struct parm_iterate 00252 { 00253 QofParamForeachCB fcn; 00254 gpointer data; 00255 }; 00256 00257 static void 00258 param_foreach_cb (gpointer key __attribute__ ((unused)), 00259 gpointer item, gpointer arg) 00260 { 00261 struct parm_iterate *qiter = arg; 00262 QofParam *parm = item; 00263 00264 qiter->fcn (parm, qiter->data); 00265 } 00266 00267 void 00268 qof_class_param_foreach (QofIdTypeConst obj_name, 00269 QofParamForeachCB cb, gpointer user_data) 00270 { 00271 struct parm_iterate qiter; 00272 GHashTable *param_ht; 00273 00274 if (!obj_name || !cb) 00275 return; 00276 if (!classTable) 00277 return; 00278 param_ht = g_hash_table_lookup (classTable, obj_name); 00279 if (!param_ht) 00280 return; 00281 00282 qiter.fcn = cb; 00283 qiter.data = user_data; 00284 00285 g_hash_table_foreach (param_ht, param_foreach_cb, &qiter); 00286 } 00287 00288 struct param_ref_list 00289 { 00290 GList *list; 00291 }; 00292 00293 static void 00294 find_reference_param_cb (QofParam * param, gpointer user_data) 00295 { 00296 struct param_ref_list *b; 00297 00298 b = (struct param_ref_list *) user_data; 00299 if ((param->param_getfcn == NULL) || (param->param_setfcn == NULL)) 00300 return; 00301 if (0 == safe_strcmp (param->param_type, QOF_TYPE_STRING)) 00302 return; 00303 if (0 == safe_strcmp (param->param_type, QOF_TYPE_NUMERIC)) 00304 return; 00305 if (0 == safe_strcmp (param->param_type, QOF_TYPE_TIME)) 00306 return; 00307 if (0 == safe_strcmp (param->param_type, QOF_TYPE_CHAR)) 00308 return; 00309 if (0 == safe_strcmp (param->param_type, QOF_TYPE_DEBCRED)) 00310 return; 00311 if (0 == safe_strcmp (param->param_type, QOF_TYPE_GUID)) 00312 return; 00313 if (0 == safe_strcmp (param->param_type, QOF_TYPE_INT32)) 00314 return; 00315 if (0 == safe_strcmp (param->param_type, QOF_TYPE_INT64)) 00316 return; 00317 if (0 == safe_strcmp (param->param_type, QOF_TYPE_DOUBLE)) 00318 return; 00319 if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP)) 00320 return; 00321 if (0 == safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN)) 00322 return; 00323 if (0 == safe_strcmp (param->param_type, QOF_ID_BOOK)) 00324 return; 00325 b->list = g_list_append (b->list, param); 00326 } 00327 00328 GList * 00329 qof_class_get_referenceList (QofIdTypeConst type) 00330 { 00331 GList *ref_list; 00332 struct param_ref_list b; 00333 00334 ref_list = NULL; 00335 b.list = NULL; 00336 qof_class_param_foreach (type, find_reference_param_cb, &b); 00337 ref_list = g_list_copy (b.list); 00338 return ref_list; 00339 } 00340 00341 00342 /* ============================= END OF FILE ======================== */