Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv3328

Modified Files:
      Tag: xquery-decomposition
        xrpc_client.mx xrpc_server.mx 
Log Message:
modified xrpc_client|server to handle the new soap xrpc protocol, but
now we need to modify the code again because we have decided to used
node position number instead of using xrpc:id and xrpc:idref attributes



Index: xrpc_client.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_client.mx,v
retrieving revision 1.41.2.6
retrieving revision 1.41.2.7
diff -u -d -r1.41.2.6 -r1.41.2.7
--- xrpc_client.mx      6 Mar 2008 15:31:41 -0000       1.41.2.6
+++ xrpc_client.mx      7 Mar 2008 16:09:56 -0000       1.41.2.7
@@ -316,7 +316,7 @@
                     var k := 
set_kind(local_name.leftjoin(reverse(ws.fetch(CONT_NAME))).tmark([EMAIL 
PROTECTED]), ELEM);
                     res_kind.append(k);
                     tpe := ""; # clean up type info
-                } else if (tpe = "processing-instruction") { # text value of a 
PI node
+                } else if (tpe = "pi") { # text value of a PI node
                     res_iter.append(oid(itercnt));
                     res_item.append(pre);
                     var k := 
set_kind(local_name.leftjoin(reverse(ws.fetch(CONT_NAME))).tmark([EMAIL 
PROTECTED]), ELEM);
@@ -965,7 +965,8 @@
 
     if(ucnt == 0 && rcnt == 0)
         return GDK_SUCCEED;
-   
+
+    /* TODO: multiple fragment! */
     str2buf(b, "<xrpc:fragments><xrpc:fragment>");
     ret = runtime_doc_projection2stream(NULL, bs, ws,
             used_item, used_kind, returned_item, returned_kind,
@@ -973,7 +974,7 @@
             int_values, dbl_values, dec_values, str_values);
     str2buf(b, "</xrpc:fragment></xrpc:fragments>");
 
-    return GDK_SUCCEED;
+    return ret;
 }
 
 int
@@ -1168,6 +1169,7 @@
                 item = fitem_lst[a];
                 cmbn_cont_kind = fkind_lst[a];
                 cur_kind = XTRACT_KIND(cmbn_cont_kind);
+                contID = XTRACT_CONT(cmbn_cont_kind);
 
                 switch (cur_kind) {
                     case BOOL:
@@ -1198,7 +1200,6 @@
                                 "</xrpc:atomic-value>", str_val);
                     case ATTR:
                     {
-                        contID = XTRACT_CONT(cmbn_cont_kind);
                         pre_nid   = getBatFromContainer(ws, PRE_NID, contID);
                         attr_own  = getBatFromContainer(ws, ATTR_OWN, contID);
                         attr_qn   = getBatFromContainer(ws, ATTR_QN, contID);
@@ -1232,12 +1233,14 @@
                         char *loc    = (char*)BUNtail(qn_loci,    
attr_qn_lst[item]);
                         if(prefix && *prefix)
                             b->pos += snprintf((b->buf + b->pos), (b->len - 
b->pos),
-                                    "<xrpc:attribute xrpc:idref=\""OIDFMT"\" 
xrpc:atrr_qn=\"%s:%s\"/>",
-                                    owner, prefix, loc);
+                                    "<xrpc:attribute 
xrpc:idref=\"d%d:n"OIDFMT"\" "
+                                                    "xrpc:atrr_qn=\"%s:%s\"/>",
+                                    contID, owner, prefix, loc);
                         else
                             b->pos += snprintf((b->buf + b->pos), (b->len - 
b->pos),
-                                    "<xrpc:attribute xrpc:idref=\""OIDFMT"\" 
xrpc:atrr_qn=\"%s\"/>",
-                                    owner, loc);
+                                    "<xrpc:attribute 
xrpc:idref=\"d%d:n"OIDFMT"\" "
+                                                    "xrpc:atrr_qn=\"%s\"/>",
+                                    contID, owner, loc);
 
                         BBPunfix(BBPcacheid(pre_nid));
                         BBPunfix(BBPcacheid(attr_own));
