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