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_soap_message.h"
13 #include "globus_wsrf_resource.h"
14 #include "globus_service_engine.h"
15 #include "globus_operation_provider.h"
16 #include "globus_service_registry.h"
17 #include "globus_wsrf_core_tools.h"
18 #include "globus_service_registry.h"
19 #include "version.h"
20
21 #include "wsrp_SetResourcePropertiesType.h"
22 #include "wsrp_SetResourcePropertiesResponseType.h"
23
24 #define WSRP_SET_RESOURCE_PROPERTIES 1
25 #define NEED_UNABLE_TO_MODIFY_RESOURCE_PROPERTY_FAULT 0
26
27 #include "wsrp_i_faults.h"
28
29 /**
30  * @page wsrp_SetResourceProperties_provider SetResourceProperties Provider
31  *
32  * <h2>Provider Usage Overview</h2>
33  * This operation provider implements the SetResourceProperties portType defined
34  * in
35  * http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl .
36  * This portType consists of the @a SetResourceProperties operation and
37  * related faults.
38  *
39  * The WSRF service engine will automatically register this provider to handle
40  * the SetResourceProperties operation for services which use the port type.
41  *
42  * <h2>Limitations</h2>
43  * - This provider does not provide any transactional behavior when multiple
44  * Insert, Update, or Delete elements are present in the
45  * SetResourcePropertiesRequest element, nor does it prevent concurrent
46  * accesses to resource property values
47  * - This provider does not implement read-only resource properties.
48  * - The minOccurs and maxOccurs attributes are extremely loosely enforced.
49  *   If neither are present, then a resource property may have exactly one
50  *   value. If either are present, then the resource property is effectively
51  *   unbounded.
52  */
53
54 static
55 int
56 wsrp_SetResourceProperties_activate(void);
57
58 static
59 int
60 wsrp_SetResourceProperties_deactivate(void);
61
62 GlobusExtensionDefineModule(globus_ws_resource_properties) =
63 {
64     "wsrp_SetResourceProperties",
65     wsrp_SetResourceProperties_activate,
66     wsrp_SetResourceProperties_deactivate,
67     NULL,
68     NULL,
69     &local_version
70 };
71
72 /* Prototypes */
73 static
74 globus_result_t
75 wsrp_SetResourceProperties_init_provider(
76     globus_service_engine_t             engine,
77     globus_soap_message_handle_t        handle,
78     wsrp_SetResourcePropertiesType *    SetResourceProperties);
79
80 static
81 globus_result_t
82 wsrp_SetResourceProperties_provider(
83     globus_service_engine_t             engine,
84     globus_soap_message_handle_t        handle,
85     globus_service_descriptor_t *       service,
86     wsrp_SetResourcePropertiesType *    SetResourceProperties,
87     wsrp_SetResourcePropertiesResponseType *
88                                         SetResourcePropertiesResponse,
89     char **                             fault_name,
90     void **                             fault);
91
92 static
93 globus_result_t
94 wsrp_l_InsertResourceProperty(
95     globus_resource_t                   resource,
96     xsd_any_array *                     any,
97     char **                             fault_name,
98     void **                             fault);
99
100 static
101 globus_result_t
102 wsrp_l_UpdateResourceProperty(
103     globus_resource_t                   resource,
104     xsd_any_array *                     any,
105     char **                             fault_name,
106     void **                             fault);
107
108 static
109 globus_result_t
110 wsrp_l_DeleteResourceProperty(
111     globus_resource_t                   resource,
112     xsd_QName *                         qname,
113     char **                             fault_name,
114     void **                             fault);
115
116 static
117 globus_result_t
118 wsrp_l_check_for_uniformity(
119     xsd_any_array *                     any_array,
120     char **                             fault_name,
121     void **                             fault);
122
123 /* Local Variables */
124 static xsd_QName wsrp_SetResourceProperties_qname =
125 {
126     "http://www.globus.org/docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl",
127     "SetResourceProperties"
128 };
129
130 static
131 globus_operation_provider_descriptor_t
132 wsrp_SetResourceProperties_descriptor =
133 {
134     &wsrp_SetResourceProperties_qname,
135     "SetResourceProperties",
136     (void *)wsrp_SetResourceProperties_init_provider,
137     (void *)wsrp_SetResourceProperties_provider
138 };
139
140 /* Implementation */
141
142 static
143 globus_result_t
144 wsrp_SetResourceProperties_init_provider(
145     globus_service_engine_t             engine,
146     globus_soap_message_handle_t        handle,
147     wsrp_SetResourcePropertiesType *    SetResourceProperties)
148 129 {
149 129     return GLOBUS_SUCCESS;
150 }
151 /* wsrp_SetResourceProperties_init_provider() */
152
153 static
154 globus_result_t
155 wsrp_SetResourceProperties_provider(
156     globus_service_engine_t             engine,
157     globus_soap_message_handle_t        handle,
158     globus_service_descriptor_t *       service,
159     wsrp_SetResourcePropertiesType *    SetResourceProperties,
160     wsrp_SetResourcePropertiesResponseType *
161                                         SetResourcePropertiesResponse,
162     char **                             fault_name,
163     void **                             fault)
164 129 {
165 129     globus_resource_t                   resource;
166 129     globus_result_t                     result;
167 129     int                                 i;
168 129     xsd_any_array *                     any;
169
170 129     *fault_name = NULL;
171 129     *fault  = NULL;
172
173 129     result = globus_wsrf_core_get_resource(
174             handle,
175             service,
176             &resource);
177
178 129     if (result != GLOBUS_SUCCESS || resource == NULL)
179     {
180 0         result = RESOURCE_UNKNOWN(fault_name, fault);
181
182 0         goto out;
183     }
184
185 206     for (i = 0; i < SetResourceProperties->choice_value.length; i++)
186     {
187 129         switch (SetResourceProperties->choice_value.elements[i].type)
188         {
189             case wsrp_SetResourcePropertiesType_Insert:
190 59                 any = &SetResourceProperties->choice_value.elements[i].
191                             value.Insert.any,
192                 result = wsrp_l_check_for_uniformity(any, fault_name, fault);
193 59                 if (result != GLOBUS_SUCCESS || *fault != NULL)
194                 {
195 51                     goto finish_out;
196                 }
197 51                 result = wsrp_l_InsertResourceProperty(
198                         resource,
199                         any,
200                         fault_name,
201                         fault);
202
203 51                 if (result != GLOBUS_SUCCESS || *fault != NULL)
204                 {
205 57                     goto finish_out;
206                 }
207
208 57                 break;
209
210             case wsrp_SetResourcePropertiesType_Update:
211 57                 any = &SetResourceProperties->choice_value.elements[i].
212                             value.Update.any,
213                 result = wsrp_l_check_for_uniformity(any, fault_name, fault);
214 57                 if (result != GLOBUS_SUCCESS || *fault != NULL)
215                 {
216 49                     goto finish_out;
217                 }
218 49                 result = wsrp_l_UpdateResourceProperty(
219                         resource,
220                         any,
221                         fault_name,
222                         fault);
223
224 49                 if (result != GLOBUS_SUCCESS || *fault != NULL)
225                 {
226 13                     goto finish_out;
227                 }
228
229 13                 break;
230
231             case wsrp_SetResourcePropertiesType_Delete:
232 13                 result = wsrp_l_DeleteResourceProperty(
233                         resource,
234                         &SetResourceProperties->choice_value.elements[i].
235                             value.Delete._ResourceProperty,
236                         fault_name,
237                         fault);
238
239 13                 if (result != GLOBUS_SUCCESS || *fault != NULL)
240                 {
241 0                     goto finish_out;
242                 }
243 0                 break;
244
245             case wsrp_SetResourcePropertiesType_undefined:
246 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
247                         fault_name,
248                         fault);
249 0                 goto finish_out;
250         }
251     }
252
253 finish_out:
254 129     globus_resource_finish(resource);
255 out:
256 129     return result;
257 }
258 /* wsrp_SetResourceProperties_provider() */
259
260 static
261 int
262 wsrp_SetResourceProperties_activate(void)
263 29 {
264 29     int                                 res = 0;
265 29     GlobusFuncName(wsrp_SetResourceProperties_activate);
266     
267 29     res = globus_extension_registry_add(
268         GLOBUS_OPERATION_PROVIDER_REGISTRY,
269         &wsrp_SetResourceProperties_qname,
270         GlobusExtensionMyModule(globus_ws_resource_properties),
271         &wsrp_SetResourceProperties_descriptor);
272
273 29     return res;
274 }
275 /* wsrp_SetResourceProperties_activate()) */
276
277 static
278 int
279 wsrp_SetResourceProperties_deactivate(void)
280 0 {
281 0     GlobusFuncName(wsrp_SetResourceProperties_deactivate);
282
283 0     globus_extension_registry_remove(
284         GLOBUS_OPERATION_PROVIDER_REGISTRY,
285         &wsrp_SetResourceProperties_qname);
286
287 0     return 0;
288 }
289 /* wsrp_SetResourceProperties_deactivate() */
290
291 /** 
292  * Insert a new RP element to the RP document.
293  */
294 static
295 globus_result_t
296 wsrp_l_InsertResourceProperty(
297     globus_resource_t                   resource,
298     xsd_any_array *                     any,
299     char **                             fault_name,
300     void **                             fault)
301 51 {
302 51     globus_result_t                     result = GLOBUS_SUCCESS;
303 51     globus_xsd_type_info_t              prop_info;
304 51     globus_xsd_type_info_t              array_info;
305 51     void *                              prop_value;
306 51     xsd_any *                           prop_any;
307 51     globus_bool_t                       use_any = GLOBUS_FALSE;
308 51     int                                 i;
309 51     globus_object_t *                   error;
310 51     void *                              copy_value = NULL;
311
312 51     result = globus_resource_get_property(
313             resource,
314             any->elements[0].element,
315             &prop_value,
316             &prop_info);
317
318 51     if (result != GLOBUS_SUCCESS)
319     {
320         /* The property QName doesn't appear to be in our RP document */
321 8         error = globus_error_get(result);
322 8         if (globus_error_match(
323                 error,
324                 GLOBUS_WSRF_RESOURCE_MODULE,
325                 GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_PROPERTY))
326         {
327 8             result = INVALID_RESOURCE_PROPERTY_QNAME(fault_name, fault);
328         }
329         else
330         {
331 0             result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(fault_name, fault);
332         }
333 8         globus_object_free(error);
334 8         goto out;
335     }
336
337 43     if (prop_info == &xsd_any_info)
338     {
339         /* Got an any */
340 20         prop_any = prop_value;
341
342 20         if (prop_any->any_info == NULL ||
343             prop_any->any_info == any->elements[0].any_info)
344         {
345             /* Single value info */
346 10             if (any->length > 1 || prop_any->value != NULL)
347             {
348                 /* Only a single value will fit in the any */
349 4                 result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
350                         fault_name,
351                         fault);
352 4                 goto out;
353             }
354 6             if (prop_any->element == NULL)
355             {
356                 /* The any is new, we'll need to set element and info */
357 6                 prop_any->any_info = any->elements[0].any_info;
358 6                 result = xsd_QName_copy(
359                         &prop_any->element,
360                         any->elements[0].element);
361
362 6                 if (result != GLOBUS_SUCCESS)
363                 {
364 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
365                             fault_name,
366                             fault);
367
368 0                     goto out;
369                 }
370             }
371
372             /* Copy the content of the any passed in to this function to the
373              * any in the RP document
374              */
375 6             result = any->elements[0].any_info->copy(
376                     &prop_any->value,
377                     any->elements[0].value);
378 6             if (result != GLOBUS_SUCCESS)
379             {
380 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
381                         fault_name,
382                         fault);
383 0                 goto out;
384             }
385         }
386 10         else if (prop_any->any_info == &xsd_any_array_info ||
387             prop_any->any_info == any->elements[0].any_info->array_info)
388         {
389 10             if (prop_any->element == NULL)
390             {
391                 /* New any with hint that we can stick as many as we like here
392                  */
393 6                 result = xsd_QName_copy(
394                         &prop_any->element,
395                         any->elements[0].element);
396
397 6                 if (result != GLOBUS_SUCCESS)
398                 {
399 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
400                             fault_name,
401                             fault);
402
403 0                     goto out;
404                 }
405                 /* Make new array for values */
406 6                 array_info = any->elements[0].any_info->array_info;
407 6                 if (any->elements[0].any_info->array_info == NULL)
408                 {
409                     /* No array info? I guess use the any one */
410 2                     array_info = &xsd_any_array_info;
411 2                     use_any = GLOBUS_TRUE;
412                 }
413 6                 result = array_info->initialize(&prop_any->value);
414 6                 if (result != GLOBUS_SUCCESS)
415                 {
416 0                     xsd_QName_destroy(prop_any->element);
417 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
418                             fault_name,
419                             fault);
420
421 0                     goto out;
422                 }
423 6                 prop_any->any_info = array_info;
424             }
425
426             /* Add new values to the any array now */
427 26             for (i = 0; i < any->length; i++)
428             {
429 16                 copy_value = prop_any->any_info->push(prop_any->value);
430
431 16                 if (copy_value == NULL)
432                 {
433 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
434                             fault_name,
435                             fault);
436 0                     goto out;
437                 }
438
439 16                 if (!use_any)
440                 {
441 12                     result = any->elements[i].any_info->copy_contents(
442                             copy_value,
443                             any->elements[i].value);
444                 }
445                 else
446                 {
447 4                     xsd_any_info.copy_contents(
448                             copy_value,
449                             &any->elements[i]);
450                 }
451 16                 if (result != GLOBUS_SUCCESS)
452                 {
453 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
454                             fault_name,
455                             fault);
456 0                     goto out;
457                 }
458             }
459         }
460     }
461 23     else if (any->elements[0].any_info == prop_info)
462     {
463         /* The RP element and this element have the same type. We're OK
464          * If there's only one element in the any.
465          */
466 12         if (any->length > 1 || prop_value != NULL)
467         {
468 4             result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
469                     fault_name,
470                     fault);
471 4             goto out;
472         }
473 8         prop_info->copy(&copy_value, any->elements[0].value);
474 8         result = globus_resource_set_property(
475                 resource,
476                 any->elements[0].element,
477                 copy_value);
478 8         if (result != GLOBUS_SUCCESS)
479         {
480 0             error = globus_error_get(result);
481
482 0             if (globus_error_match(
483                     error,
484                     GLOBUS_WSRF_RESOURCE_MODULE,
485                     GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_PROPERTY))
486             {
487 0                 result = INVALID_RESOURCE_PROPERTY_QNAME(fault_name, fault);
488             }
489             else
490             {
491 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
492                         fault_name,
493                         fault);
494             }
495 0             globus_object_free(error);
496
497 0             goto out;
498         }
499     }
500 11     else if (any->elements[0].any_info->array_info == prop_info)
501     {
502         /* The RP element is an array of the type we have in the any, so
503          * we'll need to add the new values to the array.
504          */
505 7         void * array_value = prop_value;
506
507 7         if (array_value == NULL)
508         {
509 4             result = prop_info->initialize(&array_value);
510 4             if (result != GLOBUS_SUCCESS)
511             {
512 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
513                         fault_name,
514                         fault);
515 0                 goto out;
516             }
517 4             result = globus_resource_set_property(
518                     resource,
519                     any->elements[0].element,
520                     array_value);
521
522 4             if (result != GLOBUS_SUCCESS)
523             {
524 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
525                         fault_name,
526                         fault);
527 0                 goto out;
528             }
529         }
530
531 20         for (i = 0; i < any->length; i++)
532         {
533 13             copy_value =
534                 any->elements[i].any_info->array_info->push(array_value);
535 13             any->elements[i].any_info->copy_contents(
536                     copy_value,
537                     any->elements[i].value);
538         }
539     }
540     else
541     {
542         /* The types don't match at all, we can't do anything about that */
543 4         result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
544                 fault_name,
545                 fault);
546         goto out;
547     }
548 out:
549 51     return result;
550 }
551 /* wsrp_l_InsertResourceProperty() */
552
553 static
554 globus_result_t
555 wsrp_l_UpdateResourceProperty(
556     globus_resource_t                   resource,
557     xsd_any_array *                     any,
558     char **                             fault_name,
559     void **                             fault)
560 49 {
561 49     globus_result_t                     result = GLOBUS_SUCCESS;
562 49     globus_xsd_type_info_t              prop_info;
563 49     void *                              prop_value;
564 49     xsd_any *                           prop_any;
565 49     globus_xsd_type_info_t              old_info;
566 49     globus_xsd_type_info_t              array_info;
567 49     globus_bool_t                       use_any = GLOBUS_FALSE;
568 49     xsd_QName *                         old_element;
569 49     void *                              old_value;
570 49     int                                 i;
571 49     globus_object_t *                   error;
572 49     void *                              copy_value = NULL;
573
574 49     result = globus_resource_get_property(
575             resource,
576             any->elements[0].element,
577             &prop_value,
578             &prop_info);
579
580 49     if (result != GLOBUS_SUCCESS)
581     {
582         /* The property QName doesn't appear to be in our RP document */
583 8         error = globus_error_get(result);
584 8         if (globus_error_match(
585                 error,
586                 GLOBUS_WSRF_RESOURCE_MODULE,
587                 GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_PROPERTY))
588         {
589 8             result = INVALID_RESOURCE_PROPERTY_QNAME(fault_name, fault);
590         }
591         else
592         {
593 0             result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(fault_name, fault);
594         }
595
596 8         globus_object_free(error);
597 8         goto out;
598     }
599
600 41     if (prop_info == &xsd_any_info)
601     {
602         /* Got an any */
603 22         prop_any = prop_value;
604
605 22         if (prop_any->any_info == NULL ||
606             prop_any->any_info == any->elements[0].any_info)
607         {
608             /* Single value info */
609 10             if (any->length > 1)
610             {
611                 /* Only a single value will fit in the any */
612 2                 result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
613                         fault_name,
614                         fault);
615 2                 goto out;
616             }
617
618 8             old_value = prop_any->value;
619 8             old_info = prop_any->any_info;
620
621 8             if (prop_any->element == NULL)
622             {
623                 /* The any is new, we'll need to set element and info */
624 6                 prop_any->any_info = any->elements[0].any_info;
625 6                 result = xsd_QName_copy(
626                         &prop_any->element,
627                         any->elements[0].element);
628
629 6                 if (result != GLOBUS_SUCCESS)
630                 {
631 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
632                             fault_name,
633                             fault);
634
635 0                     goto out;
636                 }
637             }
638
639             /* Copy the content of the any passed in to this function to the
640              * any in the RP document
641              */
642 8             result = any->elements[0].any_info->copy(
643                     &prop_any->value,
644                     any->elements[0].value);
645 8             if (result != GLOBUS_SUCCESS)
646             {
647 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
648                         fault_name,
649                         fault);
650 0                 goto out;
651             }
652
653 8             if (old_info && old_value)
654             {
655 2                 old_info->destroy(old_value);
656             }
657         }
658 12         else if (prop_any->any_info == &xsd_any_array_info ||
659             prop_any->any_info == any->elements[0].any_info->array_info)
660         {
661 12             old_info = prop_any->any_info;
662 12             old_value = prop_any->value;
663 12             old_element = prop_any->element;
664
665 12             prop_any->value = NULL;
666 12             if (prop_any->element == NULL)
667             {
668                 /* New any with hint that we can stick as many as we like here
669                  */
670 8                 result = xsd_QName_copy(
671                         &prop_any->element,
672                         any->elements[0].element);
673
674 8                 if (result != GLOBUS_SUCCESS)
675                 {
676 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
677                             fault_name,
678                             fault);
679
680 0                     goto out;
681                 }
682
683             }
684
685             /* Make new array for values */
686 12             array_info = any->elements[0].any_info->array_info;
687 12             if (any->elements[0].any_info->array_info == NULL)
688             {
689                 /* No array info? I guess use the any one */
690 2                 array_info = &xsd_any_array_info;
691 2                 use_any = GLOBUS_TRUE;
692             }
693 12             result = array_info->initialize(&prop_any->value);
694
695 12             if (result != GLOBUS_SUCCESS)
696             {
697                 /* Restore property state */
698 0                 xsd_QName_destroy(prop_any->element);
699 0                 prop_any->value = old_value;
700 0                 prop_any->element = old_element;
701 0                 prop_any->any_info = old_info;
702
703 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
704                         fault_name,
705                         fault);
706
707 0                 goto out;
708             }
709 12             prop_any->any_info = array_info;
710
711             /* Add new values to the any array now */
712 30             for (i = 0; i < any->length; i++)
713             {
714 18                 copy_value = prop_any->any_info->push(prop_any->value);
715
716 18                 if (copy_value == NULL)
717                 {
718                     /* Restore property state */
719 0                     xsd_QName_destroy(prop_any->element);
720 0                     prop_any->value = old_value;
721 0                     prop_any->element = old_element;
722 0                     prop_any->any_info = old_info;
723
724 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
725                             fault_name,
726                             fault);
727 0                     goto out;
728                 }
729
730 18                 if (!use_any)
731                 {
732 14                     result = any->elements[i].any_info->copy_contents(
733                             copy_value,
734                             any->elements[i].value);
735                 }
736                 else
737                 {
738 4                     result = xsd_any_info.copy_contents(
739                             copy_value,
740                             &any->elements[i]);
741                 }
742 18                 if (result != GLOBUS_SUCCESS)
743                 {
744 0                     prop_any->any_info->destroy(prop_any->value);
745
746                     /* Restore property state */
747 0                     xsd_QName_destroy(prop_any->element);
748 0                     prop_any->value = old_value;
749 0                     prop_any->element = old_element;
750 0                     prop_any->any_info = old_info;
751
752
753 0                     result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
754                             fault_name,
755                             fault);
756 0                     goto out;
757                 }
758             }
759 12             if (old_info && old_value)
760             {
761 4                 old_info->destroy(old_value);
762             }
763         }
764     }
765 19     else if (any->elements[0].any_info == prop_info)
766     {
767         /* The RP element and this element have the same type. We're OK
768          * If there's only one element in the any.
769          */
770 10         if (any->length > 1)
771         {
772 2             result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
773                     fault_name,
774                     fault);
775 2             goto out;
776         }
777 8         prop_info->copy(&copy_value, any->elements[0].value);
778 8         result = globus_resource_set_property(
779                 resource,
780                 any->elements[0].element,
781                 copy_value);
782 8         if (result != GLOBUS_SUCCESS)
783         {
784 0             error = globus_error_get(result);
785
786 0             if (globus_error_match(
787                     error,
788                     GLOBUS_WSRF_RESOURCE_MODULE,
789                     GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_PROPERTY))
790             {
791 0                 result = INVALID_RESOURCE_PROPERTY_QNAME(fault_name, fault);
792             }
793             else
794             {
795 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
796                         fault_name,
797                         fault);
798             }
799 0             globus_object_free(error);
800
801 0             goto out;
802         }
803     }
804 9     else if (any->elements[0].any_info->array_info == prop_info)
805     {
806         /* The RP element is an array of the type we have in the any, so
807          * we'll need to replace the value of the array
808          */
809 5         void * array_value = NULL;
810
811 5         result = prop_info->initialize(&array_value);
812 5         if (result != GLOBUS_SUCCESS)
813         {
814 0             result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
815                     fault_name,
816                     fault);
817 0             goto out;
818         }
819 5         result = globus_resource_set_property(
820                 resource,
821                 any->elements[0].element,
822                 array_value);
823
824 5         if (result != GLOBUS_SUCCESS)
825         {
826 0             result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
827                     fault_name,
828                     fault);
829 0             goto out;
830         }
831
832 13         for (i = 0; i < any->length; i++)
833         {
834 8             copy_value =
835                 any->elements[i].any_info->array_info->push(array_value);
836 8             if (copy_value == NULL)
837             {
838 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
839                         fault_name,
840                         fault);
841
842 0                 goto out;
843             }
844 8             result = any->elements[i].any_info->copy_contents(
845                     copy_value,
846                     any->elements[i].value);
847 8             if (result != GLOBUS_SUCCESS)
848             {
849 0                 result = SET_RESOURCE_PROPERTY_REQUEST_FAILED(
850                         fault_name,
851                         fault);
852 0                 goto out;
853             }
854         }
855     }
856     else
857     {
858         /* The types don't match at all, we can't do anything about that */
859 4         result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
860                 fault_name,
861                 fault);
862         goto out;
863     }
864 out:
865 49     return result;
866 }
867 /* wsrp_l_UpdateResourceProperty() */
868
869 static
870 globus_result_t
871 wsrp_l_DeleteResourceProperty(
872     globus_resource_t                   resource,
873     xsd_QName *                         qname,
874     char **                             fault_name,
875     void **                             fault)
876 13 {
877 13     globus_result_t                     result;
878 13     globus_object_t *                   error;
879
880 13     result = globus_resource_set_property(
881         resource,
882         qname,
883         NULL);
884
885 13     if (result != GLOBUS_SUCCESS)
886     {
887 0         error = globus_error_get(result);
888
889 0         if (globus_error_match(
890             error,
891             GLOBUS_WSRF_RESOURCE_MODULE,
892             GLOBUS_WSRF_RESOURCE_ERROR_TYPE_UNKNOWN_PROPERTY))
893         {
894 0             result = INVALID_RESOURCE_PROPERTY_QNAME(fault_name, fault);
895         }
896         else
897         {
898 0             result = RESOURCE_UNKNOWN(fault_name, fault);
899         }
900 0         globus_object_free(error);
901     }
902
903 13     return result;
904 }
905 /* wsrp_l_DeleteResourceProperty() */
906
907 /**
908  * Check that all elements in the any array have the same element name
909  * and type info.
910  * 
911  * If not, return a wsrp_InvalidSetResourcePropertiesRequestContentFaultType
912  * fault in the fault_name and fault parameters.
913  */
914 static
915 globus_result_t
916 wsrp_l_check_for_uniformity(
917     xsd_any_array *                     any_array,
918     char **                             fault_name,
919     void **                             fault)
920 116 {
921 116     int                                 i;
922 116     globus_result_t                     result = GLOBUS_SUCCESS;
923 116     xsd_QName *                         last_element;
924 116     xsd_QName *                         element = NULL;
925 116     globus_xsd_type_info_t              last_type;
926 116     globus_xsd_type_info_t              type = NULL;
927
928     /* Verify that all update elements are the same */
929 265     for (i = 0; i < any_array->length; i++)
930     {
931 165         last_element = element;
932 165         last_type = type;
933
934 165         element = any_array->elements[i].element;
935 165         type = any_array->elements[i].any_info;
936
937 165         if (i != 0)
938         {
939 49             if (! xsd_QName_keyeq(element, last_element))
940             {
941 8                 result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
942                         fault_name,
943                         fault);
944
945 8                 goto out;
946             }
947 41             else if (type != last_type)
948             {
949 8                 result = INVALID_SET_RESOURCE_PROPERTIES_REQUEST_CONTENT(
950                         fault_name,
951                         fault);
952
953 8                 goto out;
954             }
955         }
956     }
957 out:
958 116     return result;
959 }