1 /*
2 * Portions of this file Copyright 1999-2005 University of Chicago
3 * Portions of this file Copyright 1999-2005 The University of Southern California.
4 *
5 * This file or a portion of this file is licensed under the
6 * terms of the Globus Toolkit Public License, found at
7 * http://www.globus.org/toolkit/download/license.html.
8 * If you redistribute this file, with or without
9 * modifications, you must include this notice in the file.
10 */
11
12 #include "globus_common.h"
13 #include "globus_i_xsd.h"
14 #include "globus_i_xsd_type_registry.h"
15 #include "globus_i_xsd_type_info.h"
16 #include "globus_soap_message_utils.h"
17 #include "globus_soap_message.h"
18
19 /**
20 * Initialize a new type registry.
21 *
22 * @param registry
23 * New type registry.
24 *
25 * @retval GLOBUS_SUCCESS
26 * Registry initialized.
27 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
28 * The @a registry parameter was NULL.
29 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
30 * Unable to allocate registry data.
31 *
32 * @see globus_xsd_type_registry_destroy()
33 */
34 globus_result_t
35 globus_xsd_type_registry_init(
36 globus_xsd_type_registry_t * registry)
37 374 {
38 globus_result_t result;
39 struct globus_xsd_type_registry_s * p;
40 int rc;
41 GlobusFuncName(globus_xsd_type_registry_init);
42 374 GlobusSoapMessageDebugEnter();
43
44 374 if (registry == NULL)
45 {
46 0 result = GlobusSoapMessageErrorNullParam;
47
48 0 goto error;
49 }
50 374 *registry = NULL;
51
52 374 p = globus_libc_malloc(sizeof(struct globus_xsd_type_registry_s));
53 374 if (p == NULL)
54 {
55 0 result = GlobusSoapMessageErrorOutOfMemory;
56
57 0 goto error;
58 }
59
60 374 rc = globus_hashtable_init(
61 &p->table,
62 257,
63 xsd_QName_hash,
64 xsd_QName_keyeq);
65
66 374 if (rc != GLOBUS_SUCCESS)
67 {
68 0 result = GlobusSoapMessageErrorOutOfMemory;
69
70 0 goto free_p_error;
71 }
72
73 374 p->default_mapping = &xsd_string_info;
74
75 374 globus_mutex_init(&p->lock, NULL);
76 374 *registry = p;
77
78 374 GlobusSoapMessageDebugExit();
79 374 return GLOBUS_SUCCESS;
80
81 0 free_p_error:
82 0 globus_libc_free(p);
83 0 error:
84 0 GlobusSoapMessageDebugExit();
85 0 return result;
86 }
87 /* globus_xsd_type_registry_init() */
88
89 /**
90 * Destroy a type registry.
91 *
92 * @param registry
93 * Type registry to destroy.
94 *
95 * @retval GLOBUS_SUCCESS
96 * Registry destroyed.
97 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
98 * The @a registry parameter was NULL.
99 *
100 * @see globus_xsd_type_registry_init()
101 * @see globus_xsd_type_registry_clear()
102 */
103 globus_result_t
104 globus_xsd_type_registry_destroy(
105 globus_xsd_type_registry_t registry)
106 288 {
107 globus_result_t result;
108 GlobusFuncName(globus_xsd_type_registry_destroy);
109 288 GlobusSoapMessageDebugEnter();
110
111 288 result = globus_xsd_type_registry_clear(registry);
112
113 288 if (result == GLOBUS_SUCCESS)
114 {
115 288 globus_hashtable_destroy(&registry->table);
116 288 globus_mutex_destroy(&registry->lock);
117 288 globus_libc_free(registry);
118 }
119
120 288 GlobusSoapMessageDebugExit();
121 288 return result;
122 }
123 /* globus_xsd_type_registry_destroy() */
124
125 /**
126 * Insert a type into the registry.
127 *
128 * If an existing type mapping is registered for the specified type, it
129 * is replaced with the new type. The old type is returned in value pointed to
130 * by the @a old_info parameter.
131 *
132 * @param registry
133 * Registry to modify.
134 * @param info
135 * Information about the type.
136 * @param old_info
137 * Pointer to be set to the value of the previous info for this type.
138 * May be NULL if the caller is not interested in this.
139 *
140 * @retval GLOBUS_SUCCESS
141 * Type mapping added
142 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
143 * The @a registry or @a info parameter was NULL.
144 *
145 * @see globus_xsd_type_registry_remove()
146 * @see globus_xsd_type_registry_get()
147 */
148 globus_result_t
149 globus_xsd_type_registry_insert(
150 globus_xsd_type_registry_t registry,
151 globus_xsd_type_info_t info,
152 globus_xsd_type_info_t * old_info)
153 22000 {
154 globus_result_t result;
155 globus_xsd_type_info_t p;
156 int rc;
157 GlobusFuncName(globus_xsd_type_registry_insert);
158 22000 GlobusSoapMessageDebugEnter();
159
160 22000 if (registry == NULL || info == NULL)
161 {
162 0 result = GlobusSoapMessageErrorNullParam;
163
164 0 goto error;
165 }
166
167 22000 rc = globus_mutex_lock(&registry->lock);
168 22000 if (rc != GLOBUS_SUCCESS)
169 {
170 0 result = GlobusSoapMessageErrorOutOfMemory;
171
172 0 goto error;
173 }
174
175 22000 p = globus_hashtable_lookup(&registry->table, info->type);
176 22000 if(p == info)
177 {
178 635 if(old_info)
179 {
180 0 *old_info = p;
181 }
182 goto exit;
183 }
184
185 21365 p = globus_hashtable_remove(&registry->table, info->type);
186
187 21365 if (old_info)
188 {
189 0 *old_info = p;
190 }
191
192 21365 rc = globus_hashtable_insert(&registry->table, info->type, info);
193
194 21365 if (rc != GLOBUS_SUCCESS)
195 {
196 0 result = GlobusSoapMessageErrorOutOfMemory;
197
198 0 goto unlock_error;
199 }
200
201 22000 exit:
202 22000 globus_mutex_unlock(&registry->lock);
203
204 22000 GlobusSoapMessageDebugExit();
205 22000 return GLOBUS_SUCCESS;
206
207 0 unlock_error:
208 0 globus_mutex_unlock(&registry->lock);
209 0 error:
210 0 GlobusSoapMessageDebugExit();
211 0 return result;
212 }
213 /* globus_xsd_type_registry_insert() */
214
215 /**
216 * Remove a type from the registry.
217 *
218 * @param registry
219 * Registry to modify.
220 * @param name
221 * Name of the type to be unregistered.
222 * @param info
223 * Pointer to be set to the previously registred type information. May be
224 * NULL if the caller doesn't want that type info.
225 *
226 * @retval GLOBUS_SUCCESS
227 * Type mapping removed.
228 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
229 * The @a registry or @a name parameter was NULL.
230 *
231 * @see globus_xsd_type_registry_replace()
232 * @see globus_xsd_type_registry_remove()
233 * @see globus_xsd_type_registry_get()
234 */
235 globus_result_t
236 globus_xsd_type_registry_remove(
237 globus_xsd_type_registry_t registry,
238 const xsd_QName * name,
239 globus_xsd_type_info_t * info)
240 0 {
241 globus_result_t result;
242 globus_xsd_type_info_t tmp;
243 GlobusFuncName(globus_xsd_type_registry_remove);
244 0 GlobusSoapMessageDebugEnter();
245
246 0 if (registry == NULL || name == NULL)
247 {
248 0 result = GlobusSoapMessageErrorNullParam;
249
250 0 goto error;
251 }
252
253 0 globus_mutex_lock(&registry->lock);
254 0 tmp = globus_hashtable_remove(&registry->table, (void *) name);
255
256 0 if (info != NULL)
257 {
258 0 *info = tmp;
259 }
260 0 globus_mutex_unlock(&registry->lock);
261
262 0 GlobusSoapMessageDebugExit();
263 0 return GLOBUS_SUCCESS;
264 0 error:
265 0 GlobusSoapMessageDebugExit();
266 0 return result;
267 }
268 /* globus_xsd_type_registry_remove() */
269
270 globus_result_t
271 globus_xsd_type_registry_clear(
272 globus_xsd_type_registry_t registry)
273 288 {
274 int rc;
275 globus_result_t result;
276 globus_list_t * tmp_list;
277 globus_xsd_type_info_t p;
278 GlobusFuncName(globus_xsd_type_registry_clear);
279 288 GlobusSoapMessageDebugEnter();
280
281 288 if (registry == NULL)
282 {
283 0 result = GlobusSoapMessageErrorNullParam;
284
285 0 goto error;
286 }
287 288 rc = globus_mutex_lock(&registry->lock);
288 288 if (rc != GLOBUS_SUCCESS)
289 {
290 0 result = GlobusSoapMessageErrorOutOfMemory;
291
292 0 goto error;
293 }
294 288 rc = globus_hashtable_to_list(&registry->table, &tmp_list);
295 288 if (rc != GLOBUS_SUCCESS)
296 {
297 0 result = GlobusSoapMessageErrorNullParam;
298
299 0 goto unlock_error;
300 }
301 14567 while (!globus_list_empty(tmp_list))
302 {
303 14279 p = globus_list_remove(&tmp_list, tmp_list);
304
305 14279 globus_assert(p);
306
307 14279 globus_hashtable_remove(&registry->table, p->type);
308 }
309
310 288 globus_mutex_unlock(&registry->lock);
311
312 288 GlobusSoapMessageDebugExit();
313 288 return GLOBUS_SUCCESS;
314
315
316 0 unlock_error:
317 0 globus_mutex_unlock(&registry->lock);
318 0 error:
319 0 GlobusSoapMessageDebugExit();
320 0 return result;
321 }
322 /* globus_xsd_type_registry_clear() */
323
324 globus_result_t
325 globus_xsd_type_registry_get(
326 globus_xsd_type_registry_t registry,
327 const xsd_QName * name,
328 globus_xsd_type_info_t * info)
329 746732 {
330 globus_result_t result;
331 int rc;
332 GlobusFuncName(globus_xsd_type_registry_get);
333 746732 GlobusSoapMessageDebugEnter();
334
335 746732 if (registry == NULL || name == NULL || info == NULL)
336 {
337 0 result = GlobusSoapMessageErrorNullParam;
338
339 0 goto error;
340 }
341 746732 rc = globus_mutex_lock(&registry->lock);
342 746732 if (rc != GLOBUS_SUCCESS)
343 {
344 0 result = GlobusSoapMessageErrorOutOfMemory;
345
346 0 goto error;
347 }
348 746732 *info = globus_hashtable_lookup(&registry->table, (void *) name);
349
350 746732 globus_mutex_unlock(&registry->lock);
351
352 746732 GlobusSoapMessageDebugExit();
353 746732 return GLOBUS_SUCCESS;
354 0 error:
355 0 GlobusSoapMessageDebugExit();
356 0 return result;
357 }
358 /* globus_xsd_type_registry_get() */
359
360 globus_result_t
361 globus_xsd_type_registry_set_default(
362 globus_xsd_type_registry_t registry,
363 globus_xsd_type_info_t info)
364 0 {
365 globus_result_t result;
366 GlobusFuncName(globus_xsd_type_registry_set_default);
367 0 GlobusSoapMessageDebugEnter();
368
369 0 if (registry == NULL || info == NULL)
370 {
371 0 result = GlobusSoapMessageErrorNullParam;
372
373 0 goto error;
374 }
375 0 globus_mutex_lock(&registry->lock);
376 0 registry->default_mapping = info;
377 0 globus_mutex_unlock(&registry->lock);
378
379 0 GlobusSoapMessageDebugExit();
380 0 return GLOBUS_SUCCESS;
381 0 error:
382 0 GlobusSoapMessageDebugExit();
383 0 return result;
384 }
385 /* globus_xsd_type_registry_set_default() */
386
387 globus_result_t
388 globus_xsd_type_registry_get_default(
389 globus_xsd_type_registry_t registry,
390 globus_xsd_type_info_t * info)
391 0 {
392 globus_result_t result;
393 GlobusFuncName(globus_xsd_type_registry_get_default);
394 0 GlobusSoapMessageDebugEnter();
395
396 0 if (registry == NULL || info == NULL)
397 {
398 0 result = GlobusSoapMessageErrorNullParam;
399
400 0 goto error;
401 }
402 0 globus_mutex_lock(&registry->lock);
403 0 *info = registry->default_mapping;
404 0 globus_mutex_unlock(&registry->lock);
405
406 0 GlobusSoapMessageDebugExit();
407 0 return GLOBUS_SUCCESS;
408 0 error:
409 0 GlobusSoapMessageDebugExit();
410 0 return result;
411 }
412 /* globus_xsd_type_registry_get_default() */
413
414
415 globus_result_t
416 globus_xsd_type_registry_add_base_types(
417 globus_xsd_type_registry_t registry)
418 296 {
419 296 globus_result_t result = GLOBUS_SUCCESS;
420 GlobusFuncName(globus_xsd_type_registry_add_base_types);
421 296 GlobusSoapMessageDebugEnter();
422
423 296 result = globus_xsd_type_registry_insert(registry, &xsd_QName_info, NULL);
424 296 if(result != GLOBUS_SUCCESS)
425 {
426 296 goto exit;
427 }
428
429 296 result = globus_xsd_type_registry_insert(registry, &xsd_anyURI_info, NULL);
430 296 if(result != GLOBUS_SUCCESS)
431 {
432 296 goto exit;
433 }
434
435 296 result = globus_xsd_type_registry_insert(registry, &xsd_base64Binary_info, NULL);
436 296 if(result != GLOBUS_SUCCESS)
437 {
438 296 goto exit;
439 }
440
441 296 result = globus_xsd_type_registry_insert(registry, &xsd_boolean_info, NULL);
442 296 if(result != GLOBUS_SUCCESS)
443 {
444 296 goto exit;
445 }
446
447 296 result = globus_xsd_type_registry_insert(registry, &xsd_byte_info, NULL);
448 296 if(result != GLOBUS_SUCCESS)
449 {
450 296 goto exit;
451 }
452
453 296 result = globus_xsd_type_registry_insert(registry, &xsd_date_info, NULL);
454 296 if(result != GLOBUS_SUCCESS)
455 {
456 296 goto exit;
457 }
458
459 296 result = globus_xsd_type_registry_insert(registry, &xsd_dateTime_info, NULL);
460 296 if(result != GLOBUS_SUCCESS)
461 {
462 296 goto exit;
463 }
464
465 296 result = globus_xsd_type_registry_insert(registry, &xsd_decimal_info, NULL);
466 296 if(result != GLOBUS_SUCCESS)
467 {
468 296 goto exit;
469 }
470
471 296 result = globus_xsd_type_registry_insert(registry, &xsd_double_info, NULL);
472 296 if(result != GLOBUS_SUCCESS)
473 {
474 296 goto exit;
475 }
476
477 296 result = globus_xsd_type_registry_insert(registry, &xsd_duration_info, NULL);
478 296 if(result != GLOBUS_SUCCESS)
479 {
480 296 goto exit;
481 }
482
483 296 result = globus_xsd_type_registry_insert(registry, &xsd_float_info, NULL);
484 296 if(result != GLOBUS_SUCCESS)
485 {
486 296 goto exit;
487 }
488
489 296 result = globus_xsd_type_registry_insert(registry, &xsd_hexBinary_info, NULL);
490 296 if(result != GLOBUS_SUCCESS)
491 {
492 296 goto exit;
493 }
494
495 296 result = globus_xsd_type_registry_insert(registry, &xsd_int_info, NULL);
496 296 if(result != GLOBUS_SUCCESS)
497 {
498 296 goto exit;
499 }
500
501 296 result = globus_xsd_type_registry_insert(registry, &xsd_integer_info, NULL);
502 296 if(result != GLOBUS_SUCCESS)
503 {
504 296 goto exit;
505 }
506
507 296 result = globus_xsd_type_registry_insert(registry, &xsd_long_info, NULL);
508 296 if(result != GLOBUS_SUCCESS)
509 {
510 296 goto exit;
511 }
512
513 296 result = globus_xsd_type_registry_insert(registry, &xsd_negativeInteger_info, NULL);
514 296 if(result != GLOBUS_SUCCESS)
515 {
516 296 goto exit;
517 }
518
519 296 result = globus_xsd_type_registry_insert(registry, &xsd_nonNegativeInteger_info, NULL);
520 296 if(result != GLOBUS_SUCCESS)
521 {
522 296 goto exit;
523 }
524
525 296 result = globus_xsd_type_registry_insert(registry, &xsd_nonPositiveInteger_info, NULL);
526 296 if(result != GLOBUS_SUCCESS)
527 {
528 296 goto exit;
529 }
530
531 296 result = globus_xsd_type_registry_insert(registry, &xsd_positiveInteger_info, NULL);
532 296 if(result != GLOBUS_SUCCESS)
533 {
534 296 goto exit;
535 }
536
537 296 result = globus_xsd_type_registry_insert(registry, &xsd_short_info, NULL);
538 296 if(result != GLOBUS_SUCCESS)
539 {
540 296 goto exit;
541 }
542
543 296 result = globus_xsd_type_registry_insert(registry, &xsd_string_info, NULL);
544 296 if(result != GLOBUS_SUCCESS)
545 {
546 296 goto exit;
547 }
548
549 296 result = globus_xsd_type_registry_insert(registry, &xsd_time_info, NULL);
550 296 if(result != GLOBUS_SUCCESS)
551 {
552 296 goto exit;
553 }
554
555 296 result = globus_xsd_type_registry_insert(registry, &xsd_unsignedByte_info, NULL);
556 296 if(result != GLOBUS_SUCCESS)
557 {
558 296 goto exit;
559 }
560
561 296 result = globus_xsd_type_registry_insert(registry, &xsd_unsignedInt_info, NULL);
562 296 if(result != GLOBUS_SUCCESS)
563 {
564 296 goto exit;
565 }
566
567 296 result = globus_xsd_type_registry_insert(registry, &xsd_unsignedLong_info, NULL);
568 296 if(result != GLOBUS_SUCCESS)
569 {
570 296 goto exit;
571 }
572
573 296 result = globus_xsd_type_registry_insert(registry, &xsd_unsignedShort_info, NULL);
574 if(result != GLOBUS_SUCCESS)
575 {
576 goto exit;
577 }
578
579 296 exit:
580
581 296 GlobusSoapMessageDebugExit();
582 296 return result;
583 }
584
585 globus_result_t
586 globus_xsd_type_registry_dump(
587 globus_xsd_type_registry_t registry)
588 0 {
589 0 globus_result_t result = GLOBUS_SUCCESS;
590 globus_xsd_type_info_t info;
591 0 int rc = 0;
592 GlobusFuncName(globus_xsd_type_registry_dump);
593 0 GlobusSoapMessageDebugEnter();
594
595 0 rc = globus_mutex_lock(&registry->lock);
596 0 if (rc != GLOBUS_SUCCESS)
597 {
598 0 result = GlobusSoapMessageErrorOutOfMemory;
599 0 goto error;
600 }
601
602 0 info = globus_hashtable_first(&registry->table);
603
604 0 while(info)
605 {
606 0 GlobusSoapMessageDebugPrintf(
607 GLOBUS_SOAP_MESSAGE_DEBUG_REGISTRY,
608 ("{%s}%s\n",
609 info->type->Namespace,
610 info->type->local));
611
612 0 info = globus_hashtable_next(&registry->table);
613 }
614
615 0 rc = globus_mutex_unlock(&registry->lock);
616 0 if(rc != GLOBUS_SUCCESS)
617 {
618 0 result = GlobusSoapMessageErrorOutOfMemory;
619 goto error;
620 }
621
622 0 error:
623
624 0 GlobusSoapMessageDebugExit();
625 0 return result;