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
18 #include "xsd_anyType.h"
19 #include "globus_soap_message.h"
20 #include "globus_soap_message_utils.h"
21 #include "globus_i_soap_message.h"
22 #include "globus_i_soap_message_wildcards.h"
23 #include "globus_xml_buffer.h"
24 #include "globus_i_xsd.h"
25
26 GLOBUS_I_XSD_DEFINE_QNAME(xsd, anyType);
27 0 GLOBUS_I_XSD_DEFINE_TYPE_INIT_ARRAY(xsd_anyType);
28 0 GLOBUS_I_XSD_DEFINE_TYPE_DESTROY_ARRAY(xsd_anyType);
29 0 GLOBUS_I_XSD_DEFINE_TYPE_COPY_ARRAY(xsd_anyType);
30 0 GLOBUS_I_XSD_DEFINE_TYPE_SERIALIZE_ARRAY(xsd_anyType);
31 0 GLOBUS_I_XSD_DEFINE_TYPE_DESERIALIZE_ARRAY(xsd_anyType);
32 0 GLOBUS_I_XSD_DEFINE_TYPE_ARRAY_PUSH(xsd_anyType);
33 452 GLOBUS_I_XSD_DEFINE_TYPE_INIT(xsd_anyType);
34 2952 GLOBUS_I_XSD_DEFINE_TYPE_DESTROY(xsd_anyType);
35 1523 GLOBUS_I_XSD_DEFINE_TYPE_COPY(xsd_anyType);
36 63 GLOBUS_I_XSD_DEFINE_INIT_CONTENTS_GENERIC(xsd_anyType);
37
38 globus_result_t
39 xsd_anyType_serialize_wrapper(
40     const xsd_QName *                   element_qname,
41     const void *                        instance,
42     globus_soap_message_handle_t        message_handle,
43     globus_xsd_element_options_t        options)
44 {
45 12     return xsd_anyType_serialize(
46         element_qname,
47         (xsd_anyType *) instance,
48         message_handle, options);
49 }
50
51 globus_result_t
52 xsd_anyType_deserialize_pointer_wrapper(
53     const xsd_QName *                   element_qname,
54     void **                             ip,
55     globus_soap_message_handle_t        message_handle,
56     globus_xsd_element_options_t        options)
57 30 {
58 30     return xsd_anyType_deserialize_pointer(
59         element_qname,
60         (xsd_anyType **) ip,
61         message_handle, options);
62 }
63
64 struct globus_xsd_type_info_s xsd_anyType_info =
65 {
66     &xsd_anyType_qname,
67     xsd_anyType_serialize_wrapper,
68     xsd_anyType_deserialize_pointer_wrapper,
69     xsd_anyType_init_wrapper,
70     xsd_anyType_destroy_wrapper,
71     xsd_anyType_copy_wrapper,
72     xsd_anyType_init_contents_wrapper,
73     xsd_anyType_destroy_contents_wrapper,
74     xsd_anyType_copy_contents_wrapper,
75     sizeof(xsd_anyType),
76     NULL,
77     NULL,
78     NULL
79 };
80
81 struct globus_xsd_type_info_s xsd_anyType_array_info =
82 {
83     &xsd_anyType_qname,
84     xsd_anyType_array_serialize_wrapper,
85     xsd_anyType_array_deserialize_wrapper,
86     xsd_anyType_array_init_wrapper,
87     xsd_anyType_array_destroy_wrapper,
88     xsd_anyType_array_copy_wrapper,
89     xsd_anyType_array_init_contents_wrapper,
90     xsd_anyType_array_destroy_contents_wrapper,
91     xsd_anyType_array_copy_contents_wrapper,
92     sizeof(xsd_anyType),
93     xsd_anyType_array_push_wrapper,
94     NULL,
95     NULL
96 };
97
98 struct globus_xsd_type_info_s xsd_anyType_contents_info =
99 {
100     &xsd_anyType_qname,
101     xsd_anyType_serialize_wrapper,
102     xsd_anyType_deserialize_pointer_wrapper,
103     xsd_anyType_init_wrapper,
104     xsd_anyType_destroy_wrapper,
105     xsd_anyType_copy_wrapper,
106     xsd_anyType_init_contents_wrapper,
107     xsd_anyType_destroy_contents_wrapper,
108     xsd_anyType_copy_contents_wrapper,
109     sizeof(xsd_anyType),
110     NULL,
111     NULL,
112     NULL
113 };
114
115 void
116 xsd_anyType_destroy_contents(
117     xsd_anyType *                       instance)
118 1522 {
119 1522     GlobusFuncName(xsd_anyType_destroy_contents);
120 1522     GlobusSoapMessageDebugEnter();
121
122 1522     if(instance && instance->value && instance->any_info)
123     {
124 1385         instance->any_info->destroy(instance->value);
125 1385         instance->value = NULL;
126     }
127
128 1522     GlobusSoapMessageDebugExit();
129 }
130
131 globus_result_t
132 xsd_anyType_copy_contents(
133     xsd_anyType *                       dest,
134     const xsd_anyType *                 src)
135 1081 {
136 1081     globus_result_t                     result = GLOBUS_SUCCESS;
137 1081     GlobusFuncName(xsd_anyType_copy_contents);
138 1081     GlobusSoapMessageDebugEnter();
139
140 1081     if(dest && src)
141     {
142 1081         *dest = *src;
143 1081         if(src->value && src->any_info)
144         {
145 1019             result = src->any_info->copy(&dest->value, src->value);
146         }
147     }
148
149 1081     GlobusSoapMessageDebugExit();
150 1081     return result;
151 }
152
153 globus_result_t
154 xsd_anyType_serialize(
155     const xsd_QName *                   element_qname,
156     const xsd_anyType *                 anyinst,
157     globus_soap_message_handle_t        message_handle,
158     globus_xsd_element_options_t        options)
159 97 {
160 97     globus_result_t                     result = GLOBUS_SUCCESS;
161 97     globus_bool_t                       skip_type_info = GLOBUS_FALSE;
162 97     GlobusFuncName(xsd_anyType_serialize);
163 97     GlobusSoapMessageDebugEnter();
164
165 97     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
166     {
167         /* add begin element (always act like GLOBUS_XSD_ELEMENT_TYPE_ATTR is
168          * set for anyType). But, if the type QName is globus_xml_buffer_qname,
169          * we'll not actually serialize it.
170          */
171
172 97         if (anyinst->any_info != NULL &&
173             anyinst->any_info->type != NULL &&
174             xsd_QName_keyeq(
175                 anyinst->any_info->type,
176                 &globus_xml_buffer_qname))
177         {
178 23             skip_type_info = GLOBUS_TRUE;
179         }
180
181
182 97         result = globus_soap_message_attribute_ns_set(
183             message_handle,
184             element_qname,
185             "http://www.w3.org/2001/XMLSchema-instance",
186             &options);
187 97         if(result != GLOBUS_SUCCESS)
188         {
189 0             result = GlobusSoapMessageErrorSerializeFailed(
190                 result, NULL, element_qname);
191 0             goto exit;
192         }
193
194 97         result = globus_soap_message_attribute_ns_set(
195             message_handle,
196             element_qname,
197             xsd_QName_qname.Namespace,
198             &options);
199 97         if(result != GLOBUS_SUCCESS)
200         {
201 0             result = GlobusSoapMessageErrorSerializeFailed(
202                 result, NULL, element_qname);
203 0             goto exit;
204         }
205
206 97         result = globus_soap_message_element_ns_set(
207             message_handle,
208             element_qname,
209             element_qname->Namespace,
210             &options);
211
212 97         if(result != GLOBUS_SUCCESS)
213         {
214 0             result = GlobusSoapMessageErrorSerializeFailed(
215                 result, NULL, element_qname);
216 0             goto exit;
217         }
218
219 97         if (anyinst->any_info != NULL &&
220             anyinst->any_info->type != NULL &&
221             !skip_type_info)
222         {
223 32             result = globus_soap_message_element_ns_set(
224                 message_handle,
225                 element_qname,
226                 anyinst->any_info->type->Namespace,
227                 &options);
228
229 32             if(result != GLOBUS_SUCCESS)
230             {
231 0                 result = GlobusSoapMessageErrorSerializeFailed(
232                     result, NULL, element_qname);
233 0                 goto exit;
234             }
235         }
236
237 97         result = globus_soap_message_serialize_element(
238                 message_handle,
239                 element_qname,
240                 options | GLOBUS_XSD_ELEMENT_TYPE_ATTR,
241                 (anyinst->any_info != NULL)
242                     ? anyinst->any_info->type
243                     : NULL);
244
245 97         if(result != GLOBUS_SUCCESS)
246         {
247 0             result = GlobusSoapMessageErrorSerializeFailed(
248                 result,
249                 "Serialization of xsd:anyType failed",
250                 element_qname);
251 0             goto exit;
252         }
253
254 97         result = globus_soap_message_attribute_ns_add(
255                 message_handle,
256                 element_qname,
257                 "http://www.w3.org/2001/XMLSchema-instance",
258                 &options);
259 97         if(result != GLOBUS_SUCCESS)
260         {
261 0             result = GlobusSoapMessageErrorSerializeFailed(
262                 result,
263                 "Serialization of xsd:anyType failed",
264                 element_qname);
265 0             goto exit;
266         }
267
268 97         result = globus_soap_message_element_ns_add(
269                 message_handle,
270                 element_qname,
271                 element_qname->Namespace,
272                 &options);
273 97         if(result != GLOBUS_SUCCESS)
274         {
275 0             result = GlobusSoapMessageErrorSerializeFailed(
276                 result,
277                 "Serialization of xsd:anyType failed",
278                 element_qname);
279 0             goto exit;
280         }
281 97         if (anyinst->any_info != NULL &&
282             anyinst->any_info->type != NULL &&
283             !skip_type_info)
284         {
285 32             xsd_QName                   type_attr;
286
287 32             result = globus_soap_message_element_ns_add(
288                 message_handle,
289                 element_qname,
290                 anyinst->any_info->type->Namespace,
291                 &options);
292
293 32             if(result != GLOBUS_SUCCESS)
294             {
295 0                 result = GlobusSoapMessageErrorSerializeFailed(
296                     result, NULL, element_qname);
297 0                 goto exit;
298             }
299 32             type_attr.local = "type";
300 32             type_attr.Namespace =
301                     "http://www.w3.org/2001/XMLSchema-instance";
302 32             result = globus_soap_message_serialize_QName_attribute(
303                 message_handle,
304                 &type_attr,
305                 anyinst->any_info->type);
306 32             if(result != GLOBUS_SUCCESS)
307             {
308 0                 result = GlobusSoapMessageErrorSerializeFailed(
309                     result, NULL, element_qname);
310 0                 goto exit;
311             }
312         }
313
314 97         result = globus_soap_message_serialize_element_begin_close(
315                 message_handle, element_qname);
316 97         if(result != GLOBUS_SUCCESS)
317         {
318 0             result = GlobusSoapMessageErrorSerializeFailed(
319                 result,
320                 "Serialization of xsd:anyType failed",
321                 element_qname);
322 0             goto exit;
323         }
324     }
325
326 97     if (anyinst->any_info != NULL)
327     {
328         /* serialize contents of type */
329 55         result = anyinst->any_info->serialize(
330             element_qname,
331             anyinst->value,
332             message_handle,
333             options | GLOBUS_XSD_ELEMENT_TYPE_ATTR
334                     | GLOBUS_XSD_ELEMENT_CONTENTS_ONLY);
335 55         if(result != GLOBUS_SUCCESS)
336         {
337 0             result = GlobusSoapMessageErrorSerializeFailed(
338                 result,
339                 "Serialization of xsd:any failed",
340                 element_qname);
341 0             goto exit;
342         }
343     }
344
345 97     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
346     {
347 97         result = globus_soap_message_serialize_element_end(
348                 message_handle,
349                 element_qname,
350                 options,
351                 NULL);
352 97         if(result != GLOBUS_SUCCESS)
353         {
354 0             result = GlobusSoapMessageErrorSerializeFailed(
355                 result,
356                 "Serialization of empty xsd:anyType failed",
357                 element_qname);
358 0             goto exit;
359         }
360 97         if (anyinst->any_info != NULL &&
361             anyinst->any_info->type != NULL &&
362             !skip_type_info)
363         {
364 32             globus_soap_message_element_ns_remove(
365                 message_handle,
366                 anyinst->any_info->type->Namespace,
367                 &options);
368         }
369 97         globus_soap_message_element_ns_remove(
370                 message_handle,
371                 element_qname->Namespace,
372                 &options);
373
374 97         if (!skip_type_info)
375         {
376 74             globus_soap_message_attribute_ns_remove(
377                     message_handle,
378                     "http://www.w3.org/2001/XMLSchema-instance",
379                     &options);
380         }
381     }
382
383  exit:
384
385 97     GlobusSoapMessageDebugExit();
386 97     return result;
387 }
388
389 globus_result_t
390 xsd_anyType_deserialize(
391     const xsd_QName *                   element_qname,
392     xsd_anyType *                       instance,
393     globus_soap_message_handle_t        message_handle,
394     globus_xsd_element_options_t        options)
395 123 {
396 123     globus_result_t                     result = GLOBUS_SUCCESS;
397 123     globus_bool_t                       empty = GLOBUS_FALSE;
398 123     globus_bool_t                       no_element = GLOBUS_FALSE;
399 123     GlobusFuncName(xsd_anyType_deserialize);
400 123     GlobusSoapMessageDebugEnter();
401
402 123     result = globus_soap_message_deserialize_element(
403         message_handle, element_qname);
404 123     if(result != GLOBUS_SUCCESS)
405     {
406 0         if(GlobusSoapMessageStatusFailedWithTextCheck(result))
407         {
408 0             no_element = GLOBUS_TRUE;
409 0             result = GLOBUS_SUCCESS;
410         }
411 0         else if(!GlobusSoapMessageStatusCheck(result))
412         {
413 0             result = GlobusSoapMessageErrorDeserializeFailed(
414                 result, element_qname);
415 0             goto exit;
416         }
417         else
418         {
419 123             goto exit;
420         }
421     }
422
423 123     if (globus_soap_message_deserialize_element_is_empty(message_handle))
424     {
425 50         empty = GLOBUS_TRUE;
426     }
427
428 123     if (! no_element)
429     {
430         /* Push the element back if there was one. If we are deserializing
431          * contents only, then the element is part of the contents, otherwise,
432          * the deserializer in the any_info will want to see the element.
433          */
434 123         globus_soap_message_deserialize_push_element(message_handle);
435     }
436
437 123     GlobusSoapMessageDebugPrintf(
438         GLOBUS_SOAP_MESSAGE_DEBUG_WILDCARDS, 
439         ("\n\nDeserializing xsd:anyType\n"));
440
441 123     result = globus_i_xsd_deserialize_from_xsi_type(
442         &instance->any_info,
443         instance->registry,
444         message_handle);
445 123     if(result != GLOBUS_SUCCESS)
446     {
447 0         result = GlobusSoapMessageErrorDeserializeFailed(
448             result, element_qname);
449 0         goto exit;
450     }
451
452 123     if(!instance->any_info)
453     {
454 102         instance->any_info = (&globus_xml_buffer_info);
455     }
456
457 123     GlobusSoapMessageDebugPrintf(
458         GLOBUS_SOAP_MESSAGE_DEBUG_WILDCARDS, 
459         ("Using any info: {%s}%s\n",
460          instance->any_info->type->Namespace,
461          instance->any_info->type->local));
462
463 123     if (!empty)
464     {
465 73         result = instance->any_info->deserialize(
466             element_qname,
467             &instance->value,
468             message_handle,
469             options);
470 73         if(result != GLOBUS_SUCCESS)
471         {
472 0             result = GlobusSoapMessageErrorDeserializeFailed(
473                 result, instance->any_info->type);
474 0             goto exit;
475         }
476     }
477 50     else if (!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
478     {
479 50         result = globus_soap_message_deserialize_element_end(
480             message_handle,
481             element_qname);
482     }
483
484
485  exit:
486
487 123     if(result != GLOBUS_SUCCESS)
488     {
489 0         xsd_anyType_destroy_contents(instance);
490     }
491
492 123     GlobusSoapMessageDebugExit();
493 123     return result;
494 }
495
496 globus_result_t
497 xsd_anyType_deserialize_pointer(
498     const xsd_QName *                   element_qname,
499     xsd_anyType **                      ip,
500     globus_soap_message_handle_t        message_handle,
501     globus_xsd_element_options_t        options)
502 81 {
503 81     xsd_anyType *                       instance = NULL;
504 81     globus_result_t                     result = GLOBUS_SUCCESS;
505 81     globus_bool_t                       empty = GLOBUS_FALSE;
506 81     GlobusFuncName(xsd_any_deserialize_pointer);
507 81     GlobusSoapMessageDebugEnter();
508
509 81     result = globus_soap_message_deserialize_element(
510         message_handle, element_qname);
511 81     if(result != GLOBUS_SUCCESS)
512     {
513 49         if(GlobusSoapMessageStatusElementNotFoundCheck(result) ||
514            GlobusSoapMessageStatusFailedElementCheck(result))
515         {
516 49             *ip = NULL;
517 49             result = GLOBUS_SUCCESS;
518
519 49             goto exit;
520         }
521
522 0         if(!GlobusSoapMessageStatusCheck(result))
523         {
524 0             result = GlobusSoapMessageErrorDeserializeFailed(
525                 result, element_qname);
526 0             goto exit;
527         }
528 32         goto exit;
529     }
530
531 32     if (globus_soap_message_deserialize_element_is_empty(message_handle))
532     {
533 30         empty = GLOBUS_TRUE;
534     }
535
536 32     globus_soap_message_deserialize_push_element(message_handle);
537
538 32     GlobusSoapMessageDebugPrintf(
539         GLOBUS_SOAP_MESSAGE_DEBUG_WILDCARDS, 
540         ("\n\nDeserializing xsd:anyType\n"));
541
542 32     result = xsd_anyType_init(&instance);
543 32     if(result != GLOBUS_SUCCESS)
544     {
545 0         result = GlobusSoapMessageErrorDeserializeFailed(
546             result, &xsd_anyType_qname);
547 0         goto exit;
548     }
549
550 32     result = globus_i_xsd_deserialize_from_xsi_type(
551         &instance->any_info,
552         instance->registry,
553         message_handle);
554 32     if(result != GLOBUS_SUCCESS)
555     {
556 0         result = GlobusSoapMessageErrorDeserializeFailed(
557             result, element_qname);
558 0         goto exit;
559     }
560
561
562 32     if(!instance->any_info)
563     {
564 32         instance->any_info = (&globus_xml_buffer_info);
565     }
566
567 32     if (!empty)
568     {
569 2         result = instance->any_info->deserialize(
570             element_qname,
571             &instance->value,
572             message_handle,
573             options);
574 2         if(result != GLOBUS_SUCCESS)
575         {
576 0             result = GlobusSoapMessageErrorDeserializeFailed(
577                 result, instance->any_info->type);
578 0             goto exit;
579         }
580     }
581 30     else if (!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
582     {
583 30         result = globus_soap_message_deserialize_element_end(
584             message_handle,
585             element_qname);
586     }
587
588 32     *ip = instance;
589
590  exit:
591
592 81     if(result != GLOBUS_SUCCESS && instance)
593     {
594 0         xsd_anyType_destroy(instance);
595     }
596
597 81     GlobusSoapMessageDebugExit();
598 81     return result;