QOF  0.7.5
qofclass.c
1 /********************************************************************\
2  * qofclass.c -- provide QOF parameterized data objects *
3  * Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
23 
24 #include "config.h"
25 
26 #include <glib.h>
27 
28 #include "qof.h"
29 #include "qofclass-p.h"
30 
31 static QofLogModule log_module = QOF_MOD_CLASS;
32 
33 static GHashTable *classTable = NULL;
34 static GHashTable *sortTable = NULL;
35 static gboolean initialized = FALSE;
36 
37 static gboolean
38 clear_table (gpointer key __attribute__ ((unused)), gpointer value,
39  gpointer user_data __attribute__ ((unused)))
40 {
41  g_hash_table_destroy (value);
42  return TRUE;
43 }
44 
45 /* *******************************************************************/
46 /* PRIVATE FUNCTIONS */
47 
48 static gboolean
49 check_init (void)
50 {
51  if (initialized)
52  return TRUE;
53 
54  PERR ("You must call qof_class_init() before using qof_class.");
55  return FALSE;
56 }
57 
58 void
59 qof_class_init (void)
60 {
61  if (initialized)
62  return;
63  initialized = TRUE;
64 
65  classTable = g_hash_table_new (g_str_hash, g_str_equal);
66  sortTable = g_hash_table_new (g_str_hash, g_str_equal);
67 }
68 
69 void
70 qof_class_shutdown (void)
71 {
72  if (!initialized)
73  return;
74  initialized = FALSE;
75 
76  g_hash_table_foreach_remove (classTable, clear_table, NULL);
77  g_hash_table_destroy (classTable);
78  g_hash_table_destroy (sortTable);
79 }
80 
82 qof_class_get_default_sort (QofIdTypeConst obj_name)
83 {
84  if (!obj_name)
85  return NULL;
86  return g_hash_table_lookup (sortTable, obj_name);
87 }
88 
89 /* *******************************************************************/
90 /* PUBLISHED API FUNCTIONS */
91 
92 void
94  QofSortFunc default_sort_function, const QofParam * params)
95 {
96  GHashTable *ht;
97  int i;
98 
99  if (!obj_name)
100  return;
101  if (!check_init ())
102  return;
103 
104  if (default_sort_function)
105  {
106  g_hash_table_insert (sortTable, (gchar *) obj_name,
107  default_sort_function);
108  }
109 
110  ht = g_hash_table_lookup (classTable, obj_name);
111 
112  /* If it doesn't already exist, create a new table for this object */
113  if (!ht)
114  {
115  ht = g_hash_table_new (g_str_hash, g_str_equal);
116  g_hash_table_insert (classTable, (gchar *) obj_name, ht);
117  }
118 
119  /* At least right now, we allow dummy, parameterless objects,
120  * for testing purposes. Although I suppose that should be
121  * an error.. */
122  /* Now insert all the parameters */
123  if (params)
124  {
125  for (i = 0; params[i].param_name; i++)
126  g_hash_table_insert (ht,
127  (char *) params[i].param_name, (gpointer) & (params[i]));
128  }
129 }
130 
131 gboolean
133 {
134  if (!obj_name)
135  return FALSE;
136  if (!check_init ())
137  return FALSE;
138 
139  if (g_hash_table_lookup (classTable, obj_name))
140  return TRUE;
141 
142  return FALSE;
143 }
144 
145 const QofParam *
146 qof_class_get_parameter (QofIdTypeConst obj_name, const gchar *parameter)
147 {
148  GHashTable *ht;
149 
150  g_return_val_if_fail (obj_name, NULL);
151  g_return_val_if_fail (parameter, NULL);
152  if (!check_init ())
153  return NULL;
154 
155  ht = g_hash_table_lookup (classTable, obj_name);
156  if (!ht)
157  {
158  PWARN ("no object of type %s", obj_name);
159  return NULL;
160  }
161 
162  return (g_hash_table_lookup (ht, parameter));
163 }
164 
167  const gchar *parameter)
168 {
169  const QofParam *prm;
170 
171  g_return_val_if_fail (obj_name, NULL);
172  g_return_val_if_fail (parameter, NULL);
173 
174  prm = qof_class_get_parameter (obj_name, parameter);
175  if (prm)
176  return prm->param_getfcn;
177 
178  return NULL;
179 }
180 
183  const gchar *parameter)
184 {
185  const QofParam *prm;
186 
187  g_return_val_if_fail (obj_name, NULL);
188  g_return_val_if_fail (parameter, NULL);
189 
190  prm = qof_class_get_parameter (obj_name, parameter);
191  if (prm)
192  return prm->param_setfcn;
193 
194  return NULL;
195 }
196 
197 QofType
199  const gchar *param_name)
200 {
201  const QofParam *prm;
202 
203  if (!obj_name || !param_name)
204  return NULL;
205 
206  prm = qof_class_get_parameter (obj_name, param_name);
207  if (!prm)
208  return NULL;
209 
210  return (prm->param_type);
211 }
212 
213 /* ================================================================ */
214 
215 struct class_iterate
216 {
217  QofClassForeachCB fcn;
218  gpointer data;
219 };
220 
221 static void
222 class_foreach_cb (gpointer key __attribute__ ((unused)),
223  gpointer item __attribute__ ((unused)),
224  gpointer arg)
225 {
226  struct class_iterate *qiter = arg;
227  QofIdTypeConst id = key;
228 
229  qiter->fcn (id, qiter->data);
230 }
231 
232 void
233 qof_class_foreach (QofClassForeachCB cb, gpointer user_data)
234 {
235  struct class_iterate qiter;
236 
237  if (!cb)
238  return;
239  if (!classTable)
240  return;
241 
242  qiter.fcn = cb;
243  qiter.data = user_data;
244 
245  g_hash_table_foreach (classTable, class_foreach_cb, &qiter);
246 }
247 
248 /* ================================================================ */
249 
250 struct parm_iterate
251 {
252  QofParamForeachCB fcn;
253  gpointer data;
254 };
255 
256 static void
257 param_foreach_cb (gpointer key __attribute__ ((unused)),
258  gpointer item, gpointer arg)
259 {
260  struct parm_iterate *qiter = arg;
261  QofParam *parm = item;
262 
263  qiter->fcn (parm, qiter->data);
264 }
265 
266 void
268  QofParamForeachCB cb, gpointer user_data)
269 {
270  struct parm_iterate qiter;
271  GHashTable *param_ht;
272 
273  if (!obj_name || !cb)
274  return;
275  if (!classTable)
276  return;
277  param_ht = g_hash_table_lookup (classTable, obj_name);
278  if (!param_ht)
279  return;
280 
281  qiter.fcn = cb;
282  qiter.data = user_data;
283 
284  g_hash_table_foreach (param_ht, param_foreach_cb, &qiter);
285 }
286 
287 struct param_ref_list
288 {
289  GList *list;
290 };
291 
292 static void
293 find_reference_param_cb (QofParam * param, gpointer user_data)
294 {
295  struct param_ref_list *b;
296 
297  b = (struct param_ref_list *) user_data;
298  if ((param->param_getfcn == NULL) || (param->param_setfcn == NULL))
299  return;
300  if (0 == safe_strcmp (param->param_type, QOF_TYPE_STRING))
301  return;
302  if (0 == safe_strcmp (param->param_type, QOF_TYPE_NUMERIC))
303  return;
304  if (0 == safe_strcmp (param->param_type, QOF_TYPE_TIME))
305  return;
306 #ifndef QOF_DISABLE_DEPRECATED
307  if (0 == safe_strcmp (param->param_type, QOF_TYPE_DATE))
308  return;
309 #endif
310  if (0 == safe_strcmp (param->param_type, QOF_TYPE_CHAR))
311  return;
312  if (0 == safe_strcmp (param->param_type, QOF_TYPE_DEBCRED))
313  return;
314  if (0 == safe_strcmp (param->param_type, QOF_TYPE_GUID))
315  return;
316  if (0 == safe_strcmp (param->param_type, QOF_TYPE_INT32))
317  return;
318  if (0 == safe_strcmp (param->param_type, QOF_TYPE_INT64))
319  return;
320  if (0 == safe_strcmp (param->param_type, QOF_TYPE_DOUBLE))
321  return;
322  if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP))
323  return;
324  if (0 == safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN))
325  return;
326  if (0 == safe_strcmp (param->param_type, QOF_ID_BOOK))
327  return;
328  b->list = g_list_append (b->list, param);
329 }
330 
331 GList *
333 {
334  GList *ref_list;
335  struct param_ref_list b;
336 
337  ref_list = NULL;
338  b.list = NULL;
339  qof_class_param_foreach (type, find_reference_param_cb, &b);
340  ref_list = g_list_copy (b.list);
341  return ref_list;
342 }
343 
344 
345 /* ============================= END OF FILE ======================== */