1 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
2
3 #include "globus_i_notification_producer.h"
4 #include "wstop_TopicSpaceType.h"
5 #include "wstop_TopicType.h"
6 #include "globus_xml_buffer.h"
7 #include "notif_ConcreteTopicExpressionType.h"
8 #include "wstop_TopicSpace.h"
9 #include "libxml/xpath.h"
10 #include "libxml/xpathInternals.h"
11 #include "libxml/xmlwriter.h"
12 #include "xpath_XPathExpressionType.h"
13 #include "xpath_NamespaceMapEntryType.h"
14
15 #define SIMPLE_TOPIC_EXPRESSION \
16     "http://docs.oasis-open.org/wsn/2004/06/TopicExpression/Simple"
17
18 #define CONCRETE_TOPIC_EXPRESSION \
19     "http://docs.oasis-open.org/wsn/2004/06/TopicExpression/Concrete"
20
21 #define FULL_TOPIC_EXPRESSION \
22     "http://docs.oasis-open.org/wsn/2004/06/TopicExpression/Full"
23
24
25 static
26 globus_result_t
27 globus_l_notification_topic_to_concrete_path(
28     const wsnt_TopicExpressionType *    topic_expression,
29     notif_ConcreteTopicExpressionType * concrete_topic_expression);
30
31 globus_result_t
32 globus_l_notification_topic_space_lookup_parent(
33     const wstop_TopicSpaceType *        topic_space,
34     const notif_ConcreteTopicExpressionType *
35                                         concrete_topic_expression,
36     wstop_TopicType **                  parent_topic);
37
38 static
39 globus_result_t
40 globus_l_notification_topic_set_concrete_lookup(
41     globus_i_notification_topic_set_t   topic_set,
42     const wsnt_TopicExpressionType *    topic_expression,
43     globus_i_notification_producer_topic_t **
44                                         topic);
45
46 static
47 globus_result_t
48 globus_l_notification_topic_set_full_lookup(
49     globus_i_notification_topic_set_t   topic_set,
50     const wsnt_TopicExpressionType *    topic_expression,
51     globus_list_t **                    topic_list);
52
53 static
54 globus_result_t
55 globus_l_notification_topic_space_write(
56     xmlTextWriterPtr                    writer,
57     wstop_TopicSpaceType *              topic_space);
58
59 globus_result_t
60 globus_l_notification_topic_space_write_topic(
61     xmlTextWriterPtr                    writer,
62     wstop_TopicType *                   topic,
63     char *                              ns);
64
65 static
66 wstop_TopicSpaceType *
67 globus_l_topic_space_lookup(
68     globus_i_notification_topic_set_t   topic_set,
69     xsd_anyURI                          Namespace);
70 #endif
71
72 /**
73  * Enumerate the topics published by a notification producer
74  * @ingroup notification_topics
75  *
76  * @param resource_id
77  *     Resource id associated with notification producer state.
78  * @param topics
79  *     Pointer to an array of topic expressions. An element for each
80  *     topic will be pushed onto this array if this function is successful.
81  *     The caller must free this array.
82  *
83  * @retval GLOBUS_SUCCESS
84  * @retval GLOBUS_NOTIFICATION_PRODUCER_ERROR_TYPE_NULL_PARAMETER
85  * @retval GLOBUS_NOTIFICATION_PRODUCER_ERROR_TYPE_UNKNOWN_RESOURCE
86  * @retval GLOBUS_NOTIFICATION_PRODUCER_ERROR_TYPE_OUT_OF_MEMORY
87  */
88 globus_result_t
89 globus_notification_producer_topic_enumerate(
90     const char *                        resource_id,
91     wsnt_TopicExpressionType_array **   topics)
92 362 {
93 362     globus_result_t                     result = GLOBUS_SUCCESS;
94 362     globus_notification_producer_t      producer;
95 362     wstop_TopicSpaceType *              topic_space;
96     globus_i_notification_producer_topic_t *
97 362                                         topic;
98 362     wsnt_TopicExpressionType *          copy;
99 362     int                                 i;
100 362     int                                 j;
101
102 362     if (topics == NULL)
103     {
104 0         result = GLOBUS_NOTIFICATION_PRODUCER_NULL_PARAMETER();
105         
106 0         goto out;
107     }
108
109 362     *topics = NULL;
110
111 362     if (resource_id == NULL)
112     {
113 0         result = GLOBUS_NOTIFICATION_PRODUCER_NULL_PARAMETER();
114         
115 0         goto out;
116     }
117
118 362     GlobusNotificationProducerGlobalLock();
119
120 362     producer = globus_hashtable_lookup(
121             &globus_i_notification_producers,
122             (void *) resource_id);
123
124 362     if (producer == NULL)
125     {
126 0         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_RESOURCE();
127
128 0         GlobusNotificationProducerGlobalUnlock();
129 0         goto out;
130     }
131     else
132     {
133 362         GlobusNotificationProducerLock(producer);
134 362         GlobusNotificationProducerGlobalUnlock();
135     }
136
137 362     wsnt_TopicExpressionType_array_init(topics);
138
139     /* Enumerate root topics (for now) */
140 1338     for (i = 0; i < producer->topic_set->length; i++)
141     {
142 976         topic_space = &producer->topic_set->elements[i];
143
144 3198         for (j = 0; j < topic_space->Topic.length; j++)
145         {
146 2222             copy = wsnt_TopicExpressionType_array_push(*topics);
147 2222             if (copy == NULL)
148             {
149 0                 result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
150
151 0                 goto destroy_topics_out;
152             }
153 2222             topic = topic_space->Topic.elements[j].any.elements[0].value;
154 2222             result = wsnt_TopicExpressionType_copy_contents(copy, &topic->topic);
155
156 2222             if (result != GLOBUS_SUCCESS)
157             {
158 0                 result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
159
160 0                 goto destroy_topics_out;
161             }
162 2222             xsd_anyURI_destroy_contents(copy->_Dialect);
163 2222             xsd_anyURI_init_contents_cstr(copy->_Dialect,
164                     globus_libc_strdup(SIMPLE_TOPIC_EXPRESSION));
165         }
166     }
167
168 destroy_topics_out:
169 362     if (result != GLOBUS_SUCCESS)
170     {
171 0         wsnt_TopicExpressionType_array_destroy(*topics);
172 0         *topics = NULL;
173     }
174 362     GlobusNotificationProducerUnlock(producer);
175 out:
176 362     return result;
177 }
178 /* globus_notification_producer_topic_enumerate() */
179
180 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
181 /**
182  * @ingroup globus_i_notification_topic_set
183  */
184 globus_result_t
185 globus_i_notification_topic_set_init(
186     globus_i_notification_topic_set_t * topic_set)
187 93 {
188 93     globus_result_t                     result;
189
190 93     result = wstop_TopicSpaceType_array_init(topic_set);
191
192 93     return result ? GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY() : GLOBUS_SUCCESS;
193 }
194 /* globus_i_notification_topic_set_init() */
195
196 /**
197  * @ingroup globus_i_notification_topic_set
198  */
199 void
200 globus_i_notification_topic_set_destroy(
201     globus_i_notification_topic_set_t   topic_set)
202 0 {
203 0     wstop_TopicSpaceType_array_destroy(topic_set);
204 }
205 /* globus_i_notification_topic_set_destroy() */
206
207 /**
208  * @ingroup globus_i_notification_topic_set
209  */
210 globus_result_t
211 globus_i_notification_topic_set_add(
212     globus_i_notification_topic_set_t   topic_set,
213     const wsnt_TopicExpressionType *    topic_expression)
214 650 {
215 650     wstop_TopicSpaceType *              topic_space;
216 650     wstop_TopicType_array *             topics;
217 650     wstop_TopicType *                   parent_topic;
218 650     wstop_TopicType *                   topic;
219     globus_i_notification_producer_topic_t *
220 650                                         topic_info;
221 650     globus_result_t                     result;
222 650     globus_bool_t                       new_topic_space = GLOBUS_FALSE;
223 650     int                                 i;
224 650     notif_ConcreteTopicExpressionType   concrete_topic_expression;
225 650     xsd_any *                           any;
226 650     xsd_NCName                          topic_leaf;
227     
228 650     if (topic_set == NULL ||
229         topic_expression == NULL)
230     {
231 0         result = GLOBUS_NOTIFICATION_PRODUCER_NULL_PARAMETER();
232
233 0         goto out;
234     }
235
236 650     result = globus_l_notification_topic_to_concrete_path(
237             topic_expression,
238             &concrete_topic_expression);
239 650     if (result != GLOBUS_SUCCESS)
240     {
241 0         goto out;
242     }
243
244 650     topic_space = globus_l_topic_space_lookup(
245             topic_set,
246             concrete_topic_expression.Root.Namespace);
247 650     if (topic_space == NULL)
248     {
249         /* Create a new TopicSpace for this namespace */
250 268         topic_space = wstop_TopicSpaceType_array_push(topic_set);
251 268         if (topic_space == NULL)
252         {
253 0             result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
254
255 0             goto free_concrete_path_out;
256         }
257 268         new_topic_space = GLOBUS_TRUE;
258 268         result = xsd_anyURI_copy_contents(
259                 &topic_space->_targetNamespace,
260                 &concrete_topic_expression.Root.Namespace);
261 268         if (result != GLOBUS_SUCCESS)
262         {
263 0             result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
264
265 0             goto remove_topic_space_out;
266         }
267     }
268
269 650     if (concrete_topic_expression.Path.length == 0)
270     {
271         /* Root topic */
272 642         topics = &topic_space->Topic;
273 642         topic_leaf = concrete_topic_expression.Root.local;
274     }
275     else
276     {
277         /* Non-root topic */
278 8         result = globus_l_notification_topic_space_lookup_parent(
279                 topic_space,
280                 &concrete_topic_expression,
281                 &parent_topic);
282
283 8         if (result != GLOBUS_SUCCESS)
284         {
285 0             goto remove_topic_space_out;
286         }
287 8         topics = &parent_topic->
288                choice_value.value.NonAliasTopicDefinition.Topic;
289
290 8         topic_leaf = concrete_topic_expression.Path.elements[
291             concrete_topic_expression.Path.length-1];
292     }
293
294     /* Verify uniqueness */
295 1172     for (i = 0; i < topics->length; i++)
296     {
297 522         if (!strcmp(topics->elements[i]._name, topic_leaf))
298         {
299 0             result = GLOBUS_NOTIFICATION_PRODUCER_ALREADY_EXISTS();
300
301 0             goto remove_topic_space_out;
302         }
303     }
304
305 650     topic = wstop_TopicType_array_push(topics);
306
307 650     if (topic == NULL)
308     {
309 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
310
311 0         goto remove_topic_space_out;
312     }
313 650     topic->choice_value.type = wstop_TopicType_NonAliasTopicDefinition;
314
315 650     result = xsd_NCName_copy_contents(
316             &topic->_name,
317             &topic_leaf);
318 650     if (result != GLOBUS_SUCCESS)
319     {
320 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
321
322 0         goto free_topic;
323     }
324 650     result = TopicInfo_init(&topic_info);
325 650     if (result != GLOBUS_SUCCESS)
326     {
327 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
328 0         goto free_topic;
329     }
330 650     result = wsnt_TopicExpressionType_copy_contents(
331             &topic_info->topic,
332             topic_expression);
333 650     if (result != GLOBUS_SUCCESS)
334     {
335 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
336 0         goto free_topic_info;
337     }
338 650     any = xsd_any_array_push(&topic->any);
339 650     if (any == NULL)
340     {
341 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
342 0         goto free_topic_info;
343     }
344 650     any->any_info = &TopicInfo_info;
345 650     any->value = topic_info;
346
347 650     if (result != GLOBUS_SUCCESS)
348     {
349 free_topic_info:
350 0         TopicInfo_destroy(topic_info);
351 free_topic:
352 0         wstop_TopicType_destroy_contents(topic);
353 0         topics->length--;
354 remove_topic_space_out:
355 0         if (new_topic_space)
356         {
357 0             wstop_TopicSpaceType_destroy_contents(topic_space);
358 0             topic_set->length--;
359         }
360     }
361
362 free_concrete_path_out:
363 650     notif_ConcreteTopicExpressionType_destroy_contents(&concrete_topic_expression);
364 out:
365 650     return result;
366 }
367 /* globus_i_notification_topic_set_add() */
368
369 /**
370  * @ingroup globus_i_notification_topic_set
371  */
372 globus_result_t
373 globus_i_notification_topic_set_lookup(
374     globus_i_notification_topic_set_t   topic_set,
375     const wsnt_TopicExpressionType *    topic_expression,
376     globus_list_t **                    topic_list)
377 427 {
378 427     globus_result_t                     result;
379     globus_i_notification_producer_topic_t *
380 427                                         topic;
381
382 427     *topic_list = NULL;
383
384 427     if (strcmp(*topic_expression->_Dialect, SIMPLE_TOPIC_EXPRESSION) == 0 ||
385         strcmp(*topic_expression->_Dialect, CONCRETE_TOPIC_EXPRESSION) == 0)
386     {
387 426         result = globus_l_notification_topic_set_concrete_lookup(
388                 topic_set,
389                 topic_expression,
390                 &topic);
391
392 426         if (result == GLOBUS_SUCCESS)
393         {
394 424             globus_list_insert(topic_list, topic);
395         }
396     }
397 1     else if (strcmp(*topic_expression->_Dialect, FULL_TOPIC_EXPRESSION) == 0)
398     {
399 1         result = globus_l_notification_topic_set_full_lookup(
400                 topic_set,
401                 topic_expression,
402                 topic_list);
403     }
404     else
405     {
406 0         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_DIALECT();
407     }
408 427     return result;
409 }
410
411 /**
412  * @ingroup globus_i_notification_topic_set
413  */
414 globus_result_t
415 globus_i_notification_topic_set_remove(
416     globus_i_notification_topic_set_t   topic_set,
417     const wsnt_TopicExpressionType *    topic_expression)
418 1 {
419 1     globus_result_t                     result;
420 1     wstop_TopicSpaceType *              topic_space;
421 1     wstop_TopicType_array *             topics;
422 1     wstop_TopicType *                   parent_topic;
423 1     wstop_TopicType *                   topic = NULL;
424 1     notif_ConcreteTopicExpressionType   concrete_topic_expression;
425 1     xsd_NCName                          topic_leaf;
426 1     int                                 i;
427
428 1     result = globus_l_notification_topic_to_concrete_path(
429             topic_expression,
430             &concrete_topic_expression);
431 1     if (result != GLOBUS_SUCCESS)
432     {
433 0         goto out;
434     }
435 1     topic_space = globus_l_topic_space_lookup(
436             topic_set,
437             concrete_topic_expression.Root.Namespace);
438
439 1     if (topic_space == NULL)
440     {
441 0         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_TOPIC();
442
443 0         goto free_concrete_path_out;
444     }
445
446 1     if (concrete_topic_expression.Path.length == 0)
447     {
448         /* remove a root topic */
449 1         topics = &topic_space->Topic;
450 1         topic_leaf = concrete_topic_expression.Root.local;
451     }
452     else
453     {
454 0         result = globus_l_notification_topic_space_lookup_parent(
455                 topic_space,
456                 &concrete_topic_expression,
457                 &parent_topic);
458 0         if (result != GLOBUS_SUCCESS)
459         {
460 0             goto free_concrete_path_out;
461         }
462 0         topics = &parent_topic->
463             choice_value.value.NonAliasTopicDefinition.Topic;
464 0         topic_leaf = concrete_topic_expression.Path.elements[
465             concrete_topic_expression.Path.length-1];
466     }
467
468     /* Locate the topic */
469 1     for (i = 0; i < topics->length; i++)
470     {
471 1         if (strcmp(topics->elements[i]._name, topic_leaf) == 0)
472         {
473 1             topic = &topics->elements[i];
474 1             break;
475         }
476     }
477
478 1     if (topic == NULL)
479     {
480 0         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_TOPIC();
481
482 0         goto free_concrete_path_out;
483     }
484
485     /* Remove all child topics (and related subscriptions) */
486 1     wstop_TopicType_destroy_contents(topic);
487
488 1     memmove(topics->elements + i,
489             topics->elements + i + 1,
490             topics->length - (i + 1));
491 1     topics->length--;
492
493 free_concrete_path_out:
494 1     notif_ConcreteTopicExpressionType_destroy_contents(&concrete_topic_expression);
495 out:
496 1     return result;
497 }
498 /* globus_i_notification_topic_set_remove() */
499
500
501 static
502 globus_result_t
503 globus_l_notification_topic_to_concrete_path(
504     const wsnt_TopicExpressionType *    topic,
505     notif_ConcreteTopicExpressionType * concrete_topic_expression)
506 1077 {
507 1077     globus_result_t                     result;
508 1077     globus_xml_buffer *                 buffer;
509 1077     xsd_QName *                         topic_qname;
510 1077     xsd_QName                           simple_qname = { NULL, NULL };
511 1077     globus_soap_message_handle_t        message_handle;
512
513 1077     result = notif_ConcreteTopicExpressionType_init_contents(concrete_topic_expression);
514 1077     if (result != GLOBUS_SUCCESS)
515     {
516 0         result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
517
518 0         goto out;
519     }
520
521 1077     if (topic->any->any_info == &xsd_QName_info ||
522         topic->any->any_info == &xsd_QName_contents_info ||
523         topic->any->any_info->initialize_contents == xsd_QName_init_contents_wrapper)
524     {
525 1061         topic_qname = topic->any->value;
526 1061         result = xsd_QName_copy_contents(&concrete_topic_expression->Root, topic_qname);
527
528 1061         if (result != GLOBUS_SUCCESS)
529         {
530 0             result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
531
532 0             goto out;
533         }
534     }
535 16     else if (topic->any->any_info == &notif_ConcreteTopicExpressionType_info ||
536              topic->any->any_info == &notif_ConcreteTopicExpressionType_contents_info)
537     {
538 16         result = notif_ConcreteTopicExpressionType_copy_contents(
539                 concrete_topic_expression,
540                 topic->any->value);
541 16         if (result != GLOBUS_SUCCESS)
542         {
543 0             result = GLOBUS_NOTIFICATION_PRODUCER_OUT_OF_MEMORY();
544
545 0             goto out;
546         }
547     }
548 0     else if (topic->any->any_info == &globus_xml_buffer_info ||
549              topic->any->any_info == &globus_xml_buffer_contents_info)
550     {
551 0         buffer = topic->any->value;
552
553 0         result = globus_soap_message_handle_init_from_memory(
554                 &message_handle,
555                 buffer->buffer,
556                 buffer->length);
557 0         if (result != GLOBUS_SUCCESS)
558         {
559 0             goto out;
560         }
561
562 0         if (strcmp(*topic->_Dialect, SIMPLE_TOPIC_EXPRESSION) == 0)
563         {
564 0             result = xsd_QName_deserialize_contents(
565                 NULL,
566                 &concrete_topic_expression->Root,
567                 message_handle,
568                 0);
569         }
570 0         else if (strcmp(*topic->_Dialect, CONCRETE_TOPIC_EXPRESSION) == 0)
571         {
572 0             result = notif_ConcreteTopicExpressionType_deserialize_contents(
573                     NULL,
574                     concrete_topic_expression,
575                     message_handle,
576                     0);
577         }
578
579 0         globus_soap_message_handle_destroy(message_handle);
580     }
581
582 1077     xsd_QName_destroy_contents(&simple_qname);
583 1077     if (result != GLOBUS_SUCCESS)
584     {
585 0         notif_ConcreteTopicExpressionType_destroy_contents(concrete_topic_expression);
586     }
587 out:
588 1077     return result;
589 }
590 /* globus_l_notification_topic_to_concrete_path() */
591
592 globus_result_t
593 globus_l_notification_topic_space_lookup_parent(
594     const wstop_TopicSpaceType *        topic_space,
595     const notif_ConcreteTopicExpressionType *
596                                         concrete_path,
597     wstop_TopicType **                  parent_topic)
598 16 {
599 16     globus_result_t                     result = GLOBUS_SUCCESS;
600 16     const wstop_TopicType_array *       topics;
601 16     wstop_TopicType *                   ancestor;
602 16     int                                 i;
603 16     int                                 j;
604
605 16     topics = &topic_space->Topic;
606
607     /* Compare Root topic */
608 16     ancestor = NULL;
609 16     for (j = 0; j < topics->length; j++)
610     {
611 16         if (strcmp(topics->elements[j]._name, concrete_path->Root.local) == 0)
612         {
613 16             ancestor = &topics->elements[j];
614 16             topics = &ancestor->choice_value.value.NonAliasTopicDefinition.Topic;
615 16             break;
616         }
617     }
618 16     if (ancestor == NULL)
619     {
620 0         goto out;
621     }
622     /* Compare the rest of the topic path */
623 18     for (i = 0; i < concrete_path->Path.length-1; i++)
624     {
625 2         ancestor = NULL;
626 4         for (j = 0; j < topics->length; j++)
627         {
628 4             if (strcmp(topics->elements[j]._name, concrete_path->Path.elements[i]) == 0)
629             {
630 2                 ancestor = &topics->elements[j];
631 2                 topics = &ancestor->choice_value.value.NonAliasTopicDefinition.Topic;
632 2                 break;
633             }
634         }
635 2         if (ancestor == NULL)
636         {
637 0             goto out;
638         }
639     }
640
641 out:
642 16     *parent_topic = ancestor;
643
644 16     if (ancestor == NULL)
645     {
646 0         result = GLOBUS_NOTIFICATION_PRODUCER_INVALID_TOPIC();
647     }
648
649 16     return result;
650 }
651 /* globus_l_notification_topic_space_lookup_parent() */
652
653 static
654 globus_result_t
655 globus_l_notification_topic_set_concrete_lookup(
656     globus_i_notification_topic_set_t   topic_set,
657     const wsnt_TopicExpressionType *    topic_expression,
658     globus_i_notification_producer_topic_t **
659                                         topic)
660 426 {
661 426     globus_result_t                     result;
662 426     wstop_TopicSpaceType *              topic_space;
663 426     wstop_TopicType_array *             topics;
664 426     wstop_TopicType *                   parent_topic;
665 426     notif_ConcreteTopicExpressionType   concrete_topic_expression;
666 426     xsd_NCName                          topic_leaf;
667 426     int                                 i;
668
669 426     *topic = NULL;
670
671 426     result = globus_l_notification_topic_to_concrete_path(
672             topic_expression,
673             &concrete_topic_expression);
674 426     if (result != GLOBUS_SUCCESS)
675     {
676 0         goto out;
677     }
678 426     if (concrete_topic_expression.Root.Namespace == NULL)
679     {
680 0         result = GLOBUS_NOTIFICATION_PRODUCER_INVALID_TOPIC();
681
682 0         goto free_concrete_path_out;
683     }
684 426     topic_space = globus_l_topic_space_lookup(
685             topic_set,
686             concrete_topic_expression.Root.Namespace);
687
688 426     if (topic_space == NULL)
689     {
690 2         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_TOPIC();
691 2         goto free_concrete_path_out;
692     }
693
694 424     if (concrete_topic_expression.Path.length == 0)
695     {
696         /* lookup root topic */
697 416         topics = &topic_space->Topic;
698 416         topic_leaf = concrete_topic_expression.Root.local;
699     }
700     else
701     {
702 8         result = globus_l_notification_topic_space_lookup_parent(
703                 topic_space,
704                 &concrete_topic_expression,
705                 &parent_topic);
706 8         if (result != GLOBUS_SUCCESS)
707         {
708 0             goto free_concrete_path_out;
709         }
710 8         topics = &parent_topic->
711             choice_value.value.NonAliasTopicDefinition.Topic;
712
713 8         topic_leaf = concrete_topic_expression.Path.elements[
714             concrete_topic_expression.Path.length-1];
715     }
716
717 1148     for (i = 0; i < topics->length; i++)
718     {
719 1148         if (!strcmp(topics->elements[i]._name, topic_leaf))
720         {
721 424             *topic = topics->elements[i].any.elements[0].value;
722 424             break;
723         }
724     }
725
726 424     if (*topic == NULL)
727     {
728 0         result = GLOBUS_NOTIFICATION_PRODUCER_UNKNOWN_TOPIC();
729     }
730
731 free_concrete_path_out:
732 426     notif_ConcreteTopicExpressionType_destroy_contents(&concrete_topic_expression);
733 out:
734 426     return result;
735 }
736 /* globus_l_notification_topic_set_concrete_lookup() */
737
738 static
739 globus_result_t
740 globus_l_notification_topic_set_full_lookup(
741     globus_i_notification_topic_set_t   topic_set,
742     const wsnt_TopicExpressionType *    topic_expression,
743     globus_list_t **                    topic_list)
744 1 {
745 1     int                                 i;
746 1     xmlTextWriterPtr                    writer;
747 1     xmlDocPtr                           dom;
748 1     xmlXPathContextPtr                  xpath_context;
749 1     xmlXPathCompExprPtr                 xpath_expression;
750 1     xmlXPathObjectPtr                   xpath_result;
751 1     xmlNodePtr                          node;
752 1     globus_result_t                     result = GLOBUS_SUCCESS;
753 1     xpath_XPathExpressionType *         serialized_xpath_expression;
754 1     char *                              topic_ptr_location;
755     globus_i_notification_producer_topic_t *
756 1                                         topic;
757 1     serialized_xpath_expression = topic_expression->any->value;
758
759 1     xpath_expression = xmlXPathCompile(
760             (xmlChar *) serialized_xpath_expression->ExpressionString);
761
762 1     if (xpath_expression == NULL)
763     {
764 0         result = GLOBUS_NOTIFICATION_PRODUCER_INVALID_TOPIC();
765
766 0         goto out;
767     }
768     
769 1     writer = xmlNewTextWriterDoc(&dom, 0);
770 1     if (writer == NULL)
771     {
772 0         goto free_xpath_expression_out;
773     }
774 1     xmlTextWriterStartElement(
775             writer,
776             (xmlChar *) "TopicSet");
777 4     for (i = 0; i < topic_set->length; i++)
778     {
779 3         result = globus_l_notification_topic_space_write(
780                 writer,
781                 &topic_set->elements[i]);
782
783 3         if (result != GLOBUS_SUCCESS)
784         {
785 0             goto destroy_writer_out;
786         }
787     }
788 1     xmlTextWriterEndElement(writer);
789 1     xmlTextWriterFlush(writer);
790
791 1     xpath_context = xmlXPathNewContext(dom);
792 1     if (xpath_context == NULL)
793     {
794 0         goto destroy_writer_out;
795     }
796 1     xpath_context->node = xmlDocGetRootElement(dom);
797
798 11     for (i = 0; i < serialized_xpath_expression->NamespaceMap.length; i++)
799     {
800 10         xmlXPathRegisterNs(
801                 xpath_context,
802                 (xmlChar *)
803                     serialized_xpath_expression->NamespaceMap.elements[i].Prefix,
804                 (xmlChar *)
805                     serialized_xpath_expression->NamespaceMap.elements[i].Namespace);
806     }
807 1     xpath_result = xmlXPathCompiledEval(xpath_expression, xpath_context);
808
809 1     if (xpath_result == NULL || xpath_result->type != XPATH_NODESET ||
810             xpath_result->nodesetval == NULL)
811     {
812 0         goto destroy_context_out;
813
814     }
815
816 1     if (xpath_result->type != XPATH_NODESET ||
817         xpath_result->nodesetval == NULL ||
818         xpath_result->nodesetval->nodeNr == 0)
819     {
820 0         goto destroy_xpath_result_out;
821     }
822
823 1     if ((xpath_result->type == XPATH_NODESET &&
824              (xpath_result->nodesetval == NULL ||
825               xpath_result->nodesetval->nodeNr == 0)))
826     {
827 0         result = GLOBUS_FAILURE;
828     }
829 2     for (i = 0; i < xpath_result->nodesetval->nodeNr; i++)
830     {
831         /* For each node, we find, look up topic pointer and add to the list */
832 1         node = xpath_result->nodesetval->nodeTab[i];
833 1         topic_ptr_location = (char *) xmlGetProp(node, (xmlChar *) "ptr");
834
835 1         sscanf(topic_ptr_location, "%p", &topic);
836
837 1         globus_list_insert(topic_list, topic);
838 1         xmlFree(topic_ptr_location);
839     }
840
841 destroy_xpath_result_out:
842 1     if (xpath_result != NULL)
843     {
844 1         xmlXPathFreeObject(xpath_result);
845     }
846 destroy_context_out:
847 1     xmlXPathFreeContext(xpath_context);
848 destroy_writer_out:
849 1     xmlFreeTextWriter(writer);
850 1     xmlFreeDoc(dom);
851 free_xpath_expression_out:
852 1     xmlXPathFreeCompExpr(xpath_expression);
853 out:
854 1     return result;
855 }
856 /* globus_l_notification_topic_set_full_lookup() */
857
858 static
859 globus_result_t
860 globus_l_notification_topic_space_write(
861     xmlTextWriterPtr                    writer,
862     wstop_TopicSpaceType *              topic_space)
863 3 {
864 3     globus_result_t                     result = GLOBUS_SUCCESS;
865 3     int                                 i;
866
867 9     for (i = 0; i < topic_space->Topic.length; i++)
868     {
869 6         result = globus_l_notification_topic_space_write_topic(
870                 writer,
871                 &topic_space->Topic.elements[i],
872                 topic_space->_targetNamespace);
873 6         if (result != GLOBUS_SUCCESS)
874         {
875 0             goto out;
876         }
877
878     }
879
880 out:
881 3     return result;
882 }
883 /* globus_l_notification_topic_space_full_lookup() */
884
885 globus_result_t
886 globus_l_notification_topic_space_write_topic(
887     xmlTextWriterPtr                    writer,
888     wstop_TopicType *                   topic,
889     char *                              ns)
890 9 {
891 9     globus_result_t                     result = GLOBUS_SUCCESS;
892 9     int                                 i;
893 9     wstop_TopicType_array *             children;
894
895
896 9     if (ns)
897     {
898 6         xmlTextWriterStartElementNS(
899                 writer,
900                 "ns",
901                 (xmlChar *) topic->_name,
902                 (xmlChar *) ns);
903     }
904     else
905     {
906 3     xmlTextWriterStartElement(
907             writer,
908             (xmlChar *) topic->_name);
909     }
910
911 9     xmlTextWriterWriteFormatAttribute(
912             writer,
913             (xmlChar *) "ptr",
914             "%p",
915             topic->any.elements[0].value);
916
917 9     children = &topic->choice_value.value.NonAliasTopicDefinition.Topic;
918 12     for (i = 0; i < children->length; i++)
919     {
920 3         globus_l_notification_topic_space_write_topic(
921                 writer,
922                 &children->elements[i],
923                 NULL);
924     }
925
926 9     xmlTextWriterEndElement(writer);
927 9     return result;
928 }
929 /* globus_l_notification_topic_space_write_topic() */
930
931 static
932 wstop_TopicSpaceType *
933 globus_l_topic_space_lookup(
934     globus_i_notification_topic_set_t   topic_set,
935     xsd_anyURI                          Namespace)
936 1077 {
937 1077     int                                 i;
938
939 1777     for (i = 0; i < topic_set->length; i++)
940     {
941 1507         if (strcmp(topic_set->elements[i]._targetNamespace, Namespace) == 0)
942         {
943 807             return &topic_set->elements[i];
944         }
945     }
946 270     return NULL;
947 }
948 /* globus_l_topic_space_lookup() */
949