1 /*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "globus_common.h"
18 #include "globus_i_xsd_type_registry.h"
19 #include "globus_soap_message_utils.h"
20 #include "globus_soap_message.h"
21 #include "xsd_any.h"
22 #include "xsd_anyType.h"
23 #include "xsd_anyURI.h"
24 #include "xsd_base64Binary.h"
25 #include "xsd_boolean.h"
26 #include "xsd_byte.h"
27 #include "xsd_date.h"
28 #include "xsd_dateTime.h"
29 #include "xsd_decimal.h"
30 #include "xsd_double.h"
31 #include "xsd_duration.h"
32 #include "xsd_ENTITIES.h"
33 #include "xsd_ENTITY.h"
34 #include "xsd_float.h"
35 #include "xsd_gDay.h"
36 #include "xsd_gMonthDay.h"
37 #include "xsd_gMonth.h"
38 #include "xsd_gYear.h"
39 #include "xsd_gYearMonth.h"
40 #include "xsd_hexBinary.h"
41 #include "xsd_ID.h"
42 #include "xsd_IDREF.h"
43 #include "xsd_IDREFS.h"
44 #include "xsd_integer.h"
45 #include "xsd_int.h"
46 #include "xsd_language.h"
47 #include "xsd_long.h"
48 #include "xsd_Name.h"
49 #include "xsd_NOTATION.h"
50 #include "xsd_NCName.h"
51 #include "xsd_negativeInteger.h"
52 #include "xsd_NMTOKEN.h"
53 #include "xsd_NMTOKENS.h"
54 #include "xsd_nonNegativeInteger.h"
55 #include "xsd_nonPositiveInteger.h"
56 #include "xsd_normalizedString.h"
57 #include "xsd_positiveInteger.h"
58 #include "xsd_QName.h"
59 #include "xsd_short.h"
60 #include "xsd_string.h"
61 #include "xsd_time.h"
62 #include "xsd_token.h"
63 #include "xsd_unsignedByte.h"
64 #include "xsd_unsignedInt.h"
65 #include "xsd_unsignedLong.h"
66 #include "xsd_unsignedShort.h"
67
68 static
69 void
70 globus_l_element_map_free(
71 void * p);
72
73 /**
74 * Initialize a new type registry.
75 * @ingroup globus_xsd_type_registry
76 *
77 * @param registry
78 * New type registry.
79 *
80 * @retval GLOBUS_SUCCESS
81 * Registry initialized.
82 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
83 * The @a registry parameter was NULL.
84 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
85 * Unable to allocate registry data.
86 *
87 * @see globus_xsd_type_registry_destroy()
88 */
89 globus_result_t
90 globus_xsd_type_registry_init(
91 globus_xsd_type_registry_t * registry)
92 1608 {
93 globus_result_t result;
94 struct globus_xsd_type_registry_s * p;
95 int rc;
96 GlobusFuncName(globus_xsd_type_registry_init);
97 1608 GlobusSoapMessageDebugEnter();
98
99 1608 if (registry == NULL)
100 {
101 0 result = GlobusSoapMessageErrorNullParam;
102
103 0 goto error;
104 }
105 1608 *registry = NULL;
106
107 1608 p = globus_libc_malloc(sizeof(struct globus_xsd_type_registry_s));
108 1608 if (p == NULL)
109 {
110 0 result = GlobusSoapMessageErrorOutOfMemory;
111
112 0 goto error;
113 }
114
115 1608 rc = globus_hashtable_init(
116 &p->table,
117 257,
118 xsd_QName_hash,
119 xsd_QName_keyeq);
120
121 1608 if (rc != GLOBUS_SUCCESS)
122 {
123 0 result = GlobusSoapMessageErrorOutOfMemory;
124
125 0 goto free_p_error;
126 }
127
128 1608 rc = globus_hashtable_init(
129 &p->elements,
130 257,
131 xsd_QName_hash,
132 xsd_QName_keyeq);
133
134 1608 if (rc != GLOBUS_SUCCESS)
135 {
136 0 result = GlobusSoapMessageErrorOutOfMemory;
137
138 0 goto free_table_out;
139 }
140
141 1608 rc = globus_hashtable_init(
142 &p->attributes,
143 257,
144 xsd_QName_hash,
145 xsd_QName_keyeq);
146
147 1608 if (rc != GLOBUS_SUCCESS)
148 {
149 0 result = GlobusSoapMessageErrorOutOfMemory;
150
151 0 goto free_elements_out;
152 }
153
154 1608 globus_mutex_init(&p->lock, NULL);
155 1608 *registry = p;
156
157 1608 GlobusSoapMessageDebugExit();
158 1608 return GLOBUS_SUCCESS;
159
160 0 free_elements_out:
161 0 globus_hashtable_destroy(&p->elements);
162 0 free_table_out:
163 0 globus_hashtable_destroy(&p->table);
164 0 free_p_error:
165 0 globus_libc_free(p);
166 0 error:
167 0 GlobusSoapMessageDebugExit();
168 0 return result;
169 }
170 /* globus_xsd_type_registry_init() */
171
172 /**
173 * Destroy a type registry.
174 * @ingroup globus_xsd_type_registry
175 *
176 * @param registry
177 * Type registry to destroy.
178 *
179 * @retval GLOBUS_SUCCESS
180 * Registry destroyed.
181 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
182 * The @a registry parameter was NULL.
183 *
184 * @see globus_xsd_type_registry_init()
185 * @see globus_xsd_type_registry_clear()
186 */
187 globus_result_t
188 globus_xsd_type_registry_destroy(
189 globus_xsd_type_registry_t registry)
190 554 {
191 globus_result_t result;
192 GlobusFuncName(globus_xsd_type_registry_destroy);
193 554 GlobusSoapMessageDebugEnter();
194
195 554 result = globus_xsd_type_registry_clear(registry);
196
197 554 if (result == GLOBUS_SUCCESS)
198 {
199 554 globus_hashtable_destroy(&registry->table);
200 554 globus_hashtable_destroy_all(
201 &registry->elements,
202 globus_l_element_map_free);
203 554 globus_mutex_destroy(&registry->lock);
204 554 globus_libc_free(registry);
205 }
206
207 554 GlobusSoapMessageDebugExit();
208 554 return result;
209 }
210 /* globus_xsd_type_registry_destroy() */
211
212 /**
213 * Insert a type into the registry.
214 * @ingroup globus_xsd_type_registry
215 *
216 * If an existing type mapping is registered for the specified type, it
217 * is replaced with the new type. The old type is returned in value pointed to
218 * by the @a old_info parameter.
219 *
220 * @param registry
221 * Registry to modify.
222 * @param info
223 * Information about the type.
224 * @param old_info
225 * Pointer to be set to the value of the previous info for this type.
226 * May be NULL if the caller is not interested in this.
227 *
228 * @retval GLOBUS_SUCCESS
229 * Type mapping added
230 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
231 * The @a registry or @a info parameter was NULL.
232 *
233 * @see globus_xsd_type_registry_remove()
234 * @see globus_xsd_type_registry_get()
235 */
236 globus_result_t
237 globus_xsd_type_registry_insert(
238 globus_xsd_type_registry_t registry,
239 globus_xsd_type_info_t info,
240 globus_xsd_type_info_t * old_info)
241 179247 {
242 globus_result_t result;
243 globus_xsd_type_info_t p;
244 int rc;
245 GlobusFuncName(globus_xsd_type_registry_insert);
246 179247 GlobusSoapMessageDebugEnter();
247
248 179247 if (registry == NULL || info == NULL)
249 {
250 0 result = GlobusSoapMessageErrorNullParam;
251
252 0 goto error;
253 }
254
255 179247 rc = globus_mutex_lock(&registry->lock);
256 179247 if (rc != GLOBUS_SUCCESS)
257 {
258 0 result = GlobusSoapMessageErrorOutOfMemory;
259
260 0 goto error;
261 }
262
263 179247 p = globus_hashtable_lookup(&registry->table, info->type);
264 179247 if(p == info)
265 {
266 30405 if(old_info)
267 {
268 0 *old_info = p;
269 }
270 30405 goto exit;
271 }
272
273 148842 p = globus_hashtable_remove(&registry->table, info->type);
274
275 148842 if (old_info)
276 {
277 0 *old_info = p;
278 }
279
280 148842 rc = globus_hashtable_insert(&registry->table, info->type, info);
281
282 148842 if (rc != GLOBUS_SUCCESS)
283 {
284 0 result = GlobusSoapMessageErrorOutOfMemory;
285
286 0 goto unlock_error;
287 }
288
289 179247 exit:
290 179247 globus_mutex_unlock(&registry->lock);
291
292 179247 GlobusSoapMessageDebugExit();
293 179247 return GLOBUS_SUCCESS;
294
295 0 unlock_error:
296 0 globus_mutex_unlock(&registry->lock);
297 0 error:
298 0 GlobusSoapMessageDebugExit();
299 0 return result;
300 }
301 /* globus_xsd_type_registry_insert() */
302
303 /**
304 * Remove a type from the registry.
305 * @ingroup globus_xsd_type_registry
306 *
307 * @param registry
308 * Registry to modify.
309 * @param name
310 * Name of the type to be unregistered.
311 * @param info
312 * Pointer to be set to the previously registred type information. May be
313 * NULL if the caller doesn't want that type info.
314 *
315 * @retval GLOBUS_SUCCESS
316 * Type mapping removed.
317 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
318 * The @a registry or @a name parameter was NULL.
319 *
320 * @see globus_xsd_type_registry_remove()
321 * @see globus_xsd_type_registry_get()
322 */
323 globus_result_t
324 globus_xsd_type_registry_remove(
325 globus_xsd_type_registry_t registry,
326 const xsd_QName * name,
327 globus_xsd_type_info_t * info)
328 9516 {
329 globus_result_t result;
330 globus_xsd_type_info_t tmp;
331 GlobusFuncName(globus_xsd_type_registry_remove);
332 9516 GlobusSoapMessageDebugEnter();
333
334 9516 if (registry == NULL || name == NULL)
335 {
336 0 result = GlobusSoapMessageErrorNullParam;
337
338 0 goto error;
339 }
340
341 9516 globus_mutex_lock(&registry->lock);
342 9516 tmp = globus_hashtable_remove(&registry->table, (void *) name);
343
344 9516 if (info != NULL)
345 {
346 0 *info = tmp;
347 }
348 9516 globus_mutex_unlock(&registry->lock);
349
350 9516 GlobusSoapMessageDebugExit();
351 9516 return GLOBUS_SUCCESS;
352 0 error:
353 0 GlobusSoapMessageDebugExit();
354 0 return result;
355 }
356 /* globus_xsd_type_registry_remove() */
357
358 /**
359 * Insert an element into the registry.
360 * @ingroup globus_xsd_type_registry
361 *
362 * Inserts a mapping from the given @a element to the @a type. This mapping
363 * will be used to deserialize elements based on their element names.
364 *
365 * @param registry
366 * Registry to modify.
367 * @param element
368 * Element name to insert.
369 * @param type
370 * Type name to map to.
371 *
372 * @retval GLOBUS_SUCCESS
373 * Type mapping added
374 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
375 * The @a registry or @a type or @a element parameter was NULL.
376 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
377 * Insufficient memory to add type to registry.
378 *
379 * @see globus_xsd_type_registry_remove_element()
380 * @see globus_xsd_type_registry_get()
381 */
382 globus_result_t
383 globus_xsd_type_registry_insert_element(
384 globus_xsd_type_registry_t registry,
385 const xsd_QName * element,
386 const xsd_QName * type)
387 111426 {
388 111426 globus_result_t result = GLOBUS_SUCCESS;
389 globus_i_xsd_element_map_t * map;
390 xsd_QName * tmp;
391 int rc;
392 GlobusFuncName(globus_xsd_type_registry_insert);
393 111426 GlobusSoapMessageDebugEnter();
394
395 111426 if (registry == NULL || element == NULL || type == NULL)
396 {
397 0 result = GlobusSoapMessageErrorNullParam;
398
399 0 goto out;
400 }
401
402 111426 rc = globus_mutex_lock(&registry->lock);
403 111426 if (rc != GLOBUS_SUCCESS)
404 {
405 0 result = GlobusSoapMessageErrorOutOfMemory;
406
407 0 goto out;
408 }
409
410 111426 map = globus_hashtable_lookup(&registry->elements, (void *) element);
411 111426 if(map != NULL)
412 {
413 31772 result = xsd_QName_copy(&tmp, type);
414
415 31772 if (result != GLOBUS_SUCCESS)
416 {
417 0 goto unlock_out;
418 }
419
420 31772 xsd_QName_destroy(map->type);
421 31772 map->type = tmp;
422 }
423 else
424 {
425 79654 map = malloc(sizeof(globus_i_xsd_element_map_t));
426
427 79654 result = xsd_QName_copy(&map->element, element);
428 79654 if (result != GLOBUS_SUCCESS)
429 {
430 0 goto free_map_error;
431 }
432 79654 result = xsd_QName_copy(&map->type, type);
433 79654 if (result != GLOBUS_SUCCESS)
434 {
435 0 goto free_map_element_error;
436 }
437 79654 rc = globus_hashtable_insert(
438 &registry->elements,
439 map->element,
440 (void *) map);
441
442 79654 if (rc != GLOBUS_SUCCESS)
443 {
444 0 result = GlobusSoapMessageErrorOutOfMemory;
445
446 0 goto free_map_type_error;
447 }
448 }
449
450 111426 if (result != GLOBUS_SUCCESS)
451 {
452 0 free_map_type_error:
453 0 xsd_QName_destroy(map->type);
454 0 free_map_element_error:
455 0 xsd_QName_destroy(map->element);
456 0 free_map_error:
457 0 free(map);
458 }
459
460 111426 unlock_out:
461 111426 globus_mutex_unlock(&registry->lock);
462 111426 out:
463 111426 GlobusSoapMessageDebugExit();
464 111426 return result;
465 }
466 /* globus_xsd_type_registry_insert_element() */
467
468 /**
469 * Remove an element from the registry.
470 * @ingroup globus_xsd_type_registry
471 *
472 * @param registry
473 * Registry to modify.
474 * @param element
475 * Name of the element to be unregistered.
476 *
477 * @retval GLOBUS_SUCCESS
478 * Type mapping removed.
479 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
480 * The @a registry or @a element parameter was NULL.
481 *
482 * @see globus_xsd_type_registry_remove()
483 * @see globus_xsd_type_registry_get()
484 */
485 globus_result_t
486 globus_xsd_type_registry_remove_element(
487 globus_xsd_type_registry_t registry,
488 const xsd_QName * element)
489 10084 {
490 10084 globus_result_t result = GLOBUS_SUCCESS;
491 globus_i_xsd_element_map_t * map;
492 GlobusFuncName(globus_xsd_type_registry_remove);
493 10084 GlobusSoapMessageDebugEnter();
494
495 10084 if (registry == NULL || element == NULL)
496 {
497 0 result = GlobusSoapMessageErrorNullParam;
498
499 0 goto out;
500 }
501
502 10084 globus_mutex_lock(&registry->lock);
503 10084 map = globus_hashtable_remove(&registry->elements, (void *) element);
504
505 10084 if (map)
506 {
507 8610 globus_l_element_map_free(map);
508 }
509
510 10084 globus_mutex_unlock(&registry->lock);
511
512 10084 out:
513 10084 GlobusSoapMessageDebugExit();
514 10084 return result;
515 }
516 /* globus_xsd_type_registry_remove_element() */
517
518 /**
519 * Insert an attribute into the registry.
520 * @ingroup globus_xsd_type_registry
521 *
522 * Inserts a mapping from the given @a attribute to the @a type. This mapping
523 * will be used to deserialize attribute based on their names.
524 *
525 * @param registry
526 * Registry to modify.
527 * @param attribute
528 * Attribute name to insert.
529 * @param type
530 * Type name to map to.
531 *
532 * @retval GLOBUS_SUCCESS
533 * Type mapping added
534 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
535 * The @a registry or @a type or @a element parameter was NULL.
536 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
537 * Insufficient memory to add type to registry.
538 *
539 * @see globus_xsd_type_registry_remove_attribute()
540 */
541 globus_result_t
542 globus_xsd_type_registry_insert_attribute(
543 globus_xsd_type_registry_t registry,
544 const xsd_QName * attribute,
545 const xsd_QName * type)
546 6 {
547 6 globus_result_t result = GLOBUS_SUCCESS;
548 globus_i_xsd_element_map_t * map;
549 xsd_QName * tmp;
550 int rc;
551 GlobusFuncName(globus_xsd_type_registry_insert);
552 6 GlobusSoapMessageDebugEnter();
553
554 6 if (registry == NULL || attribute == NULL || type == NULL)
555 {
556 0 result = GlobusSoapMessageErrorNullParam;
557
558 0 goto out;
559 }
560
561 6 rc = globus_mutex_lock(&registry->lock);
562 6 if (rc != GLOBUS_SUCCESS)
563 {
564 0 result = GlobusSoapMessageErrorOutOfMemory;
565
566 0 goto out;
567 }
568
569 6 map = globus_hashtable_lookup(&registry->attributes, (void *) attribute);
570 6 if(map != NULL)
571 {
572 0 result = xsd_QName_copy(&tmp, type);
573
574 0 if (result != GLOBUS_SUCCESS)
575 {
576 0 goto unlock_out;
577 }
578
579 0 xsd_QName_destroy(map->type);
580 0 map->type = tmp;
581 }
582 else
583 {
584 6 map = malloc(sizeof(globus_i_xsd_element_map_t));
585
586 6 result = xsd_QName_copy(&map->element, attribute);
587 6 if (result != GLOBUS_SUCCESS)
588 {
589 0 goto free_map_error;
590 }
591 6 result = xsd_QName_copy(&map->type, type);
592 6 if (result != GLOBUS_SUCCESS)
593 {
594 0 goto free_map_element_error;
595 }
596 6 rc = globus_hashtable_insert(
597 &registry->attributes,
598 map->element,
599 (void *) map);
600
601 6 if (rc != GLOBUS_SUCCESS)
602 {
603 0 result = GlobusSoapMessageErrorOutOfMemory;
604
605 0 goto free_map_type_error;
606 }
607 }
608
609 6 if (result != GLOBUS_SUCCESS)
610 {
611 0 free_map_type_error:
612 0 xsd_QName_destroy(map->type);
613 0 free_map_element_error:
614 0 xsd_QName_destroy(map->element);
615 0 free_map_error:
616 0 free(map);
617 }
618
619 6 unlock_out:
620 6 globus_mutex_unlock(&registry->lock);
621 6 out:
622 6 GlobusSoapMessageDebugExit();
623 6 return result;
624 }
625 /* globus_xsd_type_registry_insert_attribute() */
626
627 /**
628 * Remove an attribute from the registry.
629 * @ingroup globus_xsd_type_registry
630 *
631 * @param registry
632 * Registry to modify.
633 * @param attribute
634 * Name of the attribute to be unregistered.
635 *
636 * @retval GLOBUS_SUCCESS
637 * Type mapping removed.
638 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
639 * The @a registry or @a attribute parameter was NULL.
640 *
641 * @see globus_xsd_type_registry_remove()
642 * @see globus_xsd_type_registry_get()
643 */
644 globus_result_t
645 globus_xsd_type_registry_remove_attribute(
646 globus_xsd_type_registry_t registry,
647 const xsd_QName * attribute)
648 0 {
649 0 globus_result_t result = GLOBUS_SUCCESS;
650 globus_i_xsd_element_map_t * map;
651 GlobusFuncName(globus_xsd_type_registry_remove);
652 0 GlobusSoapMessageDebugEnter();
653
654 0 if (registry == NULL || attribute == NULL)
655 {
656 0 result = GlobusSoapMessageErrorNullParam;
657
658 0 goto out;
659 }
660
661 0 globus_mutex_lock(&registry->lock);
662 0 map = globus_hashtable_remove(&registry->attributes, (void *) attribute);
663
664 0 if (map)
665 {
666 0 globus_l_element_map_free(map);
667 }
668
669 0 globus_mutex_unlock(&registry->lock);
670
671 0 out:
672 0 GlobusSoapMessageDebugExit();
673 0 return result;
674 }
675 /* globus_xsd_type_registry_remove_attribute() */
676
677 /**
678 * Remove all entries from a type registry
679 * @ingroup globus_xsd_type_registry
680 *
681 * @param registry
682 * Registry to clear.
683 *
684 * @retval GLOBUS_SUCCESS
685 * Type mapping removed.
686 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
687 * The @a registry parameter was NULL.
688 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
689 * Insufficient memory to clear registry.
690 */
691 globus_result_t
692 globus_xsd_type_registry_clear(
693 globus_xsd_type_registry_t registry)
694 554 {
695 int rc;
696 globus_result_t result;
697 globus_list_t * tmp_list;
698 globus_xsd_type_info_t p;
699 GlobusFuncName(globus_xsd_type_registry_clear);
700 554 GlobusSoapMessageDebugEnter();
701
702 554 if (registry == NULL)
703 {
704 0 result = GlobusSoapMessageErrorNullParam;
705
706 0 goto error;
707 }
708 554 rc = globus_mutex_lock(&registry->lock);
709 554 if (rc != GLOBUS_SUCCESS)
710 {
711 0 result = GlobusSoapMessageErrorOutOfMemory;
712
713 0 goto error;
714 }
715 554 rc = globus_hashtable_to_list(&registry->table, &tmp_list);
716 554 if (rc != GLOBUS_SUCCESS)
717 {
718 0 result = GlobusSoapMessageErrorNullParam;
719
720 0 goto unlock_error;
721 }
722 36881 while (!globus_list_empty(tmp_list))
723 {
724 35773 p = globus_list_remove(&tmp_list, tmp_list);
725
726 35773 globus_assert(p);
727
728 35773 globus_hashtable_remove(&registry->table, p->type);
729 }
730 554 rc = globus_hashtable_destroy(&registry->elements);
731 554 if (rc != GLOBUS_SUCCESS)
732 {
733 0 result = GlobusSoapMessageErrorNullParam;
734
735 0 goto unlock_error;
736 }
737 554 rc = globus_hashtable_init(
738 &registry->elements,
739 257,
740 xsd_QName_hash,
741 xsd_QName_keyeq);
742 554 if (rc != GLOBUS_SUCCESS)
743 {
744 0 result = GlobusSoapMessageErrorNullParam;
745
746 0 goto unlock_error;
747 }
748
749 554 globus_mutex_unlock(&registry->lock);
750
751 554 GlobusSoapMessageDebugExit();
752 554 return GLOBUS_SUCCESS;
753
754
755 0 unlock_error:
756 0 globus_mutex_unlock(&registry->lock);
757 0 error:
758 0 GlobusSoapMessageDebugExit();
759 0 return result;
760 }
761 /* globus_xsd_type_registry_clear() */
762
763 /**
764 * Look up a QName in a type registry
765 * @ingroup globus_xsd_type_registry
766 *
767 * Locate the type mapping for a given QName in a type registry and return it.
768 *
769 * @param registry
770 * Registry to query.
771 * @param name
772 * QName of the type to look up
773 * @param info
774 * Return parameter will be set to the type mapping for the given
775 * @a name if present.
776 *
777 * @retval GLOBUS_SUCCESS
778 * The type mapping lookup was processed. The @a info value may be NULL
779 * if no mapping for the given type is in the registry.
780 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
781 * The @a registry, @a name, or @a info parameter was NULL.
782 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
783 * Insufficient memory to get registry value.
784 */
785 globus_result_t
786 globus_xsd_type_registry_get(
787 globus_xsd_type_registry_t registry,
788 const xsd_QName * name,
789 globus_xsd_type_info_t * info)
790 2397 {
791 globus_result_t result;
792 int rc;
793 GlobusFuncName(globus_xsd_type_registry_get);
794 2397 GlobusSoapMessageDebugEnter();
795
796 2397 if (registry == NULL || name == NULL || info == NULL)
797 {
798 0 result = GlobusSoapMessageErrorNullParam;
799
800 0 goto error;
801 }
802 2397 rc = globus_mutex_lock(&registry->lock);
803 2397 if (rc != GLOBUS_SUCCESS)
804 {
805 0 result = GlobusSoapMessageErrorOutOfMemory;
806
807 0 goto error;
808 }
809 2397 *info = globus_hashtable_lookup(&registry->table, (void *) name);
810
811 2397 globus_mutex_unlock(&registry->lock);
812
813 2397 GlobusSoapMessageDebugExit();
814 2397 return GLOBUS_SUCCESS;
815 0 error:
816 0 GlobusSoapMessageDebugExit();
817 0 return result;
818 }
819 /* globus_xsd_type_registry_get() */
820
821 /**
822 * Look up an element QName in the type registry
823 * @ingroup globus_xsd_type_registry
824 *
825 * Locate the type mapping for a given element in a type registry and return it.
826 *
827 * @param registry
828 * Registry to query.
829 * @param element
830 * QName of the element to look up
831 * @param info
832 * Return parameter will be set to the type mapping for the given
833 * @a name if present.
834 *
835 * @retval GLOBUS_SUCCESS
836 * The type mapping lookup was processed. The @a info value may be NULL
837 * if no mapping for the given type is in the registry.
838 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
839 * The @a registry, @a name, or @a info parameter was NULL.
840 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
841 * Insufficient memory to get registry value.
842 */
843 globus_result_t
844 globus_xsd_type_registry_get_element(
845 globus_xsd_type_registry_t registry,
846 const xsd_QName * element,
847 globus_xsd_type_info_t * info)
848 2650961 {
849 2650961 globus_result_t result = GLOBUS_SUCCESS;
850 globus_i_xsd_element_map_t * map;
851 int rc;
852 GlobusFuncName(globus_xsd_type_registry_get_element);
853 2650961 GlobusSoapMessageDebugEnter();
854
855 2650961 if (registry == NULL || element == NULL || info == NULL)
856 {
857 0 result = GlobusSoapMessageErrorNullParam;
858
859 0 goto out;
860 }
861 2650961 rc = globus_mutex_lock(&registry->lock);
862 2650961 if (rc != GLOBUS_SUCCESS)
863 {
864 0 result = GlobusSoapMessageErrorOutOfMemory;
865
866 0 goto out;
867 }
868 2650961 map = globus_hashtable_lookup(&registry->elements, (void *) element);
869 2650961 if (map == NULL)
870 {
871 23183 *info = NULL;
872
873 23183 goto unlock_out;
874 }
875
876 2627778 *info = globus_hashtable_lookup(&registry->table, map->type);
877
878 2650961 unlock_out:
879 2650961 globus_mutex_unlock(&registry->lock);
880 2650961 out:
881 2650961 GlobusSoapMessageDebugExit();
882 2650961 return result;
883 }
884 /* globus_xsd_type_registry_get_element() */
885
886 /**
887 * Look up an attribute QName in the type registry
888 * @ingroup globus_xsd_type_registry
889 *
890 * Locate the type mapping for a given element in a type registry and return it.
891 *
892 * @param registry
893 * Registry to query.
894 * @param attribute
895 * QName of the attribute to look up
896 * @param info
897 * Return parameter will be set to the type mapping for the given
898 * @a name if present.
899 *
900 * @retval GLOBUS_SUCCESS
901 * The type mapping lookup was processed. The @a info value may be NULL
902 * if no mapping for the given type is in the registry.
903 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
904 * The @a registry, @a name, or @a info parameter was NULL.
905 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
906 * Insufficient memory to get registry value.
907 */
908 globus_result_t
909 globus_xsd_type_registry_get_attribute(
910 globus_xsd_type_registry_t registry,
911 const xsd_QName * attribute,
912 globus_xsd_type_info_t * info)
913 2725 {
914 2725 globus_result_t result = GLOBUS_SUCCESS;
915 globus_i_xsd_element_map_t * map;
916 int rc;
917 GlobusFuncName(globus_xsd_type_registry_get_attribute);
918 2725 GlobusSoapMessageDebugEnter();
919
920 2725 if (registry == NULL || attribute == NULL || info == NULL)
921 {
922 0 result = GlobusSoapMessageErrorNullParam;
923
924 0 goto out;
925 }
926 2725 rc = globus_mutex_lock(&registry->lock);
927 2725 if (rc != GLOBUS_SUCCESS)
928 {
929 0 result = GlobusSoapMessageErrorOutOfMemory;
930
931 0 goto out;
932 }
933 2725 map = globus_hashtable_lookup(&registry->attributes, (void *) attribute);
934 2725 if (map == NULL)
935 {
936 2719 *info = NULL;
937
938 2719 goto unlock_out;
939 }
940
941 6 *info = globus_hashtable_lookup(&registry->table, map->type);
942
943 2725 unlock_out:
944 2725 globus_mutex_unlock(&registry->lock);
945 2725 out:
946 2725 GlobusSoapMessageDebugExit();
947 2725 return result;
948 }
949 /* globus_xsd_type_registry_get_attribute() */
950
951 /**
952 * Add XML schema base types to a registry
953 * @ingroup globus_xsd_type_registry
954 *
955 * Inserts the XML schema basic types into the given type registry.
956 *
957 * @param registry
958 * Registry to update.
959 *
960 * @retval GLOBUS_SUCCESS
961 * Type mappings added.
962 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
963 * The @a registry parameter was NULL.
964 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
965 * Insufficient memory to add types to registry.
966 */
967 globus_result_t
968 globus_xsd_type_registry_add_base_types(
969 globus_xsd_type_registry_t registry)
970 1608 {
971 1608 globus_result_t result = GLOBUS_SUCCESS;
972 int i;
973 static globus_xsd_type_info_t builtin_types[] =
974 {
975 &xsd_ID_info,
976 &xsd_IDREF_info,
977 &xsd_IDREFS_info,
978 &xsd_ENTITY_info,
979 &xsd_ENTITIES_info,
980 &xsd_NCName_info,
981 &xsd_NMTOKEN_info,
982 &xsd_NMTOKENS_info,
983 &xsd_NOTATION_info,
984 &xsd_Name_info,
985 &xsd_QName_info,
986 &xsd_any_info,
987 &xsd_anyType_info,
988 &xsd_anyURI_info,
989 &xsd_base64Binary_info,
990 &xsd_boolean_info,
991 &xsd_byte_info,
992 &xsd_date_info,
993 &xsd_dateTime_info,
994 &xsd_decimal_info,
995 &xsd_double_info,
996 &xsd_duration_info,
997 &xsd_float_info,
998 &xsd_gDay_info,
999 &xsd_gMonth_info,
1000 &xsd_gMonthDay_info,
1001 &xsd_gYear_info,
1002 &xsd_gYearMonth_info,
1003 &xsd_hexBinary_info,
1004 &xsd_int_info,
1005 &xsd_integer_info,
1006 &xsd_language_info,
1007 &xsd_long_info,
1008 &xsd_negativeInteger_info,
1009 &xsd_nonNegativeInteger_info,
1010 &xsd_nonPositiveInteger_info,
1011 &xsd_normalizedString_info,
1012 &xsd_positiveInteger_info,
1013 &xsd_short_info,
1014 &xsd_string_info,
1015 &xsd_time_info,
1016 &xsd_token_info,
1017 &xsd_unsignedByte_info,
1018 &xsd_unsignedInt_info,
1019 &xsd_unsignedLong_info,
1020 &xsd_unsignedShort_info,
1021 NULL
1022 };
1023
1024 GlobusFuncName(globus_xsd_type_registry_add_base_types);
1025 1608 GlobusSoapMessageDebugEnter();
1026
1027 75576 for (i = 0; builtin_types[i] != NULL; i++)
1028 {
1029 73968 result = globus_xsd_type_registry_insert(
1030 registry,
1031 builtin_types[i],
1032 NULL);
1033 73968 if(result != GLOBUS_SUCCESS)
1034 {
1035 0 break;
1036 }
1037 }
1038
1039 1608 GlobusSoapMessageDebugExit();
1040 1608 return result;
1041 }
1042 /* globus_xsd_type_registry_add_base_types() */
1043
1044 /**
1045 * Dump the contents of an xsd type registry to the debug stream
1046 * @ingroup globus_xsd_type_registry
1047 *
1048 * @param registry
1049 * The registry to dump.
1050 *
1051 * @retval GLOBUS_SUCCESS
1052 * Registry successfully dumped.
1053 * @retval GLOBUS_MESSAGE_ERROR_TYPE_NULL_PARAM
1054 * The @a registry parameter was NULL.
1055 * @retval GLOBUS_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
1056 * Insufficient memory to dump registry.
1057 */
1058 globus_result_t
1059 globus_xsd_type_registry_dump(
1060 globus_xsd_type_registry_t registry)
1061 0 {
1062 0 globus_result_t result = GLOBUS_SUCCESS;
1063 globus_xsd_type_info_t info;
1064 0 int rc = 0;
1065 GlobusFuncName(globus_xsd_type_registry_dump);
1066 0 GlobusSoapMessageDebugEnter();
1067
1068 0 rc = globus_mutex_lock(&registry->lock);
1069 0 if (rc != GLOBUS_SUCCESS)
1070 {
1071 0 result = GlobusSoapMessageErrorOutOfMemory;
1072 0 goto error;
1073 }
1074
1075 0 info = globus_hashtable_first(&registry->table);
1076
1077 0 while(info)
1078 {
1079 0 GlobusSoapMessageDebugPrintf(
1080 GLOBUS_SOAP_MESSAGE_DEBUG_REGISTRY,
1081 ("{%s}%s\n",
1082 info->type->Namespace,
1083 info->type->local));
1084
1085 0 info = globus_hashtable_next(&registry->table);
1086 }
1087
1088 0 rc = globus_mutex_unlock(&registry->lock);
1089 0 if(rc != GLOBUS_SUCCESS)
1090 {
1091 0 result = GlobusSoapMessageErrorOutOfMemory;
1092 0 goto error;
1093 }
1094
1095 0 error:
1096
1097 0 GlobusSoapMessageDebugExit();
1098 0 return result;
1099 }
1100 /* globus_xsd_type_registry_dump() */
1101
1102 static
1103 void
1104 globus_l_element_map_free(
1105 void * p)
1106 8610 {
1107 8610 globus_i_xsd_element_map_t * map = p;
1108
1109 8610 xsd_QName_destroy(map->element);
1110 8610 xsd_QName_destroy(map->type);
1111
1112 8610 free(map);
1113 8610 }