File 89-assoc-handling.patch of Package libcmpiutil

# HG changeset patch
# User Kaitlin Rupert <karupert@us.ibm.com>
# Date 1240873892 25200
# Node ID 1cb3975921d590d4dda4de197a4dc687e45d1840
# Parent  d4a9e07d6738f76780bcb1ada5b7c0dbc57e4e0f
Work around for sfcb's lack of association handling

If a association provider has multiple classes listed, and a user queries with
the super class for the classes listed in the registration, the provider is
not called each time for each class.  Instead, the provider is called once.

This logic detects whether the association classname specified for by the user
is an exact match of one of the classnames in the registration.  If it is,
the provider is only called once.  If the classname is a super class, then the
provider is called once for each class listed in the registration.

Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com>

diff -r d4a9e07d6738 -r 1cb3975921d5 std_association.c
--- a/std_association.c	Thu Jan 22 11:33:20 2009 -0800
+++ b/std_association.c	Mon Apr 27 16:11:32 2009 -0700
@@ -274,6 +274,56 @@
         return s;
 }
 
+static bool do_generic_assoc_call(struct std_assoc_info *info,
+                                  struct std_assoc *handler)
+{
+        int i;
+
+        if (info->assoc_class == NULL) {
+                return true;
+        } else {
+                for (i = 0; handler->assoc_class[i]; i++) {
+                        if (STREQ(info->assoc_class, handler->assoc_class[i]))
+                                return false;
+                }
+        }
+
+        return true;
+}
+
+static CMPIStatus handle_assoc(struct std_assoc_info *info,
+                               const CMPIObjectPath *ref,
+                               struct std_assoc *handler,
+                               struct inst_list *list)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        int i;
+
+        if (do_generic_assoc_call(info, handler)) {
+                for (i = 0; handler->assoc_class[i]; i++) {
+                        info->assoc_class = handler->assoc_class[i];
+
+                        CU_DEBUG("Calling handler ...");
+                        s = handler->handler(ref, info, list);
+                        if (s.rc != CMPI_RC_OK) {
+                                CU_DEBUG("Handler did not return CMPI_RC_OK.");
+                                goto out;
+                        }
+                }
+        } else {
+                CU_DEBUG("Calling handler ...");
+                s = handler->handler(ref, info, list);
+                if (s.rc != CMPI_RC_OK) {
+                        CU_DEBUG("Handler did not return CMPI_RC_OK.");
+                        goto out;
+                }
+        }
+        CU_DEBUG("Handler returned CMPI_RC_OK.");
+
+ out:
+        return s;
+}
+
 static CMPIStatus do_assoc(struct std_assoc_ctx *ctx,
                            struct std_assoc_info *info,
                            const CMPIResult *results,
@@ -284,6 +334,7 @@
         CMPIStatus s = {CMPI_RC_OK, NULL};
         struct inst_list list;
         struct std_assoc *handler;
+        int i;
 
         CU_DEBUG("Getting handler ...");
         handler = std_assoc_get_handler(ctx, info, ref);
@@ -295,13 +346,23 @@
 
         inst_list_init(&list);
 
-        CU_DEBUG("Calling handler ...");
-        s = handler->handler(ref, info, &list);
-        if (s.rc != CMPI_RC_OK) {
-                CU_DEBUG("Handler did not return CMPI_RC_OK.");
-                goto out;
+        if (do_generic_assoc_call(info, handler)) {
+                for (i = 0; handler->assoc_class[i]; i++) {
+                        info->assoc_class = handler->assoc_class[i];
+
+                        s = handle_assoc(info, ref, handler, &list);
+                        if (s.rc != CMPI_RC_OK) {
+                                CU_DEBUG("Failed to handle association");
+                                goto out;
+                        }
+                }
+        } else {
+                s = handle_assoc(info, ref, handler, &list);
+                if (s.rc != CMPI_RC_OK) {
+                        CU_DEBUG("Failed to handle association");
+                        goto out;
+                }
         }
-        CU_DEBUG("Handler returned CMPI_RC_OK.");
 
         /* References and ReferenceNames */
         if (ref_rslt)
@@ -320,6 +381,7 @@
                 CU_DEBUG("Prepare return list did not return CMPI_RC_OK.");
                 goto out;
         }
+
         CU_DEBUG("Returned %u instance(s).", list.cur);
 
         if (names_only)