00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "xmlMS.h"
00010
00011 #include <libxml/tree.h>
00012 #include <libxml/parser.h>
00013 #include <libxml/xpath.h>
00014 #include <libxml/xpathInternals.h>
00015 #include <libxml/xmlschemas.h>
00016
00017
00018
00019
00020
00021
00022
00023 static xmlNodePtr
00024 getChildNodeByName(xmlNodePtr cur, char *name)
00025 {
00026 if (cur == NULL || name == NULL)
00027 {
00028 return NULL;
00029 }
00030
00031 for(cur=cur->children; cur != NULL; cur=cur->next)
00032 {
00033 if(cur->name && (strcmp((char*)cur->name, name) == 0))
00034 {
00035 return cur;
00036 }
00037 }
00038
00039 return NULL;
00040 }
00041
00042
00043
00044
00045 static int
00046 myErrorCallback(bytesBuf_t *errBuf, const char* errMsg, ...)
00047 {
00048 va_list ap;
00049 char tmpStr[MAX_NAME_LEN];
00050 int written;
00051
00052 va_start(ap, errMsg);
00053 written = vsnprintf(tmpStr, MAX_NAME_LEN, errMsg, ap);
00054 va_end(ap);
00055
00056 appendToByteBuf(errBuf, tmpStr);
00057 return (written);
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #if defined(LIBXML_XPATH_ENABLED) && \
00096 defined(LIBXML_SAX1_ENABLED) && \
00097 defined(LIBXML_OUTPUT_ENABLED)
00098
00099 int
00100 msiLoadMetadataFromXml(msParam_t *targetObj, msParam_t *xmlObj, ruleExecInfo_t *rei)
00101 {
00102
00103 dataObjInp_t xmlDataObjInp, *myXmlDataObjInp;
00104 dataObjInp_t targetObjInp, *myTargetObjInp;
00105 int xmlObjID;
00106
00107
00108 rodsObjStat_t *rodsObjStatOut = NULL;
00109
00110
00111 openedDataObjInp_t openedDataObjInp;
00112 bytesBuf_t *xmlBuf;
00113
00114
00115 rsComm_t *rsComm;
00116
00117
00118 xmlDocPtr doc;
00119
00120
00121 xmlXPathContextPtr xpathCtx;
00122 xmlXPathObjectPtr xpathObj;
00123 xmlChar xpathExpr[] = "//AVU";
00124 xmlNodeSetPtr nodes;
00125 int avuNbr, i;
00126
00127
00128 modAVUMetadataInp_t modAVUMetadataInp;
00129 int max_attr_len = 2700;
00130 char attrStr[max_attr_len];
00131
00132
00133
00134
00135
00136
00137 RE_TEST_MACRO (" Calling msiLoadMetadataFromXml")
00138
00139
00140
00141 if (rei == NULL || rei->rsComm == NULL)
00142 {
00143 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input rei or rsComm is NULL.");
00144 return (SYS_INTERNAL_NULL_INPUT_ERR);
00145 }
00146
00147 rsComm = rei->rsComm;
00148
00149
00150
00151
00152
00153
00154 rei->status = parseMspForDataObjInp (targetObj, &targetObjInp, &myTargetObjInp, 0);
00155 if (rei->status < 0)
00156 {
00157 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input targetObj error. status = %d", rei->status);
00158 return (rei->status);
00159 }
00160
00161
00162
00163 rei->status = parseMspForDataObjInp (xmlObj, &xmlDataObjInp, &myXmlDataObjInp, 0);
00164 if (rei->status < 0)
00165 {
00166 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input xmlObj error. status = %d", rei->status);
00167 return (rei->status);
00168 }
00169
00170
00171
00172
00173
00174
00175 if ((xmlObjID = rsDataObjOpen(rsComm, &xmlDataObjInp)) < 0)
00176 {
00177 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Cannot open XML data object. status = %d", xmlObjID);
00178 return (xmlObjID);
00179 }
00180
00181
00182
00183 rei->status = rsObjStat (rsComm, &xmlDataObjInp, &rodsObjStatOut);
00184 if( NULL == rodsObjStatOut ) {
00185 rodsLog( LOG_ERROR, "msiXmlDocSchemaValidate: null &rodsObjStatOut" );
00186 return ( rei->status );
00187 }
00188
00189
00190
00191 xmlBuf = (bytesBuf_t *) malloc (sizeof (bytesBuf_t));
00192 memset (xmlBuf, 0, sizeof (bytesBuf_t));
00193
00194
00195
00196 memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
00197 openedDataObjInp.l1descInx = xmlObjID;
00198 openedDataObjInp.len = (int)rodsObjStatOut->objSize;
00199
00200 rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);
00201
00202
00203 if (strlen((char*)xmlBuf->buf) > (size_t)openedDataObjInp.len)
00204 {
00205 ((char*)xmlBuf->buf)[openedDataObjInp.len-1]='\0';
00206 }
00207
00208
00209
00210 rei->status = rsDataObjClose (rsComm, &openedDataObjInp);
00211
00212
00213 freeRodsObjStat (rodsObjStatOut);
00214
00215
00216
00217
00218
00219 xmlSubstituteEntitiesDefault(1);
00220 xmlLoadExtDtdDefaultValue = 1;
00221
00222
00223
00224 doc = xmlParseDoc((xmlChar*)xmlBuf->buf);
00225
00226
00227
00228 xpathCtx = xmlXPathNewContext(doc);
00229 if(xpathCtx == NULL)
00230 {
00231 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Unable to create new XPath context.");
00232 xmlFreeDoc(doc);
00233 return(-1);
00234 }
00235
00236
00237
00238 xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
00239 if(xpathObj == NULL)
00240 {
00241 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Unable to evaluate XPath expression \"%s\".", xpathExpr);
00242 xmlXPathFreeContext(xpathCtx);
00243 xmlFreeDoc(doc);
00244 return(-1);
00245 }
00246
00247
00248 if ((nodes = xpathObj->nodesetval) != NULL)
00249 {
00250 avuNbr = nodes->nodeNr;
00251 }
00252 else
00253 {
00254 avuNbr = 0;
00255 }
00256
00257
00258
00259
00260
00261
00262 for(i = 0; i < avuNbr; i++)
00263 {
00264 if (nodes->nodeTab[i])
00265 {
00266
00267
00268
00269
00270
00271 memset(attrStr, '\0', max_attr_len);
00272 snprintf(attrStr, max_attr_len - 1, "%s", (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Attribute")) );
00273
00274
00275 memset (&modAVUMetadataInp, 0, sizeof(modAVUMetadataInp_t));
00276 modAVUMetadataInp.arg0 = "add";
00277 modAVUMetadataInp.arg1 = "-d";
00278
00279
00280 if (myTargetObjInp->objPath != NULL && strlen(myTargetObjInp->objPath) > 0)
00281 {
00282 modAVUMetadataInp.arg2 = myTargetObjInp->objPath;
00283 }
00284 else
00285 {
00286 modAVUMetadataInp.arg2 = (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Target"));
00287 }
00288
00289 modAVUMetadataInp.arg3 = attrStr;
00290 modAVUMetadataInp.arg4 = (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Value"));
00291 modAVUMetadataInp.arg5 = (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Unit"));
00292
00293
00294 rei->status = rsModAVUMetadata (rsComm, &modAVUMetadataInp);
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303 xmlFreeDoc(doc);
00304 xmlCleanupParser();
00305
00306 return (rei->status);
00307 }
00308
00309
00310
00311 #else
00312
00313
00314
00315 int
00316 msiLoadMetadataFromXml(msParam_t *targetObj, msParam_t *xmlObj, ruleExecInfo_t *rei)
00317 {
00318 rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: XPath support not compiled in.");
00319 return (SYS_NOT_SUPPORTED);
00320 }
00321 #endif
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 int
00359 msiXmlDocSchemaValidate(msParam_t *xmlObj, msParam_t *xsdObj, msParam_t *status, ruleExecInfo_t *rei)
00360 {
00361
00362 dataObjInp_t xmlObjInp, *myXmlObjInp;
00363 dataObjInp_t xsdObjInp, *myXsdObjInp;
00364 int xmlObjID, xsdObjID;
00365
00366
00367 rodsObjStat_t *rodsObjStatOut = NULL;
00368
00369
00370 openedDataObjInp_t openedDataObjInp;
00371 bytesBuf_t *xmlBuf = NULL;
00372 char *tail;
00373
00374
00375 xmlDocPtr doc, xsd_doc;
00376 xmlSchemaParserCtxtPtr parser_ctxt;
00377 xmlSchemaPtr schema;
00378 xmlSchemaValidCtxtPtr valid_ctxt;
00379 bytesBuf_t *errBuf;
00380
00381
00382 rsComm_t *rsComm;
00383
00384
00385
00386
00387
00388
00389 RE_TEST_MACRO (" Calling msiXmlDocSchemaValidate")
00390
00391
00392
00393 if (rei == NULL || rei->rsComm == NULL)
00394 {
00395 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input rei or rsComm is NULL.");
00396 return (SYS_INTERNAL_NULL_INPUT_ERR);
00397 }
00398
00399 rsComm = rei->rsComm;
00400
00401
00402
00403
00404
00405
00406 xmlSubstituteEntitiesDefault(1);
00407 xmlLoadExtDtdDefaultValue = 1;
00408
00409
00410
00411 errBuf = (bytesBuf_t *)malloc(sizeof(bytesBuf_t));
00412 errBuf->buf = strdup("");
00413 errBuf->len = strlen((char*)errBuf->buf);
00414
00415
00416 fillBufLenInMsParam (status, -1, NULL);
00417
00418
00419
00420
00421
00422 rei->status = parseMspForDataObjInp (xmlObj, &xmlObjInp, &myXmlObjInp, 0);
00423 if (rei->status < 0)
00424 {
00425 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input xmlObj error. status = %d", rei->status);
00426 free( errBuf.buf );
00427 free( errBuf );
00428 return (rei->status);
00429 }
00430
00431
00432
00433 rei->status = parseMspForDataObjInp (xsdObj, &xsdObjInp, &myXsdObjInp, 0);
00434 if (rei->status < 0)
00435 {
00436 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input xsdObj error. status = %d", rei->status);
00437 free( errBuf.buf );
00438 free( errBuf );
00439 return (rei->status);
00440 }
00441
00442
00443
00444
00445
00446 if ((xmlObjID = rsDataObjOpen(rsComm, &xmlObjInp)) < 0)
00447 {
00448 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Cannot open XML data object. status = %d", xmlObjID);
00449 free( errBuf.buf );
00450 free( errBuf );
00451 return (xmlObjID);
00452 }
00453
00454
00455
00456 rei->status = rsObjStat (rsComm, &xmlObjInp, &rodsObjStatOut);
00457 if( NULL == rodsObjStatOut ) {
00458 rodsLog( LOG_ERROR, "msiXmlDocSchemaValidate: null &rodsObjStatOut" );
00459 free( errBuf );
00460 return ( rei->status );
00461 }
00462
00463
00464
00465 xmlBuf = (bytesBuf_t *) malloc (sizeof (bytesBuf_t));
00466 memset (xmlBuf, 0, sizeof (bytesBuf_t));
00467
00468
00469
00470 memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
00471 openedDataObjInp.l1descInx = xmlObjID;
00472 openedDataObjInp.len = (int)rodsObjStatOut->objSize + 1;
00473
00474 rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);
00475
00476
00477 tail = (char*)xmlBuf->buf;
00478 tail[openedDataObjInp.len - 1] = '\0';
00479
00480
00481
00482 rei->status = rsDataObjClose (rsComm, &openedDataObjInp);
00483
00484
00485 freeRodsObjStat (rodsObjStatOut);
00486
00487
00488
00489
00490
00491
00492 doc = xmlParseDoc((xmlChar*)xmlBuf->buf);
00493 clearBBuf(xmlBuf);
00494
00495 if (doc == NULL)
00496 {
00497 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: XML document cannot be loaded or is not well-formed.");
00498
00499 xmlCleanupParser();
00500
00501 free( errBuf.buf );
00502 free( errBuf );
00503 return (USER_INPUT_FORMAT_ERR);
00504 }
00505
00506
00507
00508
00509
00510
00511 if ((xsdObjID = rsDataObjOpen(rsComm, &xsdObjInp)) < 0)
00512 {
00513 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Cannot open XSD data object. status = %d", xsdObjID);
00514
00515 xmlFreeDoc(doc);
00516 xmlCleanupParser();
00517
00518 free( errBuf.buf );
00519 free( errBuf );
00520 return (xsdObjID);
00521 }
00522
00523
00524
00525 rei->status = rsObjStat (rsComm, &xsdObjInp, &rodsObjStatOut);
00526
00527
00528
00529 memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
00530 openedDataObjInp.l1descInx = xsdObjID;
00531 openedDataObjInp.len = (int)rodsObjStatOut->objSize + 1;
00532
00533 rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);
00534
00535
00536 tail = (char*)xmlBuf->buf;
00537 tail[openedDataObjInp.len - 1] = '\0';
00538
00539
00540
00541 rei->status = rsDataObjClose (rsComm, &openedDataObjInp);
00542
00543
00544 freeRodsObjStat (rodsObjStatOut);
00545
00546
00547
00548
00549
00550
00551 xsd_doc = xmlParseDoc((xmlChar*)xmlBuf->buf);
00552 clearBBuf(xmlBuf);
00553
00554 if (xsd_doc == NULL)
00555 {
00556 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: XML Schema cannot be loaded or is not well-formed.");
00557
00558 xmlFreeDoc(doc);
00559 xmlCleanupParser();
00560
00561 free( errBuf.buf );
00562 free( errBuf );
00563 return (USER_INPUT_FORMAT_ERR);
00564 }
00565
00566
00567
00568
00569
00570
00571 parser_ctxt = xmlSchemaNewDocParserCtxt(xsd_doc);
00572 if (parser_ctxt == NULL)
00573 {
00574 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Unable to create a parser context for the schema.");
00575
00576 xmlFreeDoc(xsd_doc);
00577 xmlFreeDoc(doc);
00578 xmlCleanupParser();
00579
00580 free( errBuf.buf );
00581 free( errBuf );
00582 return (USER_INPUT_FORMAT_ERR);
00583 }
00584
00585
00586
00587 schema = xmlSchemaParse(parser_ctxt);
00588 if (schema == NULL)
00589 {
00590 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Invalid schema.");
00591
00592 xmlSchemaFreeParserCtxt(parser_ctxt);
00593 xmlFreeDoc(doc);
00594 xmlFreeDoc(xsd_doc);
00595 xmlCleanupParser();
00596
00597 free( errBuf.buf );
00598 free( errBuf );
00599 return (USER_INPUT_FORMAT_ERR);
00600 }
00601
00602
00603
00604 valid_ctxt = xmlSchemaNewValidCtxt(schema);
00605 if (valid_ctxt == NULL)
00606 {
00607 rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Unable to create a validation context for the schema.");
00608
00609 xmlSchemaFree(schema);
00610 xmlSchemaFreeParserCtxt(parser_ctxt);
00611 xmlFreeDoc(xsd_doc);
00612 xmlFreeDoc(doc);
00613 xmlCleanupParser();
00614
00615 free( errBuf.buf );
00616 free( errBuf );
00617 return (USER_INPUT_FORMAT_ERR);
00618 }
00619
00620
00621
00622 xmlSchemaSetValidErrors(valid_ctxt, (xmlSchemaValidityErrorFunc)myErrorCallback, (xmlSchemaValidityWarningFunc)myErrorCallback, errBuf);
00623
00624
00625
00626 rei->status = xmlSchemaValidateDoc(valid_ctxt, doc);
00627
00628
00629
00630
00631
00632
00633 resetMsParam (status);
00634 fillBufLenInMsParam (status, rei->status, errBuf);
00635
00636
00637
00638 xmlSchemaFreeValidCtxt(valid_ctxt);
00639 xmlSchemaFree(schema);
00640 xmlSchemaFreeParserCtxt(parser_ctxt);
00641 xmlFreeDoc(doc);
00642 xmlFreeDoc(xsd_doc);
00643 xmlCleanupParser();
00644
00645 free( errBuf.buf );
00646 free( errBuf );
00647 return (rei->status);
00648 }
00649
00650