@@ -1248,7 +1251,6 @@
                     }
                     case ELEM:
                     {
-                        contID = XTRACT_CONT(cmbn_cont_kind);
                         elem_kind = getELEMkind(ws, contID, item);
                         if (elem_kind == GDK_chr_min) {
                             clean_up(sock, out, bs, b, argcnt, iterc);
@@ -1257,7 +1259,7 @@
                         switch(elem_kind) {
                             case 0:
                                 b->pos += snprintf((b->buf + b->pos), (b->len 
- b->pos),
-                                        "<xrpc:element 
xrpc:idref=\""OIDFMT"\"/>", item);
+                                        "<xrpc:element 
xrpc:idref=\"d%d:n"OIDFMT"\"/>", contID, item);
                                 break;
                             case 1:
                                 b->pos += snprintf((b->buf + b->pos), (b->len 
- b->pos),
@@ -1269,7 +1271,7 @@
                                 break;
                             case 3:
                                 b->pos += snprintf((b->buf + b->pos), (b->len 
- b->pos),
-                                        "<xrpc:processing-instruction 
xrpc:idref=\""OIDFMT"\"/>", item);
+                                        "<xrpc:pi xrpc:idref=\""OIDFMT"\"/>", 
item);
                                 break;
                             case 4:
                                 b->pos += snprintf((b->buf + b->pos), (b->len 
- b->pos),

Index: xrpc_server.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_server.mx,v
retrieving revision 1.58.2.3
retrieving revision 1.58.2.4
diff -u -d -r1.58.2.3 -r1.58.2.4
--- xrpc_server.mx      4 Mar 2008 17:34:05 -0000       1.58.2.3
+++ xrpc_server.mx      7 Mar 2008 16:09:56 -0000       1.58.2.4
@@ -172,6 +172,29 @@
 static BAT* xrpc_trusted = NULL;
 static BAT* xrpc_admin = NULL;
 
+/* Concatenate two strings, separated with ':'.
+ * Results goes into 'res', '\0' terminated */
+static INLINE char *
+strs_concat(str str1, str str2)
+{
+    int i = 0, j = 0;
+    int len1 = strlen(str1), len2 = strlen(str2);
+    char *res = NULL;
+
+    if(!(res = GDKmalloc(len1 + len2 + 2))){
+        GDKerror("strs_concat: failed to malloc 'res'\n");
+        return NULL;
+    } else {
+        for(i = 0, j = 0; j < len1; i++, j++)
+            res[i] = str1[j];
+        res[i++] = '|';
+        for(j = 0; j < len2; i++, j++)
+            res[i] = str2[j];
+        res[i] = '\0';
+    }
+    return res;
+}
+
 static INLINE void
 clean_up(lng **argcnt,
          char **argtpe,
@@ -366,7 +389,7 @@
  * @return the 'pre' value of this node, or
  *         0 if such node can not be found.
  */
-static oid
+static INLINE oid
 get_elem_pre(oid start_pre,
              oid end_pre,
              char elem_kind,
@@ -418,80 +441,227 @@
 }
 
 /**
- * Find the value of the attribute 'attr_name', which is owned by the
- * node with the given 'pre' value.
+ * Find the value of the attribute 'uri':'loc', which is owned by
+ * the node with the given 'pre' value.
  *
  * NB: DO NOT free the string returned by this function, because it is
  *     not copied!!!
  *
- * @return The value of the attribute 'attr_name', or
- *         NULL if attribute with such name was not found.
+ * @return The value of the attribute 'uri':'loc', or
+ *         NULL if element 'owner' does not have such attribute
  */
 static char *
 get_attr_val(stream *out,
              int    optional,
-             char  *attr_name,
-             char  *ns,
-             oid    pre,
-             size_t nattrs,
-             oid   *attr_own,
-             oid   *attr_qn,
-             oid   *attr_prop,
-             BAT   *qn_loc,
-             BAT   *qn_uri,
+             oid    owner,
+             char  *uri,
+             char  *loc,
+             BAT   *attr_own,
+             BAT   *attr_qn,
+             oid   *attr_propT,
+             BAT   *qn_uri_loc,
              BAT   *prop_val)
 {
-    oid qn = oid_nil ;
-    size_t i = 0;
-    int first = 0, len = 0;
-    char *err = NULL;
-
-    len = strlen(attr_name) + strlen(ns) + 128;
-    err = alloca(len);  assert(err);
+    BAT *match = NULL, *qn_uri_loc_sel = NULL;
+    BAT *attr_own_sel = NULL, *attr_qn_sel = NULL;
+    BATiter matchi, prop_vali;
+    char err[1024], *uri_loc = NULL, *res = NULL;
+    oid off = oid_nil ;
 
-    /* Get the 'qn' of 'attr_name'.  For now, all XRPC attributes may
-     * appear only once in the message, so the combination of ns+loc
-     * should be unique. */
-    BAT *qns = BATselect(qn_loc, attr_name, attr_name);
-    BAT *nss = BATselect(qn_uri, ns, ns);
-    BAT *match = BATkintersect(qns, nss);
+    /* cancatenate 'uri':'loc' */
+    uri_loc = strs_concat(uri, loc);
+    if(!uri_loc) {
+        send_err(out, 1, ERR500, "env:Receiver", OUT_OF_MEM);
+        goto get_attr_val_failed;
+    }
 
-    i = BATcount(match);
-    if(i > 1){
-        snprintf(err, len, "Invalid XRPC request message: multiple "
-                "definitions of attribute %s:%s\n", ns, attr_name);
+    /* BATselect(BAT *, (ptr)lowerbound, (ptr)upperbound) */
+    attr_own_sel = BATselect(attr_own, (ptr)&owner, (ptr)&owner);
+    if(!optional && (!attr_own_sel || BATcount(attr_own_sel) == 0)){
+        snprintf(err, 1024,
+                "Element with pre "OIDFMT" does not have an attribute 
\"%s:%s\"",
+                owner, uri, loc);
         send_err(out, 1, ERR404, "env:Sender", err);
-        BBPreclaim(qns);
-        BBPreclaim(nss);
-        BBPreclaim(match);
-        return NULL;
-    } else if (i == 1) {
-        BATiter matchi = bat_iterator(match), prop_vali = 
bat_iterator(prop_val);
-        qn = *(oid*) BUNhead(matchi, BUNfirst(match));
+        goto get_attr_val_failed;
+    }
 
-        BBPreclaim(qns);
-        BBPreclaim(nss);
-        BBPreclaim(match);
+    /* Get the 'qn' of 'uri':'loc': */
+    qn_uri_loc_sel = BATselect(qn_uri_loc, uri_loc, uri_loc);
+    if(!optional && (!qn_uri_loc_sel || BATcount(qn_uri_loc_sel) == 0)){
+        snprintf(err, 1024, "Could not find required attribute \"%s:%s\"", 
uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_val_failed;
+    }
 
-        /* try to find the attribute value */
-        for (i = 0; i < nattrs; i++) {
-            if (attr_own[i] > pre) break;
-            if (attr_own[i] == pre && attr_qn[i] == qn) {
-                first = BUNfirst(prop_val) + attr_prop[i];
-                return (char*) BUNtail(prop_vali, first);
-            }
-        }
+    /* BATjoin(BAT[A,B], BAT[C,D]): join on (B,C) => BAT[A,D]
+     * now we have attr IDs in head */
+    attr_qn_sel = BATjoin(attr_qn, qn_uri_loc_sel, oid_nil);
+    if(!optional && (!attr_qn_sel || BATcount(attr_qn_sel) == 0)){
+        snprintf(err, 1024, "Could not find required attribute \"%s:%s\"", 
uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_val_failed;
     }
 
-    if(!optional) {
-        snprintf(err, len,
-                "Could not find required attribute \"%s:%s\"",
-                ns, attr_name);
+    /* BATkintersect(BAT[A,B], BAT[C,D]): join on (A,C) => BAT[A,B] */
+    match = BATkintersect(attr_own_sel, attr_qn_sel);
+    if(!optional && (!match || BATcount(match) == 0)){
+        snprintf(err, 1024,
+                "Element with pre "OIDFMT" does not have an attribute 
\"%s:%s\"",
+                owner, uri, loc);
         send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_val_failed;
+    } else if(BATcount(match) > 1) {
+        snprintf(err, 1024,
+                "Element with pre "OIDFMT" has more than one attribute 
\"%s:%s\"",
+                owner, uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_val_failed;
     }
+
+    matchi = bat_iterator(match);
+    prop_vali = bat_iterator(prop_val);
+    off = *(oid*) BUNhead(matchi, BUNfirst(match)); /* attr ID */
+    off = attr_propT[off]; /* prop ID */
+    res = (char*)BUNtail(prop_vali, BUNfnd(prop_val, (ptr)&off));
+    if(!res)
+        goto get_attr_val_failed;
+
+    GDKfree(uri_loc);
+    BBPreclaim(attr_own_sel);
+    BBPreclaim(qn_uri_loc_sel);
+    BBPreclaim(attr_qn_sel);
+    BBPreclaim(match);
+    return res;
+
+get_attr_val_failed:
+    if(uri_loc) GDKfree(uri_loc);
+    if(attr_own_sel) BBPreclaim(attr_own_sel);
+    if(qn_uri_loc_sel) BBPreclaim(qn_uri_loc_sel);
+    if(attr_qn_sel) BBPreclaim(attr_qn_sel);
+    if(match) BBPreclaim(match);
     return NULL;
 }
 
+/* Find the PRE of the owner of attribute 'uri':'loc'='val'
+ * If 'del' is TRUE, delete the entry [attr, PRE] from 'attr_own',
+ * this feature is special for xrpc:id attributes, which invalidate an
+ * XML fragment, and hence should be used by the XRPC server, after
+ * shredding a request message.
+ *
+ * Returns: PRE of the owner, or -1 by error.
+ */
+static int
+get_attr_own(stream *out,
+             bool    del,
+             char   *uri,
+             char   *loc,
+             char   *val,
+             BAT    *attr_own,
+             BAT    *attr_qn,
+             BAT    *attr_prop,
+             BAT    *qn_uri_loc,
+             BAT    *prop_val)
+{
+    BAT *qn_uri_loc_sel = NULL, *attr_qn_sel = NULL, *attr_qn_sel2 = NULL;
+    BAT *prop_val_sel = NULL, *attr_prop_sel = NULL;
+    char err[1024], *uri_loc = NULL;
+    oid attr = oid_nil, res = oid_nil;
+    BUN bun = BUN_NONE;
+    BATiter attr_qni, attr_owni;
+
+    /* cancatenate 'uri':'loc' */
+    uri_loc = strs_concat(uri, loc);
+    if(!uri_loc) {
+        send_err(out, 1, ERR500, "env:Receiver", OUT_OF_MEM);
+        goto get_attr_own_failed;
+    }
+
+    /* Get the 'qn' of 'uri':'loc': */
+    qn_uri_loc_sel = BATselect(qn_uri_loc, uri_loc, uri_loc);
+    if(!qn_uri_loc_sel || BATcount(qn_uri_loc_sel) == 0){
+        snprintf(err, 1024, "Could not find required attribute \"%s:%s\"", 
uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+
+    /* BATjoin(BAT[A,B], BAT[C,D]): join on (B,C) => BAT[A,D]
+     * now we have attr IDs in head */
+    attr_qn_sel = BATjoin(attr_qn, qn_uri_loc_sel, oid_nil);
+    if(!attr_qn_sel || BATcount(attr_qn_sel) == 0){
+        snprintf(err, 1024, "Could not find required attribute \"%s:%s\"", 
uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+
+    prop_val_sel = BATselect(prop_val, val, val);
+    if(!prop_val_sel || BATcount(prop_val_sel) == 0){
+        snprintf(err, 1024, "Attribute value \"%s\" not found", val);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+
+    /* now we have attr IDs in head */
+    attr_prop_sel = BATjoin(attr_prop, prop_val_sel, oid_nil);
+    if(!attr_prop_sel || BATcount(attr_prop_sel) == 0){
+        snprintf(err, 1024, "Could not find required attribute \"%s:%s\"", 
uri, loc);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+
+    /* BATkintersect(BAT[A,B], BAT[C,D]): join on (A,C) => BAT[A,B] */
+    attr_qn_sel2 = BATkintersect(attr_qn_sel, attr_prop_sel);
+    if(!attr_qn_sel2 || BATcount(attr_qn_sel2) == 0){
+        snprintf(err, 1024, "Could not find an attribute \"%s:%s\" with value 
\"%s\"",
+                uri, loc, val);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    } else if (BATcount(attr_qn_sel2) > 1) {
+        snprintf(err, 1024, "Attribute \"%s:%s\" with value \"%s\" is not 
unique!",
+                uri, loc, val);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+
+    attr_qni = bat_iterator(attr_qn_sel2);
+    attr = *(oid*) BUNhead(attr_qni, BUNfirst(attr_qn_sel2));
+    attr_owni = bat_iterator(attr_own);
+    BUNfndVOID(bun, attr_owni, (ptr)&attr);
+    if(bun == BUN_NONE) {
+        snprintf(err, 1024, "Could not find owner of attribute \"%s:%s\" with 
value \"%s\"",
+                uri, loc, val);
+        send_err(out, 1, ERR404, "env:Sender", err);
+        goto get_attr_own_failed;
+    }
+    res = *(oid*) BUNtail(attr_owni, bun);
+
+    if(del) {
+        if(BUNdelete(attr_own, bun, FALSE) == BUN_NONE){
+            GDKerror("get_attr_own: failed to delete "
+                    "attr_own["OIDFMT","OIDFMT"]\n", attr, res);
+            send_err(out, 1, ERR500, "env:Receiver",
+                    "Conflict occurs when updating (internal) DB");
+            goto get_attr_own_failed;
+        }
+    }
+
+    GDKfree(uri_loc);
+    BBPreclaim(qn_uri_loc_sel);
+    BBPreclaim(attr_qn_sel);
+    BBPreclaim(prop_val_sel);
+    BBPreclaim(attr_prop_sel);
+    BBPreclaim(attr_qn_sel2);
+    return res;
+
+get_attr_own_failed:
+    if(uri_loc) GDKfree(uri_loc);
+    if(qn_uri_loc_sel) BBPreclaim(qn_uri_loc_sel);
+    if(attr_qn_sel) BBPreclaim(attr_qn_sel);
+    if(prop_val_sel) BBPreclaim(prop_val_sel);
+    if(attr_prop_sel) BBPreclaim(attr_prop_sel);
+    if(attr_qn_sel2) BBPreclaim(attr_qn_sel2);
+    return -1;
+}
+
 /**
  * Given the pre value of a type node, return the name of the type node
  * as a string in the form 'ns_uri:loc'.
@@ -535,31 +705,26 @@
 static int
 getFunctionInfo(stream *out,
                 oid pre,
-                lng nattrs,
-                oid *attr_ownT,
-                oid *attr_qnT,
+                BAT *attr_own,
+                BAT *attr_qn,
                 oid *attr_propT,
-                BAT *qn_loc,
-                BAT *qn_uri,
+                BAT *qn_uri_loc,
                 BAT *prop_val,
                 str *_module,
                 str *_location,
                 str *_method) {
     char *module = NULL, *location = NULL, *method = NULL;
 
-    if (!(module = get_attr_val(out, 0, "module", XRPC_NS, pre, nattrs,
-                    attr_ownT, attr_qnT, attr_propT, qn_loc, qn_uri,
-                    prop_val)))
+    if (!(module = get_attr_val(out, 0, pre, XRPC_NS, "module",
+                    attr_own, attr_qn, attr_propT, qn_uri_loc, prop_val)))
         return GDK_FAIL;
 
-    if (!(method = get_attr_val(out, 0, "method", XRPC_NS, pre, nattrs,
-                    attr_ownT, attr_qnT, attr_propT, qn_loc, qn_uri,
-                    prop_val)))
+    if (!(method = get_attr_val(out, 0, pre, XRPC_NS, "method",
+                    attr_own, attr_qn, attr_propT, qn_uri_loc, prop_val)))
         return GDK_FAIL;
 
-    if (!(location = get_attr_val(out, 0, "location", XRPC_NS, pre,
-                    nattrs, attr_ownT, attr_qnT, attr_propT, qn_loc,
-                    qn_uri, prop_val)))
+    if (!(location = get_attr_val(out, 0, pre, XRPC_NS, "location",
+                    attr_own, attr_qn, attr_propT, qn_uri_loc, prop_val)))
         return GDK_FAIL;
 
     *_module = module;
@@ -618,15 +783,15 @@
     lng argc = 0, iterc = 0, nr_args = 0;
     lng **argcnt;
     str *argtpe = NULL, *argval = NULL;
-
     lng i = 0, j = 0, k = 0, nattrs = 0;
     lng max_args = MAX_NR_PARAMS;
-    char errstr[1024];
+    char errstr[1024], ldiff = 0;
+    int res = -1;
 
     BATiter bi;
     BAT *frag_root = NULL, *pre_size = NULL;
     BAT *pre_level = NULL, *pre_kind = NULL,  *pre_prop = NULL;
-    BAT *qn_loc   = NULL,  *qn_uri = NULL;
+    BAT *qn_loc   = NULL,  *qn_uri = NULL, *qn_uri_loc = NULL;
     BAT *prop_val = NULL,  *prop_text = NULL;
     BAT *attr_own = NULL,  *attr_qn = NULL, *attr_prop = NULL;
     /* Arrays holding the Tail values of some of the BATs above. */
@@ -637,8 +802,9 @@
     oid   *pre_propT = NULL;
     var_t *prop_textT = NULL;
 
-    oid pre = 0, last_pre = 0, val_node_pre = 0;
+    oid pre = 0, req_node_pre = 0, last_pre = 0, val_node_pre = 0;
     oid seq_node_pre = 0,  call_node_pre = 0,  tpe_node_pre = 0;
+    oid frag_node_pre = 0;
     lng seq_node_size = 0, call_node_size = 0, tpe_node_size = 0;
     
     /* We need to clean up the pre_size, pre_level, pre_prop and
@@ -646,8 +812,6 @@
      * a node value is treated as part of the message */
     oid start_invalidate = 0; /* indicates from which node we should
                                  start with invalidation */
-    char level_diff = 0; /* indicates how many levels each pre_level
-                            value of a node should be reduced. */
 
     i = BUNfirst(shredBAT);
     bi = bat_iterator(shredBAT);
@@ -658,6 +822,7 @@
     prop_text  = BBP_cache(*(bat*)BUNtail(bi,i+PROP_TEXT));
     text_base  = BBP_cache(*(bat*)BUNtail(bi,i+PROP_TEXT))->theap->base;
     prop_val   = BBP_cache(*(bat*)BUNtail(bi,i+PROP_VAL) );
+    qn_uri_loc = BBP_cache(*(bat*)BUNtail(bi,i+QN_URI_LOC));
     qn_loc     = BBP_cache(*(bat*)BUNtail(bi,i+QN_LOC)   );
     qn_uri     = BBP_cache(*(bat*)BUNtail(bi,i+QN_URI)   );
     frag_root  = BBP_cache(*(bat*)BUNtail(bi,i+FRAG_ROOT));
@@ -674,8 +839,9 @@
     attr_qnT   = (oid*)  Tloc(attr_qn, BUNfirst(attr_qn));
     attr_propT = (oid*)  Tloc(attr_prop, BUNfirst(attr_prop));
 
-    pre_level  = BATsetaccess(pre_level, BAT_WRITE);
-    frag_root  = BATsetaccess(frag_root, BAT_APPEND);
+    /* don't change permission, as WS BATs might be shared */
+    //pre_level  = BATsetaccess(pre_level, BAT_WRITE);
+    //frag_root  = BATsetaccess(frag_root, BAT_APPEND);
     nattrs     = BATcount(attr_prop);
     last_pre   = (oid)pre_sizeT[0]; /* last 'pre' number, save it before
                                        it is overwritten. */
@@ -683,7 +849,7 @@
     /* There are at least two nodes before "request", namely "Envelope"
      * and "Body" (a "Header" node is optional). There are at least one
      * node after "request", namely "sequence". */
-    if (!(pre = get_elem_pre_by_name("request", XRPC_NS, 2,
+    if (!(req_node_pre = get_elem_pre_by_name("request", XRPC_NS, 2,
                     (last_pre - 1), ELEMENT, pre_propT, pre_kindT,
                     qn_loc, qn_uri))) {
         send_err(out, 1, ERR404, "env:Sender",
@@ -691,26 +857,25 @@
         return GDK_FAIL;
     }
 
-    if(getFunctionInfo(out, pre, nattrs,
-                        attr_ownT, attr_qnT, attr_propT,
-                        qn_loc, qn_uri, prop_val,
-                        module, location, method) == GDK_FAIL ||
+    if(getFunctionInfo(out, req_node_pre, attr_own, attr_qn, attr_propT,
+                       qn_uri_loc, prop_val,
+                       module, location, method) == GDK_FAIL ||
         (!isAdmin && !isTrusted(out, *location)) )
         return GDK_FAIL;
 
     char *val_ptr = NULL;
-    val_ptr = get_attr_val(out, 1, "iter-count", XRPC_NS, pre, nattrs,
-            attr_ownT, attr_qnT, attr_propT, qn_loc, qn_uri, prop_val);
+    val_ptr = get_attr_val(out, 1, req_node_pre, XRPC_NS, "iter-count",
+            attr_own, attr_qn, attr_propT, qn_uri_loc, prop_val);
     if(!val_ptr) {
         /* the optional attribute "iter-count" is not available, so just
          * count the number of "call" node */
-        iterc = count_node("call", XRPC_NS, pre+1, last_pre, pre_propT,
+        iterc = count_node("call", XRPC_NS, req_node_pre+1, last_pre, 
pre_propT,
                 pre_kindT, qn_loc, qn_uri);
     } else {
         iterc = my_strtoll(out, val_ptr, "iter-count");
         if(iterc < 0 )
             return GDK_FAIL;
-        i = count_node("call", XRPC_NS, pre+1, last_pre, pre_propT,
+        i = count_node("call", XRPC_NS, req_node_pre+1, last_pre, pre_propT,
                 pre_kindT, qn_loc, qn_uri);
         if (iterc != i) {
             snprintf(errstr, 1024, "The value (%lld) of the attribute "
@@ -721,15 +886,15 @@
         }
     }
 
-    val_ptr = get_attr_val(out, 0, "arity", XRPC_NS, pre, nattrs,
-                           attr_ownT, attr_qnT, attr_propT, qn_loc,
-                           qn_uri, prop_val);
+    val_ptr = get_attr_val(out, 0, req_node_pre, XRPC_NS, "arity",
+                           attr_own, attr_qn, attr_propT, qn_uri_loc,
+                           prop_val);
     if(!val_ptr)
         return GDK_FAIL;
     argc = my_strtoll(out, val_ptr, "arity");
     if(argc < 0 )
         return GDK_FAIL;
-    i = count_node("sequence", XRPC_NS, pre+2, last_pre, pre_propT,
+    i = count_node("sequence", XRPC_NS, req_node_pre+2, last_pre, pre_propT,
             pre_kindT, qn_loc, qn_uri) / iterc;
     if(argc != i){
         snprintf(errstr, 1024, "The value (%lld) of the attribute "
@@ -769,7 +934,7 @@
     }
    
     /* Fill the arrays 'argcnt', 'argval', 'argtpe' */
-    call_node_pre = pre;
+    call_node_pre = req_node_pre;
     for (i = 0; i < iterc; i++) {
         call_node_pre  = get_elem_pre_by_name("call", XRPC_NS,
                 (call_node_pre + call_node_size + 1), last_pre, ELEMENT,
@@ -822,12 +987,9 @@
                 }
                 
                 if(strcmp(argtpe[nr_args], "xrpc:atomic-value") == 0) {
-                    GDKfree(argtpe[nr_args]); /* find sub-type of the
-                                                 atomic-value */
-                    char *tptr = get_attr_val(out, 0, "type", XSI_NS,
-                                    tpe_node_pre, nattrs, attr_ownT,
-                                    attr_qnT, attr_propT, qn_loc,
-                                    qn_uri, prop_val);
+                    GDKfree(argtpe[nr_args]); /* find sub-type of the 
atomic-value */
+                    char *tptr = get_attr_val(out, 0, tpe_node_pre, XSI_NS, 
"type",
+                                    attr_own, attr_qn, attr_propT, qn_uri_loc, 
prop_val);
                     if(!tptr){
                         send_err(out, 1, ERR404, "env:Sender",
                                 "XRPC request: an \"atomic-value\" "
@@ -841,10 +1003,8 @@
                     if( (tpe_node_size != 1) || 
                         (pre_kindT[val_node_pre] != TEXT) ) {
                         snprintf(errstr, 1024, "XRPC request: "
-                                "iteration" LLFMT "/parameter" LLFMT
-                                                  "/value" LLFMT " "
-                                "of type \"%s\" is expected to have a "
-                                "simple value",
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
+                                "of type \"%s\" is expected to have a simple 
value",
                                 i+1, j+1, k, argtpe[nr_args]);
                         send_err(out, 1, ERR404, "env:Sender", errstr);
                         clean_up(argcnt,argtpe,argval,iterc,nr_args);
@@ -872,7 +1032,7 @@
                     }
                     if (val_node_pre == 0) {
                         snprintf(errstr, 1024, "XRPC request: "
-                                "iteration" LLFMT "/param" LLFMT "/value" 
LLFMT " "
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
                                 "does not contain a *node* value",
                                 i+1, j+1, k);
                         send_err(out, 1, ERR404, "env:Sender", errstr);
@@ -892,66 +1052,56 @@
                         return GDK_FAIL;
                     }
 
-                    if(strcmp(argtpe[nr_args], "xs:element") == 0) {
-                        val_node_pre = get_elem_pre(tpe_node_pre+1,
-                                (tpe_node_pre+tpe_node_size), ELEMENT,
-                                pre_kindT);
-                    } else if (strcmp(argtpe[nr_args], "xs:text") == 0) {
-                        val_node_pre = get_elem_pre(tpe_node_pre+1,
-                                (tpe_node_pre+tpe_node_size), TEXT,
-                                pre_kindT);
-                    } else if (strcmp(argtpe[nr_args], "xs:comment") == 0) {
-                        val_node_pre = get_elem_pre(tpe_node_pre+1,
-                                (tpe_node_pre+tpe_node_size), COMMENT,
-                                pre_kindT);
-                    } else if(strcmp(argtpe[nr_args],
-                                "xs:processing-instruction") == 0) {
-                        val_node_pre = get_elem_pre(tpe_node_pre+1,
-                                (tpe_node_pre+tpe_node_size), PI,
-                                pre_kindT);
-                    } else if (strcmp(argtpe[nr_args], "xs:document") == 0) {
-                        val_node_pre = tpe_node_pre;
-                        pre_kindT[val_node_pre] = 4;
-                        pre_propT[val_node_pre] = oid_nil;
-                    } else {
+                    if(strcmp(argtpe[nr_args], "xs:element") != 0 &&
+                       strcmp(argtpe[nr_args], "xs:text") != 0 &&
+                       strcmp(argtpe[nr_args], "xs:comment") != 0 &&
+                       strcmp(argtpe[nr_args], "xs:pi") != 0 &&
+                       strcmp(argtpe[nr_args], "xs:document") != 0) {
                         snprintf(errstr, 1024, "XRPC request: "
-                                "iteration" LLFMT "/param" LLFMT
-                                                  "/value" LLFMT " "
-                                "contains unsupported type: %s\n",
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
+                                " has unsupported type: %s\n",
                                 i+1, j+1, k, argtpe[nr_args]);
                         send_err(out, 1, ERR404, "env:Sender", errstr);
                         clean_up(argcnt,argtpe,argval,iterc,nr_args);
                         return GDK_FAIL;
                     }
 
-                    if (val_node_pre == 0) {
+                    char *idref = get_attr_val(out, 0, tpe_node_pre, XRPC_NS, 
"idref",
+                                               attr_own, attr_qn, attr_propT,
+                                               qn_uri_loc, prop_val);
+                    if(!idref){
                         snprintf(errstr, 1024, "XRPC request: "
-                                "iteration" LLFMT "/param" LLFMT
-                                                  "/value" LLFMT " "
-                                "does not contain a *node* value",
-                                i+1, j+1, k);
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
+                                " of type \"%s\" does not have an xrpc:idref 
attribute\n",
+                                i+1, j+1, k, argtpe[nr_args]);
                         send_err(out, 1, ERR404, "env:Sender", errstr);
                         clean_up(argcnt,argtpe,argval,iterc,nr_args);
                         return GDK_FAIL;
                     }
 
+                    /* NOTE: if the type of this note-typed parameter
+                     *       value is "xs:document", the xrpc:fragment
+                     *       node containing the doc fragment should
+                     *       have the "xrpc:id" attribute, and
+                     *       val_node_pre will point to the
+                     *       "xrpc:fragment" node.  The post-processing
+                     *       below will change all "xrpc:fragment" node
+                     *       into a document node */
+                    res = get_attr_own(out, TRUE, XRPC_NS,
+                            "id", idref, attr_own, attr_qn, attr_prop,
+                            qn_uri_loc, prop_val);
+                    if (res < 0) {
+                        snprintf(errstr, 1024,
+                                "XRPC request: could not find the element 
referred by "
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]",
+                                i+1, j+1, k);
+                        send_err(out, 1, ERR404, "env:Sender", errstr);
+                        clean_up(argcnt,argtpe,argval,iterc,nr_args);
+                        return GDK_FAIL;
+                    }
+                    val_node_pre = (oid) res;
                     snprintf(argval[nr_args], 32, OIDFMT, val_node_pre);
-                    frag_root = BUNappend(frag_root, (ptr)&val_node_pre, TRUE);
                     isSimpleParam = 0;
-
-                    /* reassign level values for the ELEM nodes */
-                    level_diff = pre_levelT[val_node_pre];
-                    if(strcmp(argtpe[nr_args], "xs:document") == 0)
-                        level_diff++;
-                    unsigned long long l = val_node_pre;
-                    for( ; l <= (val_node_pre + pre_sizeT[val_node_pre]); l++){
-                        pre_levelT[l] -= level_diff;
-                    }
-                    for (l = start_invalidate; l < val_node_pre; l++) {
-                        pre_levelT[l] = -3;
-                        pre_sizeT[l] = 0;
-                    }
-                    start_invalidate = val_node_pre + pre_sizeT[val_node_pre] 
+ 1;
                 }
                 /* skip all children of tpe_node and go to the next
                  * possible tpe_node */
@@ -963,6 +1113,43 @@
         } /* end FOR 'argc' */
     } /* end FOR 'iterc' */
 
+    /* Post-processing: transform each "xrpc:fragment" node into a
+     * document node and invalidate all nodes above them */
+    if(!isSimpleParam){
+        pre = get_elem_pre_by_name("fragments", XRPC_NS, req_node_pre+1,
+                req_node_pre+pre_sizeT[req_node_pre], ELEMENT, pre_propT, 
pre_kindT,
+                qn_loc, qn_uri);
+        if(!pre) {
+            send_err(out, 1, ERR404, "env:Sender",
+                    "XRPC request: 'xrpc:fragments' not found, required by 
node-typed parameters");
+            clean_up(argcnt,argtpe,argval,iterc,nr_args);
+            return GDK_FAIL;
+        }
+
+        frag_node_pre = pre;
+        start_invalidate = 0;
+        while((frag_node_pre = get_elem_pre_by_name("fragment", XRPC_NS,
+                    frag_node_pre+1, frag_node_pre+pre_sizeT[pre], ELEMENT, 
pre_propT,
+                    pre_kindT, qn_loc, qn_uri)) > 0) {
+            /* transform this xrpc:fragment node into a document node and 
adjust
+             * the level of its subtree */
+            ldiff = pre_levelT[frag_node_pre] + 1;
+            for(i = frag_node_pre; (oid)i < (frag_node_pre + 
pre_sizeT[frag_node_pre] + 1); i++)
+                pre_levelT[i] -= ldiff;
+            pre_propT[frag_node_pre] = oid_nil;
+            pre_kindT[frag_node_pre] = '\004';
+            /* add this xrpc:fragment as a document */
+            frag_root = BUNappend(frag_root, (ptr)&frag_node_pre, FALSE);
+            /* invalidate all nodes above/before this xrpc:fragment */
+            for (i = start_invalidate; (oid)i < frag_node_pre; i++) {
+                pre_levelT[i] = -3;
+                pre_sizeT[i] = 0;
+                pre_propT[i] = oid_nil;
+            }
+            start_invalidate = frag_node_pre + 1;
+        }
+    }
+
     *_isSimpleParam = isSimpleParam;
     *_argc = argc;
     *_iterc = iterc;


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to