(file) Return to XmlReader.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

   1 mike  1.25 //%/////////////////////////////////////////////////////////////////////////////
   2 mike  1.23 //
   3 kumpf 1.58 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
   4 mike  1.25 // The Open Group, Tivoli Systems
   5 mike  1.23 //
   6            // Permission is hereby granted, free of charge, to any person obtaining a copy
   7 kumpf 1.58 // of this software and associated documentation files (the "Software"), to
   8            // deal in the Software without restriction, including without limitation the
   9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10 mike  1.23 // sell copies of the Software, and to permit persons to whom the Software is
  11            // furnished to do so, subject to the following conditions:
  12            // 
  13 kumpf 1.58 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  14 mike  1.23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  16 kumpf 1.58 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19 mike  1.23 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21            //
  22            //==============================================================================
  23            //
  24            // Author: Mike Brasher (mbrasher@bmc.com)
  25            //
  26 mike  1.25 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
  27            //                  (carolann_graves@hp.com)
  28            //              Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
  29            //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
  30 mike  1.23 //
  31            //%/////////////////////////////////////////////////////////////////////////////
  32 mday  1.45 #include <Pegasus/Common/Config.h>
  33 mike  1.23 #include <cctype>
  34            #include <cstdio>
  35            #include <cstdlib>
  36 ramnath 1.46 #if defined(PEGASUS_OS_TYPE_UNIX)
  37 mday    1.45 #include <errno.h>
  38              #endif
  39 mike    1.23 #include "CIMName.h"
  40              #include "XmlReader.h"
  41              #include "XmlWriter.h"
  42              #include "CIMQualifier.h"
  43              #include "CIMQualifierDecl.h"
  44              #include "CIMClass.h"
  45              #include "CIMInstance.h"
  46              #include "CIMObject.h"
  47 mike    1.25 #include "CIMParamValue.h"
  48 kumpf   1.72 #include "System.h"
  49 mike    1.23 
  50 kumpf   1.82 #define PEGASUS_SINT64_MIN (PEGASUS_SINT64_LITERAL(0x8000000000000000))
  51 kumpf   1.74 #define PEGASUS_UINT64_MAX PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)
  52 kumpf   1.68 
  53 mike    1.25 PEGASUS_USING_STD;
  54 mike    1.23 PEGASUS_NAMESPACE_BEGIN
  55              
  56              static const Uint32 MESSAGE_SIZE = 128;
  57              
  58              //------------------------------------------------------------------------------
  59              //
  60 kumpf   1.49 // getXmlDeclaration()
  61              //
  62              //     <?xml version="1.0" encoding="utf-8"?>
  63 mike    1.23 //
  64              //------------------------------------------------------------------------------
  65              
  66 kumpf   1.49 void XmlReader::getXmlDeclaration(
  67 mike    1.23     XmlParser& parser, 
  68 kumpf   1.49     const char*& xmlVersion,
  69                  const char*& xmlEncoding)
  70 mike    1.23 {
  71 kumpf   1.49     XmlEntry entry;
  72              
  73 mike    1.23     if (!parser.next(entry) ||
  74              	entry.type != XmlEntry::XML_DECLARATION ||
  75              	strcmp(entry.text, "xml") != 0)
  76                  {
  77              	throw XmlValidationError(parser.getLine(),
  78              	    "Expected <?xml ... ?> style declaration");
  79 kumpf   1.49     }
  80              
  81                  if (!entry.getAttributeValue("version", xmlVersion))
  82              	throw XmlValidationError(
  83              	    parser.getLine(), "missing xml.version attribute");
  84              
  85                  if (!entry.getAttributeValue("encoding", xmlEncoding))
  86                  {
  87                      // ATTN-RK-P3-20020403:  Is there a default encoding?
  88 mike    1.23     }
  89              }
  90              
  91              //------------------------------------------------------------------------------
  92              //
  93 mike    1.25 //  testXmlDeclaration ()
  94              //
  95              //------------------------------------------------------------------------------
  96              
  97              Boolean XmlReader::testXmlDeclaration (
  98                  XmlParser& parser,
  99                  XmlEntry& entry)
 100              {
 101                  if (!parser.next (entry) ||
 102                      entry.type != XmlEntry::XML_DECLARATION ||
 103                      strcmp (entry.text, "xml") != 0)
 104                  {
 105                      parser.putBack (entry);
 106                      return false;
 107                  }
 108              
 109                  return true;
 110              }
 111              
 112              //------------------------------------------------------------------------------
 113              //
 114 mike    1.23 // expectStartTag()
 115              //
 116              //------------------------------------------------------------------------------
 117              
 118              void XmlReader::expectStartTag(
 119                  XmlParser& parser, 
 120                  XmlEntry& entry,
 121                  const char* tagName)
 122              {
 123                  if (!parser.next(entry) ||
 124              	entry.type != XmlEntry::START_TAG ||
 125              	strcmp(entry.text, tagName) != 0)
 126                  {
 127              	char message[MESSAGE_SIZE];
 128              	sprintf(message, "Expected open of %s element", tagName);
 129              	throw XmlValidationError(parser.getLine(), message);
 130                  }
 131              }
 132              
 133              //------------------------------------------------------------------------------
 134              //
 135 mike    1.23 // expectEndTag()
 136              //
 137              //------------------------------------------------------------------------------
 138              
 139              void XmlReader::expectEndTag(XmlParser& parser, const char* tagName)
 140              {
 141                  XmlEntry entry;
 142              
 143                  if (!parser.next(entry) ||
 144              	entry.type != XmlEntry::END_TAG ||
 145              	strcmp(entry.text, tagName) != 0)
 146                  {
 147              	char message[MESSAGE_SIZE];
 148              	sprintf(message, "Expected close of %s element, got %s instead",
 149                            tagName,entry.text);
 150              	throw XmlValidationError(parser.getLine(), message);
 151                  }
 152              }
 153              
 154              //------------------------------------------------------------------------------
 155              //
 156 mike    1.23 // expectStartTagOrEmptyTag()
 157              //
 158              //------------------------------------------------------------------------------
 159              
 160              void XmlReader::expectStartTagOrEmptyTag(
 161                  XmlParser& parser, 
 162                  XmlEntry& entry,
 163                  const char* tagName)
 164              {
 165                  if (!parser.next(entry) ||
 166              	(entry.type != XmlEntry::START_TAG &&
 167              	entry.type != XmlEntry::EMPTY_TAG) ||
 168              	strcmp(entry.text, tagName) != 0)
 169                  {
 170              	char message[MESSAGE_SIZE];
 171              	sprintf(message, 
 172              	    "Expected either open or open/close %s element", tagName);
 173              	throw XmlValidationError(parser.getLine(), message);
 174                  }
 175              }
 176              
 177 mike    1.23 //------------------------------------------------------------------------------
 178              //
 179              // expectContentOrCData()
 180              //
 181              //------------------------------------------------------------------------------
 182              
 183              Boolean XmlReader::expectContentOrCData(
 184                  XmlParser& parser, 
 185                  XmlEntry& entry)
 186              {
 187                  if (!parser.next(entry) ||
 188              	(entry.type != XmlEntry::CONTENT &&
 189              	entry.type != XmlEntry::CDATA))
 190                  {
 191              	throw XmlValidationError(parser.getLine(),
 192              	    "Expected content of CDATA");
 193                  }
 194              
 195                  return true;
 196              }
 197              
 198 mike    1.23 //------------------------------------------------------------------------------
 199              //
 200              // testStartTag()
 201              //
 202              //------------------------------------------------------------------------------
 203              
 204              Boolean XmlReader::testStartTag(
 205                  XmlParser& parser, 
 206                  XmlEntry& entry,
 207                  const char* tagName)
 208              {
 209                  if (!parser.next(entry) ||
 210              	entry.type != XmlEntry::START_TAG ||
 211              	strcmp(entry.text, tagName) != 0)
 212                  {
 213              	parser.putBack(entry);
 214              	return false;
 215                  }
 216              
 217                  return true;
 218              }
 219 mike    1.23 
 220              //------------------------------------------------------------------------------
 221              //
 222 kumpf   1.48 // testEndTag()
 223 mike    1.23 //
 224              //------------------------------------------------------------------------------
 225              
 226              Boolean XmlReader::testEndTag(XmlParser& parser, const char* tagName)
 227              {
 228                  XmlEntry entry;
 229              
 230                  if (!parser.next(entry) ||
 231              	entry.type != XmlEntry::END_TAG ||
 232              	strcmp(entry.text, tagName) != 0)
 233                  {
 234              	parser.putBack(entry);
 235              	return false;
 236                  }
 237              
 238                  return true;
 239              }
 240              
 241              //------------------------------------------------------------------------------
 242              //
 243              // testStartTagOrEmptyTag()
 244 mike    1.23 //
 245              //------------------------------------------------------------------------------
 246              
 247              Boolean XmlReader::testStartTagOrEmptyTag(
 248                  XmlParser& parser, 
 249                  XmlEntry& entry,
 250                  const char* tagName)
 251              {
 252                  if (!parser.next(entry) ||
 253              	(entry.type != XmlEntry::START_TAG &&
 254              	entry.type != XmlEntry::EMPTY_TAG) ||
 255              	strcmp(entry.text, tagName) != 0)
 256                  {
 257              	parser.putBack(entry);
 258              	return false;
 259                  }
 260              
 261                  return true;
 262              }
 263              
 264              //------------------------------------------------------------------------------
 265 mike    1.23 //
 266              // testContentOrCData()
 267              //
 268              //------------------------------------------------------------------------------
 269              
 270              Boolean XmlReader::testContentOrCData(
 271                  XmlParser& parser, 
 272                  XmlEntry& entry)
 273              {
 274                  if (!parser.next(entry) ||
 275              	(entry.type != XmlEntry::CONTENT &&
 276              	entry.type != XmlEntry::CDATA))
 277                  {
 278              	parser.putBack(entry);
 279              	return false;
 280                  }
 281              
 282                  return true;
 283              }
 284              
 285              //------------------------------------------------------------------------------
 286 mike    1.23 //
 287 kumpf   1.34 // getCimStartTag()
 288 mike    1.23 //
 289              //     <!ELEMENT CIM (MESSAGE|DECLARATION)>
 290              //     <!ATTRLIST CIM 
 291              //         CIMVERSION CDATA #REQUIRED
 292              //         DTDVERSION CDATA #REQUIRED>
 293              //
 294              //------------------------------------------------------------------------------
 295              
 296 kumpf   1.34 void XmlReader::getCimStartTag(
 297                  XmlParser& parser, 
 298                  const char*& cimVersion,
 299                  const char*& dtdVersion)
 300 mike    1.23 {
 301                  XmlEntry entry;
 302                  XmlReader::expectStartTag(parser, entry, "CIM");
 303              
 304                  if (!entry.getAttributeValue("CIMVERSION", cimVersion))
 305              	throw XmlValidationError(
 306              	    parser.getLine(), "missing CIM.CIMVERSION attribute");
 307              
 308                  if (!entry.getAttributeValue("DTDVERSION", dtdVersion))
 309              	throw XmlValidationError(
 310              	    parser.getLine(), "missing CIM.DTDVERSION attribute");
 311              }
 312              
 313              //------------------------------------------------------------------------------
 314              //
 315              // getCimNameAttribute()
 316              //
 317              //     <!ENTITY % CIMName "NAME CDATA #REQUIRED">
 318              //
 319              //------------------------------------------------------------------------------
 320              
 321 kumpf   1.74 CIMName XmlReader::getCimNameAttribute(
 322 mike    1.23     Uint32 lineNumber, 
 323                  const XmlEntry& entry,
 324                  const char* elementName,
 325                  Boolean acceptNull)
 326              {
 327                  String name;
 328              
 329                  if (!entry.getAttributeValue("NAME", name))
 330                  {
 331              	char buffer[MESSAGE_SIZE];
 332              	sprintf(buffer, "missing %s.NAME attribute", elementName);
 333              	throw XmlValidationError(lineNumber, buffer);
 334                  }
 335              
 336                  if (acceptNull && name.size() == 0)
 337 kumpf   1.74 	return CIMName ();
 338 karl    1.78     
 339 mike    1.23     if (!CIMName::legal(name))
 340                  {
 341 karl    1.78 #ifdef PEGASUS_SNIA_INTEROP_TEST
 342                  // In testing, replace illegal CIMName with this value to avoid the
 343                  // exception and let xml parsing continue.  THIS IS TEMP.    
 344                  name = "BADNAMESUBSTITUTEDBYPEGASUSCLIENT";
 345              #else
 346 mike    1.23 	char buffer[MESSAGE_SIZE];
 347              	sprintf(buffer, "Illegal value for %s.NAME attribute", elementName);
 348              	throw XmlSemanticError(lineNumber, buffer);
 349 karl    1.78 #endif
 350 mike    1.23     }
 351 kumpf   1.74     return CIMName (name);
 352 mike    1.23 }
 353              
 354              //------------------------------------------------------------------------------
 355              //
 356              // getClassNameAttribute()
 357              //
 358              //     <!ENTITY % CIMName "CLASSNAME CDATA #REQUIRED">
 359              //
 360              //------------------------------------------------------------------------------
 361              
 362              String XmlReader::getClassNameAttribute(
 363                  Uint32 lineNumber, 
 364                  const XmlEntry& entry,
 365                  const char* elementName)
 366              {
 367                  String name;
 368              
 369                  if (!entry.getAttributeValue("CLASSNAME", name))
 370                  {
 371              	char buffer[MESSAGE_SIZE];
 372              	sprintf(buffer, "missing %s.CLASSNAME attribute", elementName);
 373 mike    1.23 	throw XmlValidationError(lineNumber, buffer);
 374                  }
 375              
 376                  if (!CIMName::legal(name))
 377                  {
 378              	char buffer[MESSAGE_SIZE];
 379              	sprintf(buffer, 
 380              	    "Illegal value for %s.CLASSNAME attribute", elementName);
 381              	throw XmlSemanticError(lineNumber, buffer);
 382                  }
 383              
 384                  return name;
 385              }
 386              
 387              //------------------------------------------------------------------------------
 388              //
 389              // getClassOriginAttribute()
 390              //
 391              //     <!ENTITY % ClassOrigin "CLASSORIGIN CDATA #IMPLIED">
 392              //
 393              //------------------------------------------------------------------------------
 394 mike    1.23 
 395 kumpf   1.62 CIMName XmlReader::getClassOriginAttribute(
 396 mike    1.23     Uint32 lineNumber, 
 397                  const XmlEntry& entry,
 398                  const char* tagName)
 399              {
 400                  String name;
 401              
 402                  if (!entry.getAttributeValue("CLASSORIGIN", name))
 403 kumpf   1.62 	return CIMName();
 404 mike    1.23 
 405 karl    1.75     // KS 200209 This may be temp but we are adding test for form
 406                  // CLASSNAME = "" for Wbemservices interoperability.  Returns same
 407                  // as if attribute did not exist.
 408                  if (name.size() == 0)
 409                      return CIMName();
 410                  
 411 mike    1.23     if (!CIMName::legal(name))
 412                  {
 413              	char buffer[MESSAGE_SIZE];
 414              	sprintf(buffer, 
 415              	    "Illegal value for %s.CLASSORIGIN attribute", tagName);
 416              	throw XmlSemanticError(lineNumber, buffer);
 417                  }
 418              
 419                  return name;
 420              }
 421              
 422              //------------------------------------------------------------------------------
 423              //
 424              // getReferenceClassAttribute()
 425              //
 426              //     <!ENTITY % ReferenceClass "REFERENCECLASS CDATA #IMPLIED">
 427              //
 428              //------------------------------------------------------------------------------
 429              
 430 kumpf   1.62 CIMName XmlReader::getReferenceClassAttribute(
 431 mike    1.23     Uint32 lineNumber, 
 432                  const XmlEntry& entry,
 433                  const char* elementName)
 434              {
 435                  String name;
 436              
 437                  if (!entry.getAttributeValue("REFERENCECLASS", name))
 438 kumpf   1.62 	return CIMName();
 439 mike    1.23 
 440                  if (!CIMName::legal(name))
 441                  {
 442 karl    1.79 #ifdef PEGASUS_SNIA_INTEROP_TEST
 443                  name = "PEGASUS_SUBSTITUED_THIS_FOR_BAD_NAME";
 444                  return name;
 445              #endif 
 446 mike    1.23 	char buffer[MESSAGE_SIZE];
 447              	sprintf(buffer, 
 448              	    "Illegal value for %s.REFERENCECLASS attribute", elementName);
 449              	throw XmlSemanticError(lineNumber, buffer);
 450                  }
 451              
 452                  return name;
 453              }
 454              
 455              //------------------------------------------------------------------------------
 456              //
 457              // getSuperClassAttribute()
 458              //
 459              //     <!ENTITY % SuperClass "SUPERCLASS CDATA #IMPLIED">
 460              //
 461              //------------------------------------------------------------------------------
 462              
 463 kumpf   1.62 CIMName XmlReader::getSuperClassAttribute(
 464 mike    1.23     Uint32 lineNumber, 
 465                  const XmlEntry& entry,
 466                  const char* tagName)
 467              {
 468                  String superClass;
 469              
 470                  if (!entry.getAttributeValue("SUPERCLASS", superClass))
 471 kumpf   1.62 	return CIMName();
 472 mike    1.23 
 473                  if (!CIMName::legal(superClass))
 474                  {
 475              	char buffer[MESSAGE_SIZE];
 476              	sprintf(
 477              	    buffer, "Illegal value for %s.SUPERCLASS attribute", tagName);
 478              	throw XmlSemanticError(lineNumber, buffer);
 479                  }
 480              
 481                  return superClass;
 482              }
 483              
 484              //------------------------------------------------------------------------------
 485              //
 486              // getCimTypeAttribute()
 487              //
 488 kumpf   1.26 // This method can be used to get a TYPE attribute or a PARAMTYPE attribute.
 489              // The only significant difference is that PARAMTYPE may specify a value of
 490              // "reference" type.  This method recognizes these attributes by name, and
 491              // does not allow a "TYPE" attribute to be of "reference" type.
 492              //
 493 mike    1.23 //     <!ENTITY % CIMType "TYPE (boolean|string|char16|uint8|sint8|uint16
 494              //         |sint16|uint32|sint32|uint64|sint64|datetime|real32|real64)">
 495              //
 496 kumpf   1.26 //     <!ENTITY % ParamType "PARAMTYPE (boolean|string|char16|uint8|sint8
 497              //         |uint16|sint16|uint32|sint32|uint64|sint64|datetime|real32|real64
 498              //         |reference)">
 499              //
 500 mike    1.23 //------------------------------------------------------------------------------
 501              
 502 kumpf   1.67 Boolean XmlReader::getCimTypeAttribute(
 503 mike    1.23     Uint32 lineNumber, 
 504                  const XmlEntry& entry, 
 505 kumpf   1.67     CIMType& cimType,  // Output parameter
 506 kumpf   1.26     const char* tagName,
 507                  const char* attributeName,
 508                  Boolean required)
 509 mike    1.23 {
 510                  const char* typeName;
 511              
 512 kumpf   1.26     if (!entry.getAttributeValue(attributeName, typeName))
 513 mike    1.23     {
 514 kumpf   1.26         if (required)
 515              	{
 516              	    char message[MESSAGE_SIZE];
 517              	    sprintf(message, "missing %s.%s attribute", tagName, attributeName);
 518              	    throw XmlValidationError(lineNumber, message);
 519              	}
 520              	else
 521              	{
 522 kumpf   1.67 	    return false;
 523 kumpf   1.26 	}
 524 mike    1.23     }
 525              
 526 kumpf   1.67     CIMType type = CIMTYPE_BOOLEAN;
 527                  Boolean unrecognizedType = false;
 528 mike    1.23 
 529                  if (strcmp(typeName, "boolean") == 0)
 530 kumpf   1.61 	type = CIMTYPE_BOOLEAN;
 531 mike    1.23     else if (strcmp(typeName, "string") == 0)
 532 kumpf   1.61 	type = CIMTYPE_STRING;
 533 mike    1.23     else if (strcmp(typeName, "char16") == 0)
 534 kumpf   1.61 	type = CIMTYPE_CHAR16;
 535 mike    1.23     else if (strcmp(typeName, "uint8") == 0)
 536 kumpf   1.61 	type = CIMTYPE_UINT8;
 537 mike    1.23     else if (strcmp(typeName, "sint8") == 0)
 538 kumpf   1.61 	type = CIMTYPE_SINT8;
 539 mike    1.23     else if (strcmp(typeName, "uint16") == 0)
 540 kumpf   1.61 	type = CIMTYPE_UINT16;
 541 mike    1.23     else if (strcmp(typeName, "sint16") == 0)
 542 kumpf   1.61 	type = CIMTYPE_SINT16;
 543 mike    1.23     else if (strcmp(typeName, "uint32") == 0)
 544 kumpf   1.61 	type = CIMTYPE_UINT32;
 545 mike    1.23     else if (strcmp(typeName, "sint32") == 0)
 546 kumpf   1.61 	type = CIMTYPE_SINT32;
 547 mike    1.23     else if (strcmp(typeName, "uint64") == 0)
 548 kumpf   1.61 	type = CIMTYPE_UINT64;
 549 mike    1.23     else if (strcmp(typeName, "sint64") == 0)
 550 kumpf   1.61 	type = CIMTYPE_SINT64;
 551 mike    1.23     else if (strcmp(typeName, "datetime") == 0)
 552 kumpf   1.61 	type = CIMTYPE_DATETIME;
 553 mike    1.23     else if (strcmp(typeName, "real32") == 0)
 554 kumpf   1.61 	type = CIMTYPE_REAL32;
 555 mike    1.23     else if (strcmp(typeName, "real64") == 0)
 556 kumpf   1.61 	type = CIMTYPE_REAL64;
 557 kumpf   1.26     else if (strcmp(typeName, "reference") == 0)
 558 kumpf   1.61 	type = CIMTYPE_REFERENCE;
 559 kumpf   1.67     else unrecognizedType = true;
 560 mike    1.23 
 561 kumpf   1.67     if (unrecognizedType ||
 562 kumpf   1.61         ((type == CIMTYPE_REFERENCE) &&
 563 kumpf   1.26          (strcmp(attributeName, "PARAMTYPE") != 0)))
 564 mike    1.23     {
 565              	char message[MESSAGE_SIZE];
 566 kumpf   1.26 	sprintf(message, "Illegal value for %s.%s attribute", tagName,
 567              	        attributeName);
 568 mike    1.23 	throw XmlSemanticError(lineNumber, message);
 569                  }
 570              
 571 kumpf   1.67     cimType = type;
 572                  return true;
 573 mike    1.23 }
 574              
 575              //------------------------------------------------------------------------------
 576              //
 577              // getCimBooleanAttribute()
 578              //
 579              //------------------------------------------------------------------------------
 580              
 581              Boolean XmlReader::getCimBooleanAttribute(
 582                  Uint32 lineNumber,
 583                  const XmlEntry& entry,
 584                  const char* tagName,
 585                  const char* attributeName,
 586                  Boolean defaultValue,
 587                  Boolean required)
 588              {
 589                  const char* tmp;
 590              
 591                  if (!entry.getAttributeValue(attributeName, tmp))
 592                  {
 593              	if (!required)
 594 mike    1.23 	    return defaultValue;
 595              
 596              	char buffer[62];
 597              	sprintf(buffer, "missing required %s.%s attribute", 
 598              	    attributeName, tagName);
 599              
 600              	throw XmlValidationError(lineNumber, buffer);
 601                  }
 602              
 603                  if (strcmp(tmp, "true") == 0)
 604              	return true;
 605                  else if (strcmp(tmp, "false") == 0)
 606              	return false;
 607              
 608                  char buffer[62];
 609 kumpf   1.66     sprintf(buffer, "Invalid %s.%s attribute value", attributeName, tagName);
 610 mike    1.23     throw XmlSemanticError(lineNumber, buffer);
 611                  return false;
 612              }
 613              
 614              //------------------------------------------------------------------------------
 615              //
 616              // SringToReal()
 617              //
 618              //	[ "+" | "-" ] *decimalDigit "." 1*decimalDigit 
 619              //	    [ ( "e" | "E" ) [ "+" | "-" ] 1*decimalDigit ]
 620              //
 621              //------------------------------------------------------------------------------
 622              
 623              Boolean XmlReader::stringToReal(const char* stringValue, Real64& x)
 624              {
 625 kumpf   1.43     //
 626                  // Check the string against the DMTF-defined grammar
 627                  //
 628 mike    1.23     const char* p = stringValue;
 629              
 630                  if (!*p)
 631              	return false;
 632              
 633                  // Skip optional sign:
 634              
 635                  if (*p == '+' || *p  == '-')
 636              	p++;
 637              
 638                  // Skip optional first set of digits:
 639              
 640                  while (isdigit(*p))
 641              	p++;
 642              
 643                  // Test required dot:
 644              
 645                  if (*p++ != '.')
 646              	return false;
 647              
 648                  // One or more digits required:
 649 mike    1.23 
 650                  if (!isdigit(*p++))
 651              	return false;
 652              
 653                  while (isdigit(*p))
 654              	p++;
 655              
 656                  // If there is an exponent now:
 657              
 658                  if (*p)
 659                  {
 660              	// Test exponent:
 661              
 662              	if (*p != 'e' && *p != 'E')
 663              	    return false;
 664              
 665              	p++;
 666              
 667              	// Skip optional sign:
 668              
 669              	if (*p == '+' || *p  == '-')
 670 mike    1.23 	    p++;
 671              
 672              	// One or more digits required:
 673              
 674              	if (!isdigit(*p++))
 675              	    return false;
 676              
 677              	while (isdigit(*p))
 678              	    p++;
 679                  }
 680              
 681                  if (*p)
 682              	return false;
 683              
 684 kumpf   1.43     //
 685                  // Do the conversion
 686                  //
 687 mike    1.23     char* end;
 688 kumpf   1.43     errno = 0;
 689 mike    1.23     x = strtod(stringValue, &end);
 690 kumpf   1.43     if (*end || (errno == ERANGE))
 691                  {
 692                      return false;
 693                  }
 694              
 695 mike    1.23     return true;
 696              }
 697              
 698 kumpf   1.41 inline Uint8 _hexCharToNumeric(const char c)
 699              {
 700                  Uint8 n;
 701              
 702                  if (isdigit(c))
 703                      n = (c - '0');
 704                  else if (isupper(c))
 705                      n = (c - 'A' + 10);
 706                  else // if (islower(c))
 707                      n = (c - 'a' + 10);
 708              
 709                  return n;
 710 kumpf   1.82 }
 711              
 712              // See http://www.ietf.org/rfc/rfc2396.txt section 2
 713              String XmlReader::decodeURICharacters(String uriString)
 714              {
 715                  String decodedString;
 716                  Uint32 i;
 717              
 718                  for (i=0; i<uriString.size(); i++)
 719                  {
 720                      if (uriString[i] == '%')
 721                      {
 722                          if (i+2 >= uriString.size())
 723                          {
 724                              throw ParseError("Invalid URI encoding");
 725                          }
 726              
 727                          Uint8 digit1 = _hexCharToNumeric(char(uriString[++i]));
 728                          Uint8 digit2 = _hexCharToNumeric(char(uriString[++i]));
 729                          if ( (digit1 > 15) || (digit2 > 15) )
 730                          {
 731 kumpf   1.82                 throw ParseError("Invalid URI encoding");
 732                          }
 733              
 734                          // ATTN: Handle non-UTF-8 character sets
 735                          Uint16 decodedChar = Uint16(digit1<<4) + Uint16(digit2);
 736                          decodedString.append(Char16(decodedChar));
 737                      }
 738                      else
 739                      {
 740                          decodedString.append(uriString[i]);
 741                      }
 742                  }
 743              
 744                  return decodedString;
 745 kumpf   1.41 }
 746              
 747 mike    1.23 //------------------------------------------------------------------------------
 748              //
 749              // stringToSignedInteger
 750              //
 751              //	[ "+" | "-" ] ( positiveDecimalDigit *decimalDigit | "0" )
 752 kumpf   1.41 //    or
 753              //      [ "+" | "-" ] ( "0x" | "0X" ) 1*hexDigit
 754 mike    1.23 //
 755              //------------------------------------------------------------------------------
 756              
 757              Boolean XmlReader::stringToSignedInteger(
 758                  const char* stringValue, 
 759                  Sint64& x)
 760              {
 761                  x = 0;
 762                  const char* p = stringValue;
 763              
 764 kumpf   1.41     if (!p || !*p)
 765 mike    1.23 	return false;
 766              
 767                  // Skip optional sign:
 768              
 769                  Boolean negative = *p == '-';
 770              
 771                  if (negative || *p == '+')
 772              	p++;
 773              
 774                  if (*p == '0')
 775 kumpf   1.41     {
 776                      if ( (p[1] == 'x') || (p[1] == 'X') )
 777                      {
 778                          // Convert a hexadecimal string
 779 mike    1.23 
 780 kumpf   1.41             // Skip over the "0x"
 781                          p+=2;
 782 mike    1.23 
 783 kumpf   1.41             // At least one hexadecimal digit is required
 784                          if (!isxdigit(*p))
 785                              return false;
 786              
 787                          // Build the Sint64 as a negative number, regardless of the
 788                          // eventual sign (negative numbers can be bigger than positive ones)
 789              
 790                          // Add on each digit, checking for overflow errors
 791                          while (isxdigit(*p))
 792                          {
 793                              // Make sure we won't overflow when we multiply by 16
 794 kumpf   1.68                 if (x < PEGASUS_SINT64_MIN/16)
 795 kumpf   1.41                 {
 796                                  return false;
 797                              }
 798                              x = x << 4;
 799              
 800                              // Make sure we don't overflow when we add the next digit
 801                              Sint64 newDigit = Sint64(_hexCharToNumeric(*p++));
 802 kumpf   1.68                 if (PEGASUS_SINT64_MIN - x > -newDigit)
 803 kumpf   1.41                 {
 804                                  return false;
 805                              }
 806                              x = x - newDigit;
 807                          }
 808              
 809                          // If we found a non-hexadecimal digit, report an error
 810                          if (*p)
 811                              return false;
 812              
 813                          // Return the integer to positive, if necessary, checking for an
 814                          // overflow error
 815                          if (!negative)
 816                          {
 817 kumpf   1.68                 if (x == PEGASUS_SINT64_MIN)
 818 kumpf   1.41                 {
 819                                  return false;
 820                              }
 821                              x = -x;
 822                          }
 823                          return true;
 824                      }
 825                      else
 826                      {
 827                          // A decimal string that starts with '0' must be exactly "0".
 828              	    return p[1] == '\0';
 829                      }
 830                  }
 831 mike    1.23 
 832 kumpf   1.41     // Expect a positive decimal digit:
 833 mike    1.23 
 834 kumpf   1.41     // At least one decimal digit is required
 835                  if (!isdigit(*p))
 836                      return false;
 837              
 838                  // Build the Sint64 as a negative number, regardless of the
 839                  // eventual sign (negative numbers can be bigger than positive ones)
 840 mike    1.23 
 841 kumpf   1.41     // Add on each digit, checking for overflow errors
 842 mike    1.23     while (isdigit(*p))
 843 kumpf   1.37     {
 844 kumpf   1.41         // Make sure we won't overflow when we multiply by 10
 845 kumpf   1.68         if (x < PEGASUS_SINT64_MIN/10)
 846 kumpf   1.37         {
 847                          return false;
 848                      }
 849                      x = 10 * x;
 850 kumpf   1.41 
 851                      // Make sure we won't overflow when we add the next digit
 852                      Sint64 newDigit = (*p++ - '0');
 853 kumpf   1.68         if (PEGASUS_SINT64_MIN - x > -newDigit)
 854 kumpf   1.37         {
 855                          return false;
 856                      }
 857 kumpf   1.41         x = x - newDigit;
 858 kumpf   1.37     }
 859 mike    1.23 
 860 kumpf   1.41     // If we found a non-decimal digit, report an error
 861                  if (*p)
 862              	return false;
 863              
 864                  // Return the integer to positive, if necessary, checking for an
 865                  // overflow error
 866 kumpf   1.37     if (!negative)
 867                  {
 868 kumpf   1.68         if (x == PEGASUS_SINT64_MIN)
 869 kumpf   1.37         {
 870                          return false;
 871                      }
 872 kumpf   1.41         x = -x;
 873 kumpf   1.37     }
 874 mike    1.23     return true;
 875              }
 876              
 877              //------------------------------------------------------------------------------
 878              //
 879              // stringToUnsignedInteger
 880              //
 881 kumpf   1.40 //	( positiveDecimalDigit *decimalDigit | "0" )
 882 kumpf   1.41 //    or
 883              //      ( "0x" | "0X" ) 1*hexDigit
 884 mike    1.23 //
 885              //------------------------------------------------------------------------------
 886              
 887              Boolean XmlReader::stringToUnsignedInteger(
 888                  const char* stringValue, 
 889                  Uint64& x)
 890              {
 891                  x = 0;
 892                  const char* p = stringValue;
 893              
 894 kumpf   1.41     if (!p || !*p)
 895 mike    1.23 	return false;
 896              
 897                  if (*p == '0')
 898 kumpf   1.41     {
 899                      if ( (p[1] == 'x') || (p[1] == 'X') )
 900                      {
 901                          // Convert a hexadecimal string
 902 mike    1.23 
 903 kumpf   1.41             // Skip over the "0x"
 904                          p+=2;
 905 mike    1.23 
 906 kumpf   1.41             // At least one hexadecimal digit is required
 907                          if (!*p)
 908                              return false;
 909              
 910                          // Add on each digit, checking for overflow errors
 911                          while (isxdigit(*p))
 912                          {
 913                              // Make sure we won't overflow when we multiply by 16
 914 kumpf   1.68                 if (x > PEGASUS_UINT64_MAX/16)
 915 kumpf   1.41                 {
 916                                  return false;
 917                              }
 918                              x = x << 4;
 919              
 920                              // We can't overflow when we add the next digit
 921                              Uint64 newDigit = Uint64(_hexCharToNumeric(*p++));
 922 kumpf   1.68                 if (PEGASUS_UINT64_MAX - x < newDigit)
 923 kumpf   1.41                 {
 924                                  return false;
 925                              }
 926                              x = x + newDigit;
 927                          }
 928              
 929                          // If we found a non-hexadecimal digit, report an error
 930                          if (*p)
 931                              return false;
 932 mike    1.23 
 933 kumpf   1.41             return true;
 934                      }
 935                      else
 936                      {
 937                          // A decimal string that starts with '0' must be exactly "0".
 938              	    return p[1] == '\0';
 939                      }
 940                  }
 941 mike    1.23 
 942 kumpf   1.41     // Expect a positive decimal digit:
 943 mike    1.23 
 944 kumpf   1.41     // Add on each digit, checking for overflow errors
 945 mike    1.23     while (isdigit(*p))
 946 kumpf   1.37     {
 947 kumpf   1.41         // Make sure we won't overflow when we multiply by 10
 948 kumpf   1.68         if (x > PEGASUS_UINT64_MAX/10)
 949 kumpf   1.37         {
 950                          return false;
 951                      }
 952                      x = 10 * x;
 953 kumpf   1.41 
 954                      // Make sure we won't overflow when we add the next digit
 955                      Uint64 newDigit = (*p++ - '0');
 956 kumpf   1.68         if (PEGASUS_UINT64_MAX - x < newDigit)
 957 kumpf   1.37         {
 958                          return false;
 959                      }
 960 kumpf   1.41         x = x + newDigit;
 961 kumpf   1.37     }
 962 kumpf   1.41 
 963                  // If we found a non-decimal digit, report an error
 964                  if (*p)
 965              	return false;
 966 mike    1.23 
 967                  return true;
 968              }
 969              
 970              //------------------------------------------------------------------------------
 971              //
 972              // stringToValue()
 973              //
 974 karl    1.35 // Return: CIMValue. If the string input is zero length creates a CIMValue
 975              //         with value defined by the type.  Else the value is inserted.
 976              //         
 977              //         Note that this does not set the CIMValue Null if the string is empty.
 978              //
 979 mike    1.23 //------------------------------------------------------------------------------
 980              
 981              CIMValue XmlReader::stringToValue(
 982                  Uint32 lineNumber, 
 983                  const char* valueString, 
 984                  CIMType type)
 985              {
 986                  // ATTN-B: accepting only UTF-8 for now! (affects string and char16):
 987              
 988 karl    1.35     // Create value per type
 989 mike    1.23     switch (type)
 990                  {
 991 kumpf   1.61 	case CIMTYPE_BOOLEAN:
 992 mike    1.23 	{
 993 kumpf   1.72 	    if (System::strcasecmp(valueString, "TRUE") == 0)
 994 mike    1.23 		return CIMValue(true);
 995 kumpf   1.72 	    else if (System::strcasecmp(valueString, "FALSE") == 0)
 996 mike    1.23 		return CIMValue(false);
 997              	    else
 998              		throw XmlSemanticError(
 999 kumpf   1.66 		    lineNumber, "Invalid boolean value");
1000 mike    1.23 	}
1001              
1002 kumpf   1.61 	case CIMTYPE_STRING:
1003 mike    1.23 	{
1004 kumpf   1.60 	    return CIMValue(String(valueString));
1005 mike    1.23 	}
1006              
1007 kumpf   1.61 	case CIMTYPE_CHAR16:
1008 mike    1.23 	{
1009              	    if (strlen(valueString) != 1)
1010 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid char16 value");
1011 mike    1.23 
1012              	    return CIMValue(Char16(valueString[0]));
1013              	}
1014              
1015 kumpf   1.61 	case CIMTYPE_UINT8:
1016              	case CIMTYPE_UINT16:
1017              	case CIMTYPE_UINT32:
1018              	case CIMTYPE_UINT64:
1019 mike    1.23 	{
1020              	    Uint64 x;
1021              
1022              	    if (!stringToUnsignedInteger(valueString, x))
1023              	    {
1024 karl    1.80             char message[128];
1025                          sprintf(message, "Illegal unsigned integer value - %s", valueString);
1026                  		throw XmlSemanticError(
1027                  		    lineNumber, message);
1028 mike    1.23 	    }
1029              
1030              	    switch (type)
1031              	    {
1032 kumpf   1.61 		case CIMTYPE_UINT8:
1033 kumpf   1.37                 {
1034                                  if (x >= (Uint64(1)<<8))
1035              		    {
1036              			throw XmlSemanticError(
1037              			    lineNumber, "Uint8 value out of range");
1038              		    }
1039              		    return CIMValue(Uint8(x));
1040                              }
1041 kumpf   1.61 		case CIMTYPE_UINT16:
1042 kumpf   1.37                 {
1043                                  if (x >= (Uint64(1)<<16))
1044              		    {
1045              			throw XmlSemanticError(
1046              			    lineNumber, "Uint16 value out of range");
1047              		    }
1048              		    return CIMValue(Uint16(x));
1049                              }
1050 kumpf   1.61 		case CIMTYPE_UINT32:
1051 kumpf   1.37                 {
1052                                  if (x >= (Uint64(1)<<32))
1053              		    {
1054              			throw XmlSemanticError(
1055              			    lineNumber, "Uint32 value out of range");
1056              		    }
1057              		    return CIMValue(Uint32(x));
1058                              }
1059 kumpf   1.61 		case CIMTYPE_UINT64: return CIMValue(Uint64(x));
1060 mike    1.23 		default: break;
1061              	    }
1062              	}
1063              
1064 kumpf   1.61 	case CIMTYPE_SINT8:
1065              	case CIMTYPE_SINT16:
1066              	case CIMTYPE_SINT32:
1067              	case CIMTYPE_SINT64:
1068 mike    1.23 	{
1069              	    Sint64 x;
1070              
1071              	    if (!stringToSignedInteger(valueString, x))
1072              	    {
1073              		throw XmlSemanticError(
1074 kumpf   1.66 		    lineNumber, "Invalid signed integer value");
1075 mike    1.23 	    }
1076              
1077              	    switch (type)
1078              	    {
1079 kumpf   1.61 		case CIMTYPE_SINT8:
1080 kumpf   1.37                 {
1081                                  if(  (x >= (Sint64(1)<<7)) || (x < (-(Sint64(1)<<7))) )
1082              		    {
1083              			throw XmlSemanticError(
1084              			    lineNumber, "Sint8 value out of range");
1085              		    }
1086              		    return CIMValue(Sint8(x));
1087                              }
1088 kumpf   1.61 		case CIMTYPE_SINT16:
1089 kumpf   1.37                 {
1090                                  if(  (x >= (Sint64(1)<<15)) || (x < (-(Sint64(1)<<15))) )
1091              		    {
1092              			throw XmlSemanticError(
1093              			    lineNumber, "Sint16 value out of range");
1094              		    }
1095              		    return CIMValue(Sint16(x));
1096                              }
1097 kumpf   1.61 		case CIMTYPE_SINT32:
1098 kumpf   1.37                 {
1099                                  if(  (x >= (Sint64(1)<<31)) || (x < (-(Sint64(1)<<31))) )
1100              		    {
1101              			throw XmlSemanticError(
1102              			    lineNumber, "Sint32 value out of range");
1103              		    }
1104              		    return CIMValue(Sint32(x));
1105                              }
1106 kumpf   1.61 		case CIMTYPE_SINT64: return CIMValue(Sint64(x));
1107 mike    1.23 		default: break;
1108              	    }
1109              	}
1110              
1111 kumpf   1.61 	case CIMTYPE_DATETIME:
1112 mike    1.23 	{
1113              	    CIMDateTime tmp;
1114              
1115              	    try
1116              	    {
1117 karl    1.76             // KS 20021002 - Exception if no datatime value. Test for
1118                          // zero length and leave the NULL value in the variable
1119                          // Bugzilla 137  Adds the following if line.
1120 karl    1.78             // Expect this to become permanent but test only for now
1121 karl    1.76 #ifdef PEGASUS_SNIA_INTEROP_TEST
1122                          if (strlen(valueString) != 0)
1123              #endif
1124 karl    1.77                 tmp.set(valueString);
1125 mike    1.23 	    }
1126 kumpf   1.66 	    catch (InvalidDateTimeFormatException&)
1127 mike    1.23 	    {
1128 karl    1.77             throw XmlSemanticError(lineNumber, "Invalid datetime value");
1129 mike    1.23 	    }
1130              
1131              	    return CIMValue(tmp);
1132              	}
1133              
1134 kumpf   1.61 	case CIMTYPE_REAL32:
1135 mike    1.23 	{
1136              	    Real64 x;
1137              
1138              	    if (!stringToReal(valueString, x))
1139 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid real number value");
1140 mike    1.23 
1141              	    return CIMValue(Real32(x));
1142              	}
1143              
1144 kumpf   1.61 	case CIMTYPE_REAL64:
1145 mike    1.23 	{
1146              	    Real64 x;
1147              
1148              	    if (!stringToReal(valueString, x))
1149 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid real number value");
1150 mike    1.23 
1151              	    return CIMValue(x);
1152              	}
1153              
1154              	default:
1155              	    break;
1156                  }
1157              
1158                  throw XmlSemanticError(lineNumber, "malformed XML");
1159                  return false;
1160              }
1161              
1162              //------------------------------------------------------------------------------
1163              //
1164              // getValueElement()
1165              //
1166              //     <!ELEMENT VALUE (#PCDATA)>
1167              //
1168 karl    1.35 // Return: false if no value element.
1169              //
1170 mike    1.23 //------------------------------------------------------------------------------
1171              
1172              Boolean XmlReader::getValueElement(
1173                  XmlParser& parser, 
1174                  CIMType type, 
1175                  CIMValue& value)
1176              {
1177 karl    1.35     // Get VALUE start tag: Return false if no VALUE start Tag
1178 mike    1.23 
1179                  XmlEntry entry;
1180                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE"))
1181              	return false;
1182              
1183                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1184              
1185                  const char* valueString = "";
1186              
1187                  if (!empty)
1188                  {
1189              	if (testContentOrCData(parser, entry))
1190              	    valueString = entry.text;
1191              
1192              	expectEndTag(parser, "VALUE");
1193                  }
1194 karl    1.80 #ifdef PEGASUS_SNIA_INTEROP_TEST
1195                  // KS 20021004 - tries to put value in even if empty.
1196                  // Think this is general problem with empty value
1197                  // Need to check meaning of (#PCDATA) - Does it allow empty.
1198                  // Bugzilla tbd
1199                  if (!empty)
1200              #endif
1201                      value = stringToValue(parser.getLine(), valueString,type);
1202 karl    1.33     
1203 mike    1.23     return true;
1204              }
1205              
1206              //------------------------------------------------------------------------------
1207              //
1208              // getStringValueElement()
1209              //
1210              //     <!ELEMENT VALUE (#PCDATA)>
1211              //
1212              //------------------------------------------------------------------------------
1213              
1214              Boolean XmlReader::getStringValueElement(
1215                  XmlParser& parser, 
1216                  String& str,
1217                  Boolean required)
1218              {
1219                  XmlEntry entry;
1220              
1221                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE"))
1222                  {
1223              	if (required)
1224 mike    1.23 	    throw XmlValidationError(parser.getLine(),"Expected VALUE element");
1225              	return false;
1226                  }
1227              
1228                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1229              
1230                  const char* valueString = "";
1231              
1232                  if (!empty)
1233                  {
1234              	if (testContentOrCData(parser, entry))
1235              	    valueString = entry.text;
1236              
1237              	expectEndTag(parser, "VALUE");
1238                  }
1239              
1240                  str = valueString;
1241                  return true;
1242              }
1243              
1244              //----------------------------------------------------------------------------
1245 mike    1.23 //
1246              // getPropertyValue
1247 kumpf   1.30 //     Use: Decode property value from SetProperty request and
1248              //     GetProperty response.
1249 mike    1.23 //
1250 kumpf   1.30 //     PropertyValue is one of:
1251 mike    1.23 //
1252              //
1253 karl    1.33 //	<!ELEMENT VALUE.ARRAY (VALUE*)>
1254              //
1255              //	<!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1256 kumpf   1.30 //         <!ELEMENT VALUE.ARRAY (VALUE*)>
1257              //
1258              //         <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1259 mike    1.23 //                           INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
1260              //
1261 kumpf   1.30 //         <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
1262              //
1263 mike    1.23 //----------------------------------------------------------------------------
1264              Boolean XmlReader::getPropertyValue(
1265                  XmlParser& parser, 
1266                  CIMValue& cimValue)
1267              {
1268 kumpf   1.30     // Can not test for value type, so assume String
1269 kumpf   1.61     const CIMType type = CIMTYPE_STRING;
1270 mike    1.23 
1271 kumpf   1.30     // Test for VALUE element
1272 mike    1.23     if (XmlReader::getValueElement(parser, type, cimValue))
1273                  {
1274              	return true;
1275                  }
1276              
1277 kumpf   1.30     // Test for VALUE.ARRAY element
1278                  if (XmlReader::getValueArrayElement(parser, type, cimValue))
1279                  {
1280 mike    1.23        return true;
1281 kumpf   1.30     }
1282 mike    1.23 
1283 kumpf   1.30     // Test for VALUE.REFERENCE element
1284 kumpf   1.54     CIMObjectPath reference;
1285 kumpf   1.30     if (XmlReader::getValueReferenceElement(parser, reference))
1286 mike    1.25     {
1287                      cimValue.set(reference);
1288                      return true;
1289                  }
1290 mike    1.23 
1291 kumpf   1.30     // Test for VALUE.REFARRAY element
1292                  if (XmlReader::getValueReferenceArrayElement(parser, cimValue))
1293                  {
1294                     return true;
1295                  }
1296              
1297                  return false;
1298 mike    1.23 }
1299              
1300              //------------------------------------------------------------------------------
1301              //
1302              // stringArrayToValue()
1303              //
1304              //------------------------------------------------------------------------------
1305              
1306              template<class T>
1307              CIMValue StringArrayToValueAux(
1308                  Uint32 lineNumber, 
1309                  const Array<const char*>& stringArray,
1310                  CIMType type,
1311                  T*)
1312              {
1313                  Array<T> array;
1314              
1315                  for (Uint32 i = 0, n = stringArray.size(); i < n; i++)
1316                  {
1317              	CIMValue value = XmlReader::stringToValue(
1318              	    lineNumber, stringArray[i], type);
1319 mike    1.23 
1320              	T x;
1321              	value.get(x);
1322              	array.append(x);
1323                  }
1324              
1325                  return CIMValue(array);
1326              }
1327              
1328              CIMValue XmlReader::stringArrayToValue(
1329                  Uint32 lineNumber, 
1330                  const Array<const char*>& array, 
1331                  CIMType type)
1332              {
1333                  switch (type)
1334                  {
1335 kumpf   1.61 	case CIMTYPE_BOOLEAN: 
1336 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Boolean*)0);
1337              
1338 kumpf   1.61 	case CIMTYPE_STRING:
1339 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (String*)0);
1340              
1341 kumpf   1.61 	case CIMTYPE_CHAR16:
1342 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Char16*)0);
1343              
1344 kumpf   1.61 	case CIMTYPE_UINT8:
1345 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint8*)0);
1346              
1347 kumpf   1.61 	case CIMTYPE_UINT16:
1348 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint16*)0);
1349              
1350 kumpf   1.61 	case CIMTYPE_UINT32:
1351 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint32*)0);
1352              
1353 kumpf   1.61 	case CIMTYPE_UINT64:
1354 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint64*)0);
1355              
1356 kumpf   1.61 	case CIMTYPE_SINT8:
1357 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint8*)0);
1358              
1359 kumpf   1.61 	case CIMTYPE_SINT16:
1360 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint16*)0);
1361              
1362 kumpf   1.61 	case CIMTYPE_SINT32:
1363 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint32*)0);
1364              
1365 kumpf   1.61 	case CIMTYPE_SINT64:
1366 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint64*)0);
1367              
1368 kumpf   1.61 	case CIMTYPE_DATETIME:
1369 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (CIMDateTime*)0);
1370              
1371 kumpf   1.61 	case CIMTYPE_REAL32:
1372 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Real32*)0);
1373              
1374 kumpf   1.61 	case CIMTYPE_REAL64:
1375 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Real64*)0);
1376              
1377              	default:
1378              	    break;
1379                  }
1380              
1381                  // Unreachable:
1382                  return CIMValue();
1383              }
1384              
1385              //------------------------------------------------------------------------------
1386              //
1387              // getValueArrayElement()
1388              //
1389              //     <!ELEMENT VALUE.ARRAY (VALUE*)>
1390              //
1391 karl    1.35 //  Return: Boolean. Returns false if there is no VALUE.ARRAY start element
1392              //
1393 mike    1.23 //------------------------------------------------------------------------------
1394              
1395              Boolean XmlReader::getValueArrayElement(
1396                  XmlParser& parser, 
1397                  CIMType type, 
1398                  CIMValue& value)
1399              {
1400 karl    1.35     // Clears any values from the Array. Assumes this is array CIMValue
1401 mike    1.23     value.clear();
1402              
1403                  // Get VALUE.ARRAY open tag:
1404              
1405                  XmlEntry entry;
1406 kumpf   1.32     Array<const char*> stringArray;
1407 mike    1.23 
1408 karl    1.35     // If no VALUE.ARRAY start tag, return false
1409 mike    1.23     if (!testStartTagOrEmptyTag(parser, entry, "VALUE.ARRAY"))
1410              	return false;
1411 karl    1.33 
1412 kumpf   1.32     if (entry.type != XmlEntry::EMPTY_TAG)
1413                  {
1414                      // For each VALUE element:
1415 mike    1.23 
1416 kumpf   1.32         while (testStartTagOrEmptyTag(parser, entry, "VALUE"))
1417                      {
1418              	    if (entry.type == XmlEntry::EMPTY_TAG)
1419              	    {
1420              	        stringArray.append("");
1421              	        continue;
1422              	    }
1423 mike    1.23 
1424 kumpf   1.32 	    if (testContentOrCData(parser, entry))
1425              	        stringArray.append(entry.text);
1426              	    else
1427              	        stringArray.append("");
1428 mike    1.23 
1429 kumpf   1.32 	    expectEndTag(parser, "VALUE");
1430                      }
1431 mike    1.23 
1432 kumpf   1.32         expectEndTag(parser, "VALUE.ARRAY");
1433 mike    1.23     }
1434              
1435                  value = stringArrayToValue(parser.getLine(), stringArray, type);
1436                  return true;
1437              }
1438              
1439              //------------------------------------------------------------------------------
1440              //
1441              // getFlavor()
1442              //
1443              //     <!ENTITY % QualifierFlavor 
1444              //         "OVERRIDABLE (true|false) 'true'
1445              //         TOSUBCLASS (true|false) 'true'
1446              //         TOINSTANCE (true|false)  'false'
1447              //         TRANSLATABLE (true|false)  'false'">
1448              //
1449              //------------------------------------------------------------------------------
1450              
1451 kumpf   1.64 CIMFlavor XmlReader::getFlavor(
1452 mike    1.23     XmlEntry& entry, 
1453                  Uint32 lineNumber, 
1454                  const char* tagName)
1455              {
1456                  // Get QUALIFIER.OVERRIDABLE
1457              
1458                  Boolean overridable = getCimBooleanAttribute(
1459              	lineNumber, entry, tagName, "OVERRIDABLE", true, false);
1460              
1461                  // Get QUALIFIER.TOSUBCLASS
1462              
1463                  Boolean toSubClass = getCimBooleanAttribute(
1464              	lineNumber, entry, tagName, "TOSUBCLASS", true, false);
1465              
1466                  // Get QUALIFIER.TOINSTANCE
1467              
1468                  Boolean toInstance = getCimBooleanAttribute(
1469              	lineNumber, entry, tagName, "TOINSTANCE", false, false);
1470              
1471                  // Get QUALIFIER.TRANSLATABLE
1472              
1473 mike    1.23     Boolean translatable = getCimBooleanAttribute(
1474              	lineNumber, entry, tagName, "TRANSLATABLE", false, false);
1475              
1476 kumpf   1.44     // Start with CIMFlavor::NONE.  Defaults are specified in the
1477                  // getCimBooleanAttribute() calls above.
1478 kumpf   1.64     CIMFlavor flavor = CIMFlavor (CIMFlavor::NONE);
1479 mike    1.23 
1480                  if (overridable)
1481 kumpf   1.64         flavor.addFlavor (CIMFlavor::OVERRIDABLE);
1482                  else
1483                      flavor.addFlavor (CIMFlavor::DISABLEOVERRIDE);
1484 mike    1.23 
1485                  if (toSubClass)
1486 kumpf   1.64         flavor.addFlavor (CIMFlavor::TOSUBCLASS);
1487                  else
1488                      flavor.addFlavor (CIMFlavor::RESTRICTED);
1489 mike    1.23 
1490                  if (toInstance)
1491 kumpf   1.64         flavor.addFlavor (CIMFlavor::TOINSTANCE);
1492 mike    1.23 
1493                  if (translatable)
1494 kumpf   1.64         flavor.addFlavor (CIMFlavor::TRANSLATABLE);
1495 mike    1.23 
1496                  return flavor;
1497              }
1498              
1499              //------------------------------------------------------------------------------
1500              //
1501              // getOptionalScope()
1502              //
1503              //     DTD:
1504              //         <!ELEMENT SCOPE EMPTY>
1505              //         <!ATTLIST SCOPE 
1506              //              CLASS (true|false) 'false'
1507              //              ASSOCIATION (true|false) 'false'
1508              //              REFERENCE (true|false) 'false'
1509              //              PROPERTY (true|false) 'false'
1510              //              METHOD (true|false) 'false'
1511              //              PARAMETER (true|false) 'false'
1512              //              INDICATION (true|false) 'false'>
1513              //
1514              //------------------------------------------------------------------------------
1515              
1516 kumpf   1.63 CIMScope XmlReader::getOptionalScope(XmlParser& parser)
1517 mike    1.23 {
1518                  XmlEntry entry;
1519 kumpf   1.65     CIMScope scope;
1520 mike    1.23 
1521                  if (!parser.next(entry))
1522 kumpf   1.65 	return scope;    // No SCOPE element found; return the empty scope
1523 mike    1.23 
1524                  Boolean isEmptyTag = entry.type == XmlEntry::EMPTY_TAG;
1525              
1526                  if ((!isEmptyTag && 
1527              	entry.type != XmlEntry::START_TAG) ||
1528              	strcmp(entry.text, "SCOPE") != 0)
1529                  {
1530 kumpf   1.65 	// No SCOPE element found; return the empty scope
1531 mike    1.23 	parser.putBack(entry);
1532 kumpf   1.65 	return scope;
1533 mike    1.23     }
1534              
1535                  Uint32 line = parser.getLine();
1536              
1537                  if (getCimBooleanAttribute(line, entry, "SCOPE", "CLASS", false, false))
1538 kumpf   1.63 	scope.addScope (CIMScope::CLASS);
1539 mike    1.23 
1540                  if (getCimBooleanAttribute(
1541              	line, entry, "SCOPE", "ASSOCIATION", false, false))
1542 kumpf   1.63 	scope.addScope (CIMScope::ASSOCIATION);
1543 mike    1.23 
1544                  if (getCimBooleanAttribute(
1545              	line, entry, "SCOPE", "REFERENCE", false, false))
1546 kumpf   1.63 	scope.addScope (CIMScope::REFERENCE);
1547 mike    1.23 
1548                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PROPERTY", false, false))
1549 kumpf   1.63 	scope.addScope (CIMScope::PROPERTY);
1550 mike    1.23 
1551                  if (getCimBooleanAttribute(line, entry, "SCOPE", "METHOD", false, false))
1552 kumpf   1.63 	scope.addScope (CIMScope::METHOD);
1553 mike    1.23 
1554                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PARAMETER", false, false))
1555 kumpf   1.63 	scope.addScope (CIMScope::PARAMETER);
1556 mike    1.23 
1557                  if (getCimBooleanAttribute(line, entry, "SCOPE", "INDICATION",false, false))
1558 kumpf   1.63 	scope.addScope (CIMScope::INDICATION);
1559 mike    1.23 
1560                  if (!isEmptyTag)
1561              	expectEndTag(parser, "SCOPE");
1562              
1563                  return scope;
1564              }
1565              
1566              //------------------------------------------------------------------------------
1567              //
1568              // getQualifierElement()
1569              //
1570 kumpf   1.52 //     <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)?>
1571 mike    1.23 //     <!ATTLIST QUALIFIER
1572              //         %CIMName;
1573              //         %CIMType; #REQUIRED
1574              //         %Propagated;
1575              //         %QualifierFlavor;>
1576              //
1577              //------------------------------------------------------------------------------
1578              
1579              Boolean XmlReader::getQualifierElement(
1580                  XmlParser& parser, 
1581                  CIMQualifier& qualifier)
1582              {
1583                  // Get QUALIFIER element:
1584              
1585                  XmlEntry entry;
1586                  if (!testStartTag(parser, entry, "QUALIFIER"))
1587              	return false;
1588              
1589                  // Get QUALIFIER.NAME attribute:
1590              
1591 kumpf   1.74     CIMName name = getCimNameAttribute(parser.getLine(), entry, "QUALIFIER");
1592 mike    1.23 
1593                  // Get QUALIFIER.TYPE attribute:
1594              
1595 kumpf   1.67     CIMType type;
1596                  getCimTypeAttribute(parser.getLine(), entry, type, "QUALIFIER");
1597 mike    1.23 
1598                  // Get QUALIFIER.PROPAGATED
1599              
1600                  Boolean propagated = getCimBooleanAttribute(
1601              	parser.getLine(), entry, "QUALIFIER", "PROPAGATED", false, false);
1602              
1603                  // Get flavor oriented attributes:
1604              
1605 kumpf   1.64     CIMFlavor flavor = getFlavor(entry, parser.getLine(), "QUALIFIER");
1606 mike    1.23 
1607                  // Get VALUE or VALUE.ARRAY element:
1608              
1609                  CIMValue value;
1610              
1611                  if (!getValueElement(parser, type, value) &&
1612              	!getValueArrayElement(parser, type, value))
1613                  {
1614 kumpf   1.52         value.setNullValue(type, false);
1615 mike    1.23     }
1616              
1617                  // Expect </QUALIFIER>:
1618              
1619                  expectEndTag(parser, "QUALIFIER");
1620              
1621                  // Build qualifier:
1622              
1623                  qualifier = CIMQualifier(name, value, flavor, propagated);
1624                  return true;
1625              }
1626              
1627              //------------------------------------------------------------------------------
1628              //
1629              // getQualifierElements()
1630              //
1631              //------------------------------------------------------------------------------
1632              
1633              template<class CONTAINER>
1634              void getQualifierElements(XmlParser& parser, CONTAINER& container)
1635              {
1636 mike    1.23     CIMQualifier qualifier;
1637              
1638                  while (XmlReader::getQualifierElement(parser, qualifier))
1639                  {
1640              	try
1641              	{
1642              	    container.addQualifier(qualifier);
1643              	}
1644 kumpf   1.66 	catch (AlreadyExistsException&)
1645 mike    1.23 	{
1646              	    throw XmlSemanticError(parser.getLine(), "duplicate qualifier");
1647              	}
1648                  }
1649              }
1650              
1651              //------------------------------------------------------------------------------
1652              //
1653              // getPropertyElement()
1654              //
1655              //     <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
1656              //     <!ATTLIST PROPERTY
1657              //         %CIMName;
1658              //         %ClassOrigin;
1659              //         %Propagated;
1660              //         %CIMType; #REQUIRED>
1661              //
1662              //------------------------------------------------------------------------------
1663              
1664              Boolean XmlReader::getPropertyElement(XmlParser& parser, CIMProperty& property)
1665              {
1666 mike    1.23     XmlEntry entry;
1667              
1668                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY"))
1669              	return false;
1670              
1671                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1672              
1673                  // Get PROPERTY.NAME attribute:
1674              
1675 kumpf   1.74     CIMName name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
1676 mike    1.23 
1677                  // Get PROPERTY.CLASSORIGIN attribute:
1678              
1679 kumpf   1.62     CIMName classOrigin = 
1680 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
1681              
1682                  // Get PROPERTY.PROPAGATED
1683              
1684                  Boolean propagated = getCimBooleanAttribute(
1685              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
1686              
1687                  // Get PROPERTY.TYPE attribute:
1688              
1689 kumpf   1.67     CIMType type;
1690                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY");
1691 mike    1.23 
1692 karl    1.35     // Create property: Sets type and !isarray
1693 mike    1.23 
1694 kumpf   1.56     CIMValue value(type, false);
1695 kumpf   1.62     property = CIMProperty(name, value, 0, CIMName(), classOrigin, propagated);
1696 mike    1.23 
1697                  if (!empty)
1698                  {
1699              	// Get qualifiers:
1700              
1701              	getQualifierElements(parser, property);
1702              
1703 karl    1.35 	// Get value:  Insert value if getValueElement exists (returns True)
1704 mike    1.23 
1705              	if (getValueElement(parser, type, value))
1706              	    property.setValue(value);
1707              
1708              	expectEndTag(parser, "PROPERTY");
1709                  }
1710              
1711                  return true;
1712              }
1713              
1714              //------------------------------------------------------------------------------
1715              //
1716              // getArraySizeAttribute()
1717              //
1718              //     Returns true if able to get array-size. Note that array size will
1719              //     always be a positive integer.
1720              //
1721              //     <!ENTITY % ArraySize "ARRAYSIZE CDATA #IMPLIED">
1722              //
1723              //------------------------------------------------------------------------------
1724              
1725 mike    1.23 Boolean XmlReader::getArraySizeAttribute(
1726                  Uint32 lineNumber,
1727                  const XmlEntry& entry,
1728                  const char* tagName,
1729                  Uint32& value)
1730              {
1731                  const char* tmp;
1732              
1733                  if (!entry.getAttributeValue("ARRAYSIZE", tmp))
1734              	return false;
1735              
1736                  Uint64 arraySize;
1737              
1738                  if (!stringToUnsignedInteger(tmp, arraySize) || arraySize == 0)
1739                  {
1740              	char message[128];
1741              	sprintf(message, "Illegal value for %s.%s", tagName, "ARRAYSIZE");
1742              	throw XmlSemanticError(lineNumber, message);
1743                  }
1744              
1745                  value = Uint32(arraySize);
1746 mike    1.23     return true;
1747              }
1748              
1749              //------------------------------------------------------------------------------
1750              //
1751              // getPropertyArrayElement()
1752              //
1753              //     <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
1754              //     <!ATTLIST PROPERTY.ARRAY
1755              //             %CIMName;
1756              //             %CIMType; #REQUIRED
1757              //             %ArraySize;
1758              //             %ClassOrigin;
1759              //             %Propagated;>
1760              //
1761              //------------------------------------------------------------------------------
1762              
1763              Boolean XmlReader::getPropertyArrayElement(
1764                  XmlParser& parser, 
1765                  CIMProperty& property)
1766              {
1767 mike    1.23     // Get PROPERTY element:
1768              
1769                  XmlEntry entry;
1770              
1771                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.ARRAY"))
1772              	return false;
1773              
1774                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1775              
1776                  // Get PROPERTY.NAME attribute:
1777              
1778 kumpf   1.74     CIMName name = 
1779 mike    1.23 	getCimNameAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1780              
1781                  // Get PROPERTY.TYPE attribute:
1782              
1783 kumpf   1.67     CIMType type;
1784                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY.ARRAY");
1785 mike    1.23 
1786                  // Get PROPERTY.ARRAYSIZE attribute:
1787              
1788                  Uint32 arraySize = 0;
1789                  getArraySizeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY", arraySize);
1790              
1791                  // Get PROPERTY.CLASSORIGIN attribute:
1792              
1793 kumpf   1.62     CIMName classOrigin 
1794 mike    1.23 	= getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1795              
1796                  // Get PROPERTY.ARRAY.PROPAGATED
1797              
1798                  Boolean propagated = getCimBooleanAttribute(
1799              	parser.getLine(), entry, "PROPERTY.ARRAY", "PROPAGATED", false, false);
1800              
1801                  // Create property:
1802              
1803 kumpf   1.56     CIMValue value(type, true, arraySize);
1804 mike    1.23     property = CIMProperty(
1805 kumpf   1.62 	name, value, arraySize, CIMName(), classOrigin, propagated);
1806 mike    1.23 
1807                  if (!empty)
1808                  {
1809              	// Get qualifiers:
1810              
1811              	getQualifierElements(parser, property);
1812              
1813              	// Get value:
1814              
1815              	if (getValueArrayElement(parser, type, value))
1816              	{
1817              	    if (arraySize && arraySize != value.getArraySize())
1818              	    {
1819              		throw XmlSemanticError(parser.getLine(),
1820              		    "ARRAYSIZE attribute and value-array size are different");
1821              	    }
1822              
1823              	    property.setValue(value);
1824              	}
1825              
1826              	expectEndTag(parser, "PROPERTY.ARRAY");
1827 mike    1.23     }
1828              
1829                  return true;
1830              }
1831              
1832              //------------------------------------------------------------------------------
1833              //
1834              // getHostElement()
1835              //
1836              //     <!ELEMENT HOST (#PCDATA)>
1837              //
1838              //------------------------------------------------------------------------------
1839              
1840              Boolean XmlReader::getHostElement(
1841                  XmlParser& parser,
1842                  String& host)
1843              {
1844                  XmlEntry entry;
1845              
1846                  if (!testStartTag(parser, entry, "HOST"))
1847              	return false;
1848 karl    1.78 #ifdef PEGASUS_SNIA_INTEROP_TEST
1849                  // Temp code to allow empty HOST field.
1850                  // SNIA CIMOMs return empty field particularly on enumerateinstance.
1851                  // Simply substitute a string for the empty.
1852              	if (!parser.next(entry))
1853              	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1854              
1855              	if (entry.type == XmlEntry::CONTENT)
1856              	    host = entry.text;
1857              	else
1858                  {
1859              	    parser.putBack(entry);
1860                      host = "HOSTNAMEINSERTEDBYPEGASUSCLIENT";
1861                  }
1862              
1863              #else
1864 mike    1.23 
1865                  if (!parser.next(entry) || entry.type != XmlEntry::CONTENT)
1866                  {
1867              	throw XmlValidationError(parser.getLine(),
1868              	    "expected content of HOST element");
1869                  }
1870              
1871                  host = entry.text;
1872 karl    1.78 #endif
1873 mike    1.23     expectEndTag(parser, "HOST");
1874                  return true;
1875              }
1876              
1877              //------------------------------------------------------------------------------
1878              //
1879              // getNameSpaceElement()
1880              //     
1881              //     <!ELEMENT NAMESPACE EMPTY>
1882              //     <!ATTLIST NAMESPACE %CIMName;>
1883              //
1884              //------------------------------------------------------------------------------
1885              
1886              Boolean XmlReader::getNameSpaceElement(
1887                  XmlParser& parser,
1888 kumpf   1.74     CIMName& nameSpaceComponent)
1889 mike    1.23 {
1890                  XmlEntry entry;
1891              
1892                  if (!testStartTagOrEmptyTag(parser, entry, "NAMESPACE"))
1893              	return false;
1894              
1895                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1896              
1897                  nameSpaceComponent = getCimNameAttribute(
1898              	parser.getLine(), entry, "NAMESPACE");
1899              
1900                  if (!empty)
1901              	expectEndTag(parser, "NAMESPACE");
1902              
1903                  return true;
1904              }
1905              
1906              //------------------------------------------------------------------------------
1907              //
1908              // getLocalNameSpacePathElement()
1909              //     
1910 mike    1.23 //     <!ELEMENT LOCALNAMESPACEPATH (NAMESPACE+)>
1911              //
1912              //------------------------------------------------------------------------------
1913              
1914              Boolean XmlReader::getLocalNameSpacePathElement(
1915                  XmlParser& parser,
1916                  String& nameSpace)
1917              {
1918                  XmlEntry entry;
1919              
1920                  if (!testStartTag(parser, entry, "LOCALNAMESPACEPATH"))
1921              	return false;
1922              
1923 kumpf   1.74     CIMName nameSpaceComponent;
1924 mike    1.23 
1925                  while (getNameSpaceElement(parser, nameSpaceComponent))
1926                  {
1927              	if (nameSpace.size())
1928 kumpf   1.71 	    nameSpace.append('/');
1929 mike    1.23 
1930 kumpf   1.74 	nameSpace.append(nameSpaceComponent.getString());
1931 mike    1.23     }
1932              
1933                  if (!nameSpace.size())
1934                  {
1935              	throw XmlValidationError(parser.getLine(),
1936              	    "Expected one or more NAMESPACE elements within "
1937              	    "LOCALNAMESPACEPATH element");
1938                  }
1939              
1940                  expectEndTag(parser, "LOCALNAMESPACEPATH");
1941                  return true;
1942              }
1943              
1944              //------------------------------------------------------------------------------
1945              //
1946              // getNameSpacePathElement()
1947              //
1948              //     <!ELEMENT NAMESPACEPATH (HOST,LOCALNAMESPACEPATH)>
1949              //
1950              //------------------------------------------------------------------------------
1951              
1952 mike    1.23 Boolean XmlReader::getNameSpacePathElement(
1953                  XmlParser& parser,
1954                  String& host,
1955                  String& nameSpace)
1956              {
1957                  host.clear();
1958                  nameSpace.clear();
1959              
1960                  XmlEntry entry;
1961              
1962                  if (!testStartTag(parser, entry, "NAMESPACEPATH"))
1963              	return false;
1964              
1965                  if (!getHostElement(parser, host))
1966              	throw XmlValidationError(parser.getLine(), "expected HOST element");
1967              
1968                  if (!getLocalNameSpacePathElement(parser, nameSpace))
1969                  {
1970              	throw XmlValidationError(parser.getLine(), 
1971              	    "expected LOCALNAMESPACEPATH element");
1972                  }
1973 mike    1.23 
1974                  expectEndTag(parser, "NAMESPACEPATH");
1975              
1976                  return true;
1977              }
1978              
1979              //------------------------------------------------------------------------------
1980              //
1981              // getClassNameElement()
1982              //
1983              //     <!ELEMENT CLASSNAME EMPTY>
1984              //     <!ATTLIST CLASSNAME %CIMName;>
1985              //
1986              //------------------------------------------------------------------------------
1987              
1988              Boolean XmlReader::getClassNameElement(
1989                  XmlParser& parser,
1990 kumpf   1.74     CIMName& className,
1991 mike    1.23     Boolean required)
1992              {
1993                  XmlEntry entry;
1994              
1995                  if (!testStartTagOrEmptyTag(parser, entry, "CLASSNAME"))
1996                  {
1997              	if (required)
1998              	{
1999              	    throw XmlValidationError(parser.getLine(),
2000              		"expected CLASSNAME element");
2001              	}
2002              	else
2003              	    return false;
2004                  }
2005                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2006              
2007                  className = getCimNameAttribute(
2008 kumpf   1.81 	parser.getLine(), entry, "CLASSNAME", false);
2009 mike    1.23 
2010                  if (!empty)
2011              	expectEndTag(parser, "CLASSNAME");
2012              
2013                  return true;
2014              }
2015              
2016              //------------------------------------------------------------------------------
2017              //
2018              // getValueTypeAttribute()
2019              //
2020              //     VALUETYPE (string|boolean|numeric) 'string'
2021              //
2022              //------------------------------------------------------------------------------
2023              
2024 kumpf   1.73 CIMKeyBinding::Type XmlReader::getValueTypeAttribute(
2025 mike    1.23     Uint32 lineNumber, 
2026                  const XmlEntry& entry,
2027                  const char* elementName)
2028              {
2029                  String tmp;
2030              
2031                  if (!entry.getAttributeValue("VALUETYPE", tmp))
2032 kumpf   1.73 	return CIMKeyBinding::STRING;
2033 mike    1.23 
2034                  if (String::equal(tmp, "string"))
2035 kumpf   1.73 	return CIMKeyBinding::STRING;
2036 mike    1.23     else if (String::equal(tmp, "boolean"))
2037 kumpf   1.73 	return CIMKeyBinding::BOOLEAN;
2038 mike    1.23     else if (String::equal(tmp, "numeric"))
2039 kumpf   1.73 	return CIMKeyBinding::NUMERIC;
2040 mike    1.23 
2041                  char buffer[MESSAGE_SIZE];
2042              
2043                  sprintf(buffer, 
2044              	"Illegal value for %s.VALUETYPE attribute; "
2045              	"CIMValue must be one of \"string\", \"boolean\", or \"numeric\"",
2046              	elementName);
2047              
2048                  throw XmlSemanticError(lineNumber, buffer);
2049 kumpf   1.73     return CIMKeyBinding::BOOLEAN;
2050 mike    1.23 }
2051              
2052              //------------------------------------------------------------------------------
2053              //
2054              // getKeyValueElement()
2055              //
2056              //     <!ELEMENT KEYVALUE (#PCDATA)>
2057              //     <!ATTLIST KEYVALUE
2058              //         VALUETYPE (string|boolean|numeric)  'string'>
2059              //
2060              //------------------------------------------------------------------------------
2061              
2062              Boolean XmlReader::getKeyValueElement(
2063                  XmlParser& parser,
2064 kumpf   1.73     CIMKeyBinding::Type& type,
2065 mike    1.23     String& value)
2066              {
2067                  XmlEntry entry;
2068              
2069                  if (!testStartTagOrEmptyTag(parser, entry, "KEYVALUE"))
2070              	return false;
2071              
2072                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2073              
2074                  type = getValueTypeAttribute(parser.getLine(), entry, "KEYVALUE");
2075              
2076                  value.clear();
2077              
2078                  if (!empty)
2079                  {
2080              	if (!parser.next(entry))
2081              	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
2082              
2083              	if (entry.type == XmlEntry::CONTENT)
2084              	    value = entry.text;
2085              	else
2086 mike    1.23 	    parser.putBack(entry);
2087              
2088              	expectEndTag(parser, "KEYVALUE");
2089                  }
2090              
2091                  return true;
2092              }
2093              
2094              //------------------------------------------------------------------------------
2095              //
2096              // getKeyBindingElement()
2097              //
2098              //     <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE)>
2099              //     <!ATTLIST KEYBINDING
2100              //         %CIMName;>
2101              //
2102              //------------------------------------------------------------------------------
2103              
2104              Boolean XmlReader::getKeyBindingElement(
2105                  XmlParser& parser,
2106 kumpf   1.74     CIMName& name,
2107 mike    1.23     String& value,
2108 kumpf   1.73     CIMKeyBinding::Type& type)
2109 mike    1.23 {
2110                  XmlEntry entry;
2111              
2112                  if (!testStartTag(parser, entry, "KEYBINDING"))
2113              	return false;
2114              
2115                  name = getCimNameAttribute(parser.getLine(), entry, "KEYBINDING");
2116              
2117                  if (!getKeyValueElement(parser, type, value))
2118 mike    1.25     {
2119 kumpf   1.54         CIMObjectPath reference;
2120 mike    1.25 
2121                      if (!getValueReferenceElement(parser, reference))
2122                      {
2123              	    throw XmlValidationError(parser.getLine(),
2124                                    "Expected KEYVALUE or VALUE.REFERENCE element");
2125                      }
2126              
2127 kumpf   1.73         type = CIMKeyBinding::REFERENCE;
2128 mike    1.25         value = reference.toString();
2129                  }
2130 mike    1.23 
2131                  expectEndTag(parser, "KEYBINDING");
2132                  return true;
2133              }
2134              
2135              //------------------------------------------------------------------------------
2136              //
2137              // getInstanceNameElement()
2138              //
2139              //     <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERENCE?)>
2140              //     <!ATTLIST INSTANCENAME
2141              //         %ClassName;>
2142              //
2143 mike    1.25 // Note: An empty key name is used in the keyBinding when the INSTANCENAME is
2144              // specified using a KEYVALUE or a VALUE.REFERENCE.
2145 mike    1.23 //
2146              //------------------------------------------------------------------------------
2147              
2148              Boolean XmlReader::getInstanceNameElement(
2149                  XmlParser& parser,
2150                  String& className,
2151 kumpf   1.73     Array<CIMKeyBinding>& keyBindings)
2152 mike    1.23 {
2153                  className.clear();
2154                  keyBindings.clear();
2155              
2156                  XmlEntry entry;
2157              
2158                  if (!testStartTagOrEmptyTag(parser, entry, "INSTANCENAME"))
2159              	return false;
2160              
2161                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2162              
2163                  className = getClassNameAttribute(parser.getLine(), entry, "INSTANCENAME");
2164              
2165 mike    1.25     if (empty)
2166 mike    1.23     {
2167 mike    1.25         return true;
2168                  }
2169 mike    1.23 
2170 kumpf   1.74     CIMName name;
2171 kumpf   1.73     CIMKeyBinding::Type type;
2172 mike    1.25     String value;
2173 kumpf   1.54     CIMObjectPath reference;
2174 mike    1.25 
2175                  if (getKeyValueElement(parser, type, value))
2176                  {
2177                      // Use empty key name because none was specified
2178 kumpf   1.73         keyBindings.append(CIMKeyBinding(name, value, type));
2179 mike    1.25     }
2180                  else if (getValueReferenceElement(parser, reference))
2181                  {
2182                      // Use empty key name because none was specified
2183 kumpf   1.73         type = CIMKeyBinding::REFERENCE;
2184 mike    1.25         value = reference.toString();
2185 kumpf   1.73         keyBindings.append(CIMKeyBinding(name, value, type));
2186 mike    1.25     }
2187                  else
2188                  {
2189 mike    1.23 	while (getKeyBindingElement(parser, name, value, type))
2190 kumpf   1.73 	    keyBindings.append(CIMKeyBinding(name, value, type));
2191 mike    1.25     }
2192 mike    1.23 
2193 mike    1.25     expectEndTag(parser, "INSTANCENAME");
2194 mike    1.23 
2195                  return true;
2196              }
2197              
2198              Boolean XmlReader::getInstanceNameElement(
2199                  XmlParser& parser,
2200 kumpf   1.54     CIMObjectPath& instanceName)
2201 mike    1.23 {
2202                  String className;
2203 kumpf   1.73     Array<CIMKeyBinding> keyBindings;
2204 mike    1.23 
2205                  if (!XmlReader::getInstanceNameElement(parser, className, keyBindings))
2206              	return false;
2207              
2208 kumpf   1.62     instanceName.set(String(), CIMNamespaceName(), className, keyBindings);
2209 mike    1.23     return true;
2210              }
2211              
2212              //------------------------------------------------------------------------------
2213              //
2214              // getInstancePathElement()
2215              //
2216              //     <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2217              //
2218              //------------------------------------------------------------------------------
2219              
2220              Boolean XmlReader::getInstancePathElement(
2221                  XmlParser& parser,
2222 kumpf   1.54     CIMObjectPath& reference)
2223 mike    1.23 {
2224                  XmlEntry entry;
2225              
2226                  if (!testStartTag(parser, entry, "INSTANCEPATH"))
2227              	return false;
2228              
2229                  String host;
2230                  String nameSpace;
2231              
2232                  if (!getNameSpacePathElement(parser, host, nameSpace))
2233                  {
2234              	throw XmlValidationError(parser.getLine(),
2235              	    "expected NAMESPACEPATH element");
2236                  }
2237              
2238                  String className;
2239 kumpf   1.73     Array<CIMKeyBinding> keyBindings;
2240 mike    1.23 
2241                  if (!getInstanceNameElement(parser, className, keyBindings))
2242                  {
2243              	throw XmlValidationError(parser.getLine(), 
2244              	    "expected INSTANCENAME element");
2245                  }
2246              
2247                  reference.set(host, nameSpace, className, keyBindings);
2248              
2249                  expectEndTag(parser, "INSTANCEPATH");
2250                  return true;
2251              }
2252              
2253              //------------------------------------------------------------------------------
2254              //
2255              // getLocalInstancePathElement()
2256              //
2257              //     <!ELEMENT LOCALINSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2258              //
2259              //------------------------------------------------------------------------------
2260              
2261 mike    1.23 Boolean XmlReader::getLocalInstancePathElement(
2262                  XmlParser& parser,
2263 kumpf   1.54     CIMObjectPath& reference)
2264 mike    1.23 {
2265                  XmlEntry entry;
2266              
2267                  if (!testStartTag(parser, entry, "LOCALINSTANCEPATH"))
2268              	return false;
2269              
2270                  String nameSpace;
2271              
2272                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2273                  {
2274              	throw XmlValidationError(parser.getLine(),
2275              	    "expected LOCALNAMESPACEPATH element");
2276                  }
2277              
2278                  String className;
2279 kumpf   1.73     Array<CIMKeyBinding> keyBindings;
2280 mike    1.23 
2281                  if (!getInstanceNameElement(parser, className, keyBindings))
2282                  {
2283              	throw XmlValidationError(parser.getLine(), 
2284              	    "expected INSTANCENAME element");
2285                  }
2286              
2287                  reference.set(String(), nameSpace, className, keyBindings);
2288              
2289                  expectEndTag(parser, "LOCALINSTANCEPATH");
2290                  return true;
2291              }
2292              
2293              //------------------------------------------------------------------------------
2294              //
2295              // getClassPathElement()
2296              //
2297              //     <!ELEMENT CLASSPATH (NAMESPACEPATH,CLASSNAME)>
2298              //
2299              //------------------------------------------------------------------------------
2300              
2301 mike    1.23 Boolean XmlReader::getClassPathElement(
2302                  XmlParser& parser,
2303 kumpf   1.54     CIMObjectPath& reference)
2304 mike    1.23 {
2305                  XmlEntry entry;
2306              
2307                  if (!testStartTag(parser, entry, "CLASSPATH"))
2308              	return false;
2309              
2310                  String host;
2311                  String nameSpace;
2312              
2313                  if (!getNameSpacePathElement(parser, host, nameSpace))
2314                  {
2315              	throw XmlValidationError(parser.getLine(),
2316              	    "expected NAMESPACEPATH element");
2317                  }
2318              
2319 kumpf   1.74     CIMName className;
2320 mike    1.23 
2321                  if (!getClassNameElement(parser, className))
2322                  {
2323              	throw XmlValidationError(parser.getLine(), 
2324              	    "expected CLASSNAME element");
2325                  }
2326              
2327                  reference.set(host, nameSpace, className);
2328              
2329                  expectEndTag(parser, "CLASSPATH");
2330                  return true;
2331              }
2332              
2333              //------------------------------------------------------------------------------
2334              //
2335              // getLocalClassPathElement()
2336              //
2337              //     <!ELEMENT LOCALCLASSPATH (LOCALNAMESPACEPATH,CLASSNAME)>
2338              //
2339              //------------------------------------------------------------------------------
2340              
2341 mike    1.23 Boolean XmlReader::getLocalClassPathElement(
2342                  XmlParser& parser,
2343 kumpf   1.54     CIMObjectPath& reference)
2344 mike    1.23 {
2345                  XmlEntry entry;
2346              
2347                  if (!testStartTag(parser, entry, "LOCALCLASSPATH"))
2348              	return false;
2349              
2350                  String nameSpace;
2351              
2352                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2353                  {
2354              	throw XmlValidationError(parser.getLine(),
2355              	    "expected LOCALNAMESPACEPATH element");
2356                  }
2357              
2358 kumpf   1.74     CIMName className;
2359 mike    1.23 
2360                  if (!getClassNameElement(parser, className))
2361                  {
2362              	throw XmlValidationError(parser.getLine(), 
2363              	    "expected CLASSNAME element");
2364                  }
2365              
2366                  reference.set(String(), nameSpace, className);
2367              
2368                  expectEndTag(parser, "LOCALCLASSPATH");
2369              
2370                  return true;
2371              }
2372              
2373              //------------------------------------------------------------------------------
2374              //
2375              // getValueReferenceElement()
2376              //
2377              //     <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
2378              //         INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
2379              //
2380 mike    1.23 //
2381              //------------------------------------------------------------------------------
2382              
2383              Boolean XmlReader::getValueReferenceElement(
2384                  XmlParser& parser,
2385 kumpf   1.54     CIMObjectPath& reference)
2386 mike    1.23 {
2387                  XmlEntry entry;
2388              
2389                  if (!testStartTag(parser, entry, "VALUE.REFERENCE"))
2390              	return false;
2391              
2392                  if (!parser.next(entry))
2393              	throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
2394              
2395                  if (entry.type != XmlEntry::START_TAG && 
2396              	entry.type != XmlEntry::EMPTY_TAG)
2397                  {
2398              	throw XmlValidationError(parser.getLine(), 
2399              	    "Expected one of the following start tags: "
2400              	    "CLASSPATH, LOCALCLASSPATH, CLASSNAME, INSTANCEPATH, "
2401              	    "LOCALINSTANCEPATH, INSTANCENAME");
2402                  }
2403              
2404                  if (strcmp(entry.text, "CLASSPATH") == 0)
2405                  {
2406              	parser.putBack(entry);
2407 mike    1.23 	getClassPathElement(parser, reference);
2408                  }
2409                  else if (strcmp(entry.text, "LOCALCLASSPATH") == 0)
2410                  {
2411              	parser.putBack(entry);
2412              	getLocalClassPathElement(parser, reference);
2413                  }
2414                  else if (strcmp(entry.text, "CLASSNAME") == 0)
2415                  {
2416              	parser.putBack(entry);
2417 kumpf   1.74 	CIMName className;
2418 mike    1.23 	getClassNameElement(parser, className);
2419 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className);
2420 mike    1.23     }
2421                  else if (strcmp(entry.text, "INSTANCEPATH") == 0)
2422                  {
2423              	parser.putBack(entry);
2424              	getInstancePathElement(parser, reference);
2425                  }
2426                  else if (strcmp(entry.text, "LOCALINSTANCEPATH") == 0)
2427                  {
2428              	parser.putBack(entry);
2429              	getLocalInstancePathElement(parser, reference);
2430                  }
2431                  else if (strcmp(entry.text, "INSTANCENAME") == 0)
2432                  {
2433              	parser.putBack(entry);
2434              	String className;
2435 kumpf   1.73 	Array<CIMKeyBinding> keyBindings;
2436 mike    1.23 	getInstanceNameElement(parser, className, keyBindings);
2437 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className, keyBindings);
2438 mike    1.23     }
2439              
2440                  expectEndTag(parser, "VALUE.REFERENCE");
2441                  return true;
2442              }
2443              
2444              //------------------------------------------------------------------------------
2445              //
2446 kumpf   1.28 // getValueReferenceArrayElement()
2447              //
2448              //     <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
2449              //
2450              //------------------------------------------------------------------------------
2451              
2452              Boolean XmlReader::getValueReferenceArrayElement(
2453                  XmlParser& parser, 
2454                  CIMValue& value)
2455              {
2456                  XmlEntry entry;
2457 kumpf   1.54     Array<CIMObjectPath> referenceArray;
2458                  CIMObjectPath reference;
2459 kumpf   1.28 
2460                  value.clear();
2461              
2462                  // Get VALUE.REFARRAY open tag:
2463              
2464                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE.REFARRAY"))
2465              	return false;
2466              
2467 kumpf   1.32     if (entry.type != XmlEntry::EMPTY_TAG)
2468                  {
2469                      // For each VALUE.REFERENCE element:
2470 kumpf   1.28 
2471 kumpf   1.32         while (getValueReferenceElement(parser, reference))
2472                      {
2473              	    referenceArray.append(reference);
2474                      }
2475 kumpf   1.28 
2476 kumpf   1.32         expectEndTag(parser, "VALUE.REFARRAY");
2477 kumpf   1.28     }
2478              
2479                  value.set(referenceArray);
2480                  return true;
2481              }
2482              
2483              //------------------------------------------------------------------------------
2484              //
2485 mike    1.23 // getPropertyReferenceElement()
2486              //
2487              //     <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,(VALUE.REFERENCE)?)>
2488              //     <!ATTLIST PROPERTY.REFERENCE
2489              //         %CIMName;
2490              //         %ReferenceClass;
2491              //         %ClassOrigin;
2492              //         %Propagated;>
2493              //
2494              //------------------------------------------------------------------------------
2495              
2496              Boolean XmlReader::getPropertyReferenceElement(
2497                  XmlParser& parser, 
2498                  CIMProperty& property)
2499              {
2500                  XmlEntry entry;
2501              
2502                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.REFERENCE"))
2503              	return false;
2504              
2505                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2506 mike    1.23 
2507                  // Get PROPERTY.NAME attribute:
2508              
2509 kumpf   1.74     CIMName name = getCimNameAttribute(
2510 mike    1.23 	parser.getLine(), entry, "PROPERTY.REFERENCE");
2511              
2512                  // Get PROPERTY.REFERENCECLASS attribute:
2513              
2514 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2515 mike    1.23 	parser.getLine(), entry, "PROPERTY.REFERENCE");
2516              
2517                  // Get PROPERTY.CLASSORIGIN attribute:
2518              
2519 kumpf   1.62     CIMName classOrigin = 
2520 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.REFERENCE");
2521              
2522                  // Get PROPERTY.PROPAGATED
2523              
2524                  Boolean propagated = getCimBooleanAttribute(parser.getLine(), entry, 
2525              	"PROPERTY.REFERENCE", "PROPAGATED", false, false);
2526              
2527                  // Create property:
2528              
2529 kumpf   1.61     CIMValue value = CIMValue(CIMTYPE_REFERENCE, false, 0);
2530 kumpf   1.54 //    value.set(CIMObjectPath());
2531 mike    1.23     property = CIMProperty(
2532              	name, value, 0, referenceClass, classOrigin, propagated);
2533              
2534                  if (!empty)
2535                  {
2536              	getQualifierElements(parser, property);
2537              
2538 kumpf   1.54 	CIMObjectPath reference;
2539 mike    1.23 
2540              	if (getValueReferenceElement(parser, reference))
2541              	    property.setValue(reference);
2542              
2543              	expectEndTag(parser, "PROPERTY.REFERENCE");
2544                  }
2545              
2546                  return true;
2547              }
2548              
2549              //------------------------------------------------------------------------------
2550              //
2551              // GetPropertyElements()
2552              //
2553              //------------------------------------------------------------------------------
2554              
2555              template<class CONTAINER>
2556              void GetPropertyElements(XmlParser& parser, CONTAINER& container)
2557              {
2558                  CIMProperty property;
2559              
2560 mike    1.23     while (XmlReader::getPropertyElement(parser, property) ||
2561              	XmlReader::getPropertyArrayElement(parser, property) ||
2562              	XmlReader::getPropertyReferenceElement(parser, property))
2563                  {
2564              	try
2565              	{
2566              	    container.addProperty(property);
2567              	}
2568 kumpf   1.66 	catch (AlreadyExistsException&)
2569 mike    1.23 	{
2570              	    throw XmlSemanticError(parser.getLine(), "duplicate property");
2571              	}
2572                  }
2573              }
2574              
2575              //------------------------------------------------------------------------------
2576              //
2577              // getParameterElement()
2578              //
2579              //     <!ELEMENT PARAMETER (QUALIFIER*)>
2580              //     <!ATTLIST PARAMETER
2581              //         %CIMName;
2582              //         %CIMType; #REQUIRED>
2583              //
2584              //------------------------------------------------------------------------------
2585              
2586              Boolean XmlReader::getParameterElement(
2587                  XmlParser& parser, 
2588                  CIMParameter& parameter)
2589              {
2590 mike    1.23     XmlEntry entry;
2591              
2592                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER"))
2593              	return false;
2594              
2595                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2596              
2597                  // Get PARAMETER.NAME attribute:
2598              
2599 kumpf   1.74     CIMName name = getCimNameAttribute(parser.getLine(), entry, "PARAMETER");
2600 mike    1.23 
2601                  // Get PARAMETER.TYPE attribute:
2602              
2603 kumpf   1.67     CIMType type;
2604                  getCimTypeAttribute(parser.getLine(), entry, type, "PARAMETER");
2605 mike    1.23 
2606                  // Create parameter:
2607              
2608                  parameter = CIMParameter(name, type);
2609              
2610                  if (!empty)
2611                  {
2612              	getQualifierElements(parser, parameter);
2613              
2614              	expectEndTag(parser, "PARAMETER");
2615                  }
2616              
2617                  return true;
2618              }
2619              
2620              //------------------------------------------------------------------------------
2621              //
2622              // getParameterArrayElement()
2623              //
2624              //     <!ELEMENT PARAMETER.ARRAY (QUALIFIER*)>
2625              //     <!ATTLIST PARAMETER.ARRAY
2626 mike    1.23 //         %CIMName;
2627              //         %CIMType; #REQUIRED
2628              //         %ArraySize;>
2629              //
2630              //------------------------------------------------------------------------------
2631              
2632              Boolean XmlReader::getParameterArrayElement(
2633                  XmlParser& parser, 
2634                  CIMParameter& parameter)
2635              {
2636                  XmlEntry entry;
2637              
2638                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.ARRAY"))
2639              	return false;
2640              
2641                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2642              
2643                  // Get PARAMETER.ARRAY.NAME attribute:
2644              
2645 kumpf   1.74     CIMName name = getCimNameAttribute(
2646 mike    1.23 	parser.getLine(), entry, "PARAMETER.ARRAY");
2647              
2648                  // Get PARAMETER.ARRAY.TYPE attribute:
2649              
2650 kumpf   1.67     CIMType type;
2651                  getCimTypeAttribute(parser.getLine(), entry, type, "PARAMETER.ARRAY");
2652 mike    1.23 
2653                  // Get PARAMETER.ARRAYSIZE attribute:
2654              
2655                  Uint32 arraySize = 0;
2656                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY",arraySize);
2657              
2658                  // Create parameter:
2659              
2660                  parameter = CIMParameter(name, type, true, arraySize);
2661              
2662                  if (!empty)
2663                  {
2664              	getQualifierElements(parser, parameter);
2665              
2666              	expectEndTag(parser, "PARAMETER.ARRAY");
2667                  }
2668              
2669                  return true;
2670              }
2671              
2672              //------------------------------------------------------------------------------
2673 mike    1.23 //
2674              // getParameterReferenceElement()
2675              //
2676              //     <!ELEMENT PARAMETER.REFERENCE (QUALIFIER*)>
2677              //     <!ATTLIST PARAMETER.REFERENCE
2678              //         %CIMName;
2679              //         %ReferenceClass;>
2680              //
2681              //------------------------------------------------------------------------------
2682              
2683              Boolean XmlReader::getParameterReferenceElement(
2684                  XmlParser& parser, 
2685                  CIMParameter& parameter)
2686              {
2687                  XmlEntry entry;
2688              
2689                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFERENCE"))
2690              	return false;
2691              
2692                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2693              
2694 mike    1.23     // Get PARAMETER.NAME attribute:
2695              
2696 kumpf   1.74     CIMName name = getCimNameAttribute(
2697 mike    1.23 	parser.getLine(), entry, "PARAMETER.REFERENCE");
2698              
2699                  // Get PARAMETER.REFERENCECLASS attribute:
2700              
2701 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2702 mike    1.23 	parser.getLine(), entry, "PARAMETER.REFERENCE");
2703              
2704                  // Create parameter:
2705              
2706 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, false, 0, referenceClass);
2707 mike    1.23 
2708                  if (!empty)
2709                  {
2710              	getQualifierElements(parser, parameter);
2711              	expectEndTag(parser, "PARAMETER.REFERENCE");
2712                  }
2713              
2714                  return true;
2715              }
2716              
2717              //------------------------------------------------------------------------------
2718              //
2719 kumpf   1.26 // getParameterReferenceArrayElement()
2720              //
2721              //     <!ELEMENT PARAMETER.REFARRAY (QUALIFIER*)>
2722              //     <!ATTLIST PARAMETER.REFARRAY
2723              //         %CIMName;
2724              //         %ReferenceClass;
2725              //         %ArraySize;>
2726              //
2727              //------------------------------------------------------------------------------
2728              
2729              Boolean XmlReader::getParameterReferenceArrayElement(
2730                  XmlParser& parser, 
2731                  CIMParameter& parameter)
2732              {
2733                  XmlEntry entry;
2734              
2735                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFARRAY"))
2736              	return false;
2737              
2738                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2739              
2740 kumpf   1.26     // Get PARAMETER.NAME attribute:
2741              
2742 kumpf   1.74     CIMName name = getCimNameAttribute(
2743 kumpf   1.26 	parser.getLine(), entry, "PARAMETER.REFARRAY");
2744              
2745                  // Get PARAMETER.REFERENCECLASS attribute:
2746              
2747 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2748 kumpf   1.26 	parser.getLine(), entry, "PARAMETER.REFARRAY");
2749              
2750                  // Get PARAMETER.ARRAYSIZE attribute:
2751              
2752                  Uint32 arraySize = 0;
2753                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.REFARRAY",
2754              			  arraySize);
2755              
2756                  // Create parameter:
2757              
2758 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, true, arraySize,
2759 kumpf   1.26 			     referenceClass);
2760              
2761                  if (!empty)
2762                  {
2763              	getQualifierElements(parser, parameter);
2764              	expectEndTag(parser, "PARAMETER.REFARRAY");
2765                  }
2766              
2767                  return true;
2768              }
2769              
2770              //------------------------------------------------------------------------------
2771              //
2772 mike    1.23 // GetParameterElements()
2773              //
2774              //------------------------------------------------------------------------------
2775              
2776              template<class CONTAINER>
2777              void GetParameterElements(XmlParser& parser, CONTAINER& container)
2778              {
2779                  CIMParameter parameter;
2780              
2781                  while (XmlReader::getParameterElement(parser, parameter) ||
2782              	XmlReader::getParameterArrayElement(parser, parameter) ||
2783 kumpf   1.26 	XmlReader::getParameterReferenceElement(parser, parameter) ||
2784              	XmlReader::getParameterReferenceArrayElement(parser, parameter))
2785 mike    1.23     {
2786              	try
2787              	{
2788              	    container.addParameter(parameter);
2789              	}
2790 kumpf   1.66 	catch (AlreadyExistsException&)
2791 mike    1.23 	{
2792              	    throw XmlSemanticError(parser.getLine(), "duplicate parameter");
2793              	}
2794                  }
2795              }
2796              
2797              //------------------------------------------------------------------------------
2798              //
2799              // getQualifierDeclElement()
2800              //
2801              //     <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
2802              //     <!ATTLIST QUALIFIER.DECLARATION 
2803              //         %CIMName;               
2804              //         %CIMType; #REQUIRED
2805              //         ISARRAY (true|false) #IMPLIED
2806              //         %ArraySize;
2807              //         %QualifierFlavor;>
2808              //         
2809              //------------------------------------------------------------------------------
2810              
2811              Boolean XmlReader::getQualifierDeclElement(
2812 mike    1.23     XmlParser& parser, 
2813                  CIMQualifierDecl& qualifierDecl)
2814              {
2815                  XmlEntry entry;
2816              
2817                  if (!testStartTagOrEmptyTag(parser, entry, "QUALIFIER.DECLARATION"))
2818              	return false;
2819              
2820                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2821              
2822                  // Get NAME attribute:
2823              
2824 kumpf   1.74     CIMName name = getCimNameAttribute(
2825 mike    1.23 	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2826              
2827                  // Get TYPE attribute:
2828              
2829 kumpf   1.67     CIMType type;
2830                  getCimTypeAttribute(parser.getLine(), entry, type, "QUALIFIER.DECLARATION");
2831 mike    1.23 
2832                  // Get ISARRAY attribute:
2833              
2834 mike    1.25     Boolean isArray = getCimBooleanAttribute(
2835                      parser.getLine(), entry, "QUALIFIER.DECLARATION", "ISARRAY",
2836                      false, false); 
2837 mike    1.23 
2838                  // Get ARRAYSIZE attribute:
2839              
2840                  Uint32 arraySize = 0;
2841                  Boolean gotArraySize = getArraySizeAttribute(parser.getLine(),
2842              	entry, "QUALIFIER.DECLARATION", arraySize);
2843              
2844                  // Get flavor oriented attributes:
2845              
2846 kumpf   1.64     CIMFlavor flavor = getFlavor (entry, parser.getLine (), 
2847                      "QUALIFIER.DECLARATION");
2848 mike    1.23 
2849                  // No need to look for interior elements if empty tag:
2850              
2851 kumpf   1.63     CIMScope scope = CIMScope ();
2852 mike    1.23     CIMValue value;
2853 kumpf   1.67     Boolean gotValue = false;
2854 mike    1.23 
2855                  if (!empty)
2856                  {
2857              	// Get the option SCOPE element:
2858              
2859              	scope = getOptionalScope(parser);
2860              
2861              	// Get VALUE or VALUE.ARRAY element:
2862              
2863              	if (getValueArrayElement(parser, type, value))
2864              	{
2865              	    if (!isArray)
2866              	    {
2867              		throw XmlSemanticError(parser.getLine(),
2868              		    "VALUE.ARRAY element encountered without "
2869              		    "ISARRAY attribute");
2870              	    }
2871              
2872              	    if (arraySize && arraySize != value.getArraySize())
2873              	    {
2874              		throw XmlSemanticError(parser.getLine(),
2875 mike    1.23 		    "VALUE.ARRAY size is not the same as "
2876              		    "ARRAYSIZE attribute");
2877              	    }
2878 kumpf   1.67 
2879                          gotValue = true;
2880 mike    1.23 	}
2881              	else if (getValueElement(parser, type, value))
2882              	{
2883              	    if (isArray)
2884              	    {
2885              		throw XmlSemanticError(parser.getLine(),
2886              		    "ISARRAY attribute used but VALUE element encountered");
2887              	    }
2888 kumpf   1.67 
2889                          gotValue = true;
2890 mike    1.23 	}
2891              
2892              	// Now get the closing tag:
2893              
2894              	expectEndTag(parser, "QUALIFIER.DECLARATION");
2895                  }
2896              
2897 kumpf   1.67     if (!gotValue)
2898 mike    1.23     {
2899              	if (isArray)
2900              	    value.setNullValue(type, true, arraySize);
2901              	else
2902              	    value.setNullValue(type, false);
2903                  }
2904              
2905                  CIMQualifierDecl tmp(name, value, scope, flavor, arraySize);
2906                  qualifierDecl = CIMQualifierDecl(name, value, scope, flavor, arraySize);
2907                  return true;
2908              }
2909              
2910              //------------------------------------------------------------------------------
2911              // getMethodElement()
2912              //
2913              //     <!ELEMENT METHOD (QUALIFIER*,(PARAMETER|PARAMETER.REFERENCE|
2914              //         PARAMETER.ARRAY|PARAMETER.REFARRAY)*)>
2915              //     <!ATTLIST METHOD
2916              //         %CIMName;
2917              //         %CIMType; #IMPLIED
2918              //         %ClassOrigin;
2919 mike    1.23 //         %Propagated;>
2920              //
2921              //------------------------------------------------------------------------------
2922              
2923              Boolean XmlReader::getMethodElement(XmlParser& parser, CIMMethod& method)
2924              {
2925                  XmlEntry entry;
2926              
2927                  if (!testStartTagOrEmptyTag(parser, entry, "METHOD"))
2928              	return false;
2929              
2930                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2931              
2932 kumpf   1.74     CIMName name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
2933 mike    1.23 
2934 kumpf   1.67     CIMType type;
2935                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY");
2936 mike    1.23 
2937 kumpf   1.62     CIMName classOrigin = 
2938 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
2939              
2940                  Boolean propagated = getCimBooleanAttribute(
2941              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
2942              
2943                  method = CIMMethod(name, type, classOrigin, propagated);
2944              
2945                  if (!empty)
2946                  {
2947 kumpf   1.26         // ATTN-RK-P2-20020219: Decoding algorithm must not depend on the
2948                      // ordering of qualifiers and parameters.
2949 mike    1.23 	getQualifierElements(parser, method);
2950              
2951              	GetParameterElements(parser, method);
2952              
2953              	expectEndTag(parser, "METHOD");
2954                  }
2955              
2956                  return true;
2957              }
2958              
2959              //------------------------------------------------------------------------------
2960              // getClassElement()
2961              //
2962              //     <!ELEMENT CLASS (QUALIFIER*,
2963              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*,METHOD*)>
2964              //     <!ATTLIST CLASS %CIMName; %SuperClass;>
2965              //
2966              //------------------------------------------------------------------------------
2967              
2968              Boolean XmlReader::getClassElement(XmlParser& parser, CIMClass& cimClass)
2969              {
2970 mike    1.23     XmlEntry entry;
2971              
2972                  if (!testStartTag(parser, entry, "CLASS"))
2973              	return false;
2974              
2975 kumpf   1.74     CIMName name = getCimNameAttribute(parser.getLine(), entry, "CLASS");
2976 mike    1.23 
2977 kumpf   1.62     CIMName superClass = getSuperClassAttribute(parser.getLine(), entry,"CLASS");
2978 mike    1.23 
2979                  cimClass = CIMClass(name, superClass);
2980              
2981                  // Get QUALIFIER elements:
2982              
2983                  getQualifierElements(parser, cimClass);
2984              
2985                  // Get PROPERTY elements:
2986              
2987                  GetPropertyElements(parser, cimClass);
2988              
2989                  // Get METHOD elements:
2990              
2991                  CIMMethod method;
2992              
2993                  while (getMethodElement(parser, method))
2994              	cimClass.addMethod(method);	
2995              
2996                  // Get CLASS end tag:
2997              
2998                  expectEndTag(parser, "CLASS");
2999 mike    1.23 
3000                  return true;
3001              }
3002              
3003              //------------------------------------------------------------------------------
3004              // getInstanceElement()
3005              //
3006              //     <!ELEMENT INSTANCE (QUALIFIER*,
3007              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*) >
3008              //     <!ATTLIST INSTANCE
3009              //         %ClassName;>
3010              //
3011              //------------------------------------------------------------------------------
3012              
3013              Boolean XmlReader::getInstanceElement(
3014                  XmlParser& parser, 
3015                  CIMInstance& cimInstance)
3016              {
3017                  XmlEntry entry;
3018              
3019                  if (!testStartTag(parser, entry, "INSTANCE"))
3020 mike    1.23 	return false;
3021              
3022                  String className = getClassNameAttribute(
3023              	parser.getLine(), entry, "INSTANCE");
3024              
3025                  cimInstance = CIMInstance(className);
3026              
3027                  // Get QUALIFIER elements:
3028              
3029                  getQualifierElements(parser, cimInstance);
3030              
3031                  // Get PROPERTY elements:
3032              
3033                  GetPropertyElements(parser, cimInstance);
3034              
3035                  // Get INSTANCE end tag:
3036              
3037                  expectEndTag(parser, "INSTANCE");
3038              
3039                  return true;
3040              }
3041 mike    1.23 
3042              //------------------------------------------------------------------------------
3043 mike    1.25 // getNamedInstanceElement()
3044              //
3045              //     <!ELEMENT VALUE.NAMEDINSTANCE (INSTANCENAME,INSTANCE)>
3046              //
3047              //------------------------------------------------------------------------------
3048              
3049              Boolean XmlReader::getNamedInstanceElement(
3050                  XmlParser& parser, 
3051 kumpf   1.55     CIMInstance& namedInstance)
3052 mike    1.25 {
3053                  XmlEntry entry;
3054              
3055                  if (!testStartTag(parser, entry, "VALUE.NAMEDINSTANCE"))
3056              	return false;
3057              
3058 kumpf   1.54     CIMObjectPath instanceName;
3059 mike    1.25 
3060                  // Get INSTANCENAME elements:
3061              
3062                  if (!getInstanceNameElement(parser, instanceName))
3063                  {
3064              	throw XmlValidationError(parser.getLine(), 
3065              	    "expected INSTANCENAME element");
3066                  }
3067              
3068                  // Get INSTANCE elements:
3069              
3070 kumpf   1.55     if (!getInstanceElement(parser, namedInstance))
3071 mike    1.25     {
3072              	throw XmlValidationError(parser.getLine(),
3073              	    "expected INSTANCE element");
3074                  }
3075              
3076                  // Get VALUE.NAMEDINSTANCE end tag:
3077              
3078                  expectEndTag(parser, "VALUE.NAMEDINSTANCE");
3079              
3080 kumpf   1.55     namedInstance.setPath (instanceName);
3081 mike    1.25 
3082                  return true;
3083              }
3084              
3085              //------------------------------------------------------------------------------
3086 mike    1.23 //
3087              // getObject()
3088              //
3089              //------------------------------------------------------------------------------
3090              
3091              void XmlReader::getObject(XmlParser& parser, CIMClass& x)
3092              {
3093                  if (!getClassElement(parser, x))
3094                  {
3095              	throw XmlValidationError(parser.getLine(),
3096              	    "expected CLASS element");
3097                  }
3098              }
3099              
3100              //------------------------------------------------------------------------------
3101              //
3102              // getObject()
3103              //
3104              //------------------------------------------------------------------------------
3105              
3106              void XmlReader::getObject(XmlParser& parser, CIMInstance& x)
3107 mike    1.23 {
3108                  if (!getInstanceElement(parser, x))
3109                  {
3110              	throw XmlValidationError(parser.getLine(),
3111              	    "expected INSTANCE element");
3112                  }
3113              }
3114              
3115              //------------------------------------------------------------------------------
3116              //
3117              // getObject()
3118              //
3119              //------------------------------------------------------------------------------
3120              
3121              void XmlReader::getObject(XmlParser& parser, CIMQualifierDecl& x)
3122              {
3123                  if (!getQualifierDeclElement(parser, x))
3124                  {
3125              	throw XmlValidationError(parser.getLine(),
3126              	    "expected QUALIFIER.DECLARATION element");
3127                  }
3128 mike    1.23 }
3129              
3130              //------------------------------------------------------------------------------
3131              //
3132              // getMessageStartTag()
3133              //
3134              //------------------------------------------------------------------------------
3135              
3136              Boolean XmlReader::getMessageStartTag(
3137                  XmlParser& parser, 
3138                  String& id,
3139 kumpf   1.34     String& protocolVersion)
3140 mike    1.23 {
3141                  XmlEntry entry;
3142              
3143                  if (!testStartTag(parser, entry, "MESSAGE"))
3144              	return false;
3145              
3146                  // Get MESSAGE.ID:
3147              
3148                  if (!entry.getAttributeValue("ID", id))
3149              	throw XmlValidationError(parser.getLine(), 
3150 kumpf   1.66 	    "Invalid or missing MESSAGE.ID attribute");
3151 mike    1.23 
3152                  // Get MESSAGE.PROTOCOLVERSION:
3153              
3154                  if (!entry.getAttributeValue("PROTOCOLVERSION", protocolVersion))
3155              	throw XmlValidationError(parser.getLine(),
3156 kumpf   1.66 	    "Invalid or missing MESSAGE.PROTOCOLVERSION attribute");
3157 mike    1.23 
3158                  return true;
3159              }
3160              
3161              //------------------------------------------------------------------------------
3162              //
3163              // getIMethodCallStartTag()
3164              //
3165              //------------------------------------------------------------------------------
3166              
3167              Boolean XmlReader::getIMethodCallStartTag(
3168                  XmlParser& parser, 
3169                  const char*& name)
3170              {
3171                  XmlEntry entry;
3172              
3173                  if (!testStartTag(parser, entry, "IMETHODCALL"))
3174              	return false;
3175              
3176                  // Get IMETHODCALL.NAME attribute:
3177              
3178 mike    1.23     if (!entry.getAttributeValue("NAME", name))
3179              	throw XmlValidationError(parser.getLine(),
3180              	    "Missing IMETHODCALL.NAME attribute");
3181              
3182                  return true;
3183              }
3184              
3185              //------------------------------------------------------------------------------
3186              //
3187              // getIMethodResponseStartTag()
3188              //
3189              //------------------------------------------------------------------------------
3190              
3191              Boolean XmlReader::getIMethodResponseStartTag(
3192                  XmlParser& parser, 
3193                  const char*& name)
3194              {
3195                  XmlEntry entry;
3196              
3197                  if (!testStartTag(parser, entry, "IMETHODRESPONSE"))
3198              	return false;
3199 mike    1.23 
3200                  // Get IMETHODRESPONSE.NAME attribute:
3201              
3202                  if (!entry.getAttributeValue("NAME", name))
3203              	throw XmlValidationError(parser.getLine(),
3204              	    "Missing IMETHODRESPONSE.NAME attribute");
3205              
3206                  return true;
3207              }
3208              
3209              //------------------------------------------------------------------------------
3210              //
3211              // getIParamValueTag()
3212              //
3213              //------------------------------------------------------------------------------
3214              
3215              Boolean XmlReader::getIParamValueTag(
3216                  XmlParser& parser, 
3217                  const char*& name)
3218              {
3219                  XmlEntry entry;
3220 mike    1.23 
3221                  if (!testStartTag(parser, entry, "IPARAMVALUE"))
3222              	return false;
3223              
3224                  // Get IPARAMVALUE.NAME attribute:
3225              
3226                  if (!entry.getAttributeValue("NAME", name))
3227              	throw XmlValidationError(parser.getLine(),
3228              	    "Missing IPARAMVALUE.NAME attribute");
3229              
3230                  return true;
3231              }
3232              
3233              //------------------------------------------------------------------------------
3234              //
3235              // getBooleanValueElement()
3236              //
3237              //     Get an elements like: "<VALUE>FALSE</VALUE>"
3238              //
3239              //------------------------------------------------------------------------------
3240              
3241 mike    1.23 Boolean XmlReader::getBooleanValueElement(
3242                  XmlParser& parser, 
3243                  Boolean& result,
3244                  Boolean required)
3245              {
3246                  XmlEntry entry;
3247              
3248                  if (!testStartTag(parser, entry, "VALUE"))
3249                  {
3250              	if (required)
3251              	{
3252              	    throw XmlValidationError(parser.getLine(),
3253              		"Expected VALUE element");
3254              	}
3255              	return false;
3256                  }
3257              
3258                  expectContentOrCData(parser, entry);
3259              
3260 kumpf   1.72     if (System::strcasecmp(entry.text, "TRUE") == 0)
3261 mike    1.23 	result = true;
3262 kumpf   1.72     else if (System::strcasecmp(entry.text, "FALSE") == 0)
3263 mike    1.23 	result = false;
3264                  else
3265              	throw XmlSemanticError(parser.getLine(), 
3266 kumpf   1.66 	    "Invalid value for VALUE element: must be \"TRUE\" or \"FALSE\"");
3267 mike    1.23 
3268                  expectEndTag(parser, "VALUE");
3269              
3270                  return true;
3271              }
3272              
3273              //------------------------------------------------------------------------------
3274              //
3275              // getErrorElement()
3276              //
3277              //     <!ELEMENT ERROR EMPTY>
3278              //     <!ATTLIST ERROR 
3279              //         CODE CDATA #REQUIRED
3280              //         DESCRIPTION CDATA #IMPLIED>
3281              //
3282              //------------------------------------------------------------------------------
3283              
3284              Boolean XmlReader::getErrorElement(
3285                  XmlParser& parser, 
3286 kumpf   1.50     CIMException& cimException,
3287 mike    1.23     Boolean required)
3288              {
3289                  XmlEntry entry;
3290              
3291                  if (!testStartTagOrEmptyTag(parser, entry, "ERROR"))
3292                  {
3293              	if (required)
3294              	    throw XmlValidationError(parser.getLine(),"Expected ERROR element");
3295              	return false;
3296                  }
3297              
3298                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3299              
3300                  // Get ERROR.CODE
3301              
3302                  Uint32 tmpCode;
3303              
3304                  if (!entry.getAttributeValue("CODE", tmpCode))
3305              	throw XmlValidationError(
3306              	    parser.getLine(), "missing ERROR.CODE attribute");
3307              
3308 kumpf   1.50     // Get ERROR.DESCRIPTION:
3309 mike    1.23 
3310 kumpf   1.50     String tmpDescription;
3311 mike    1.23 
3312 kumpf   1.50     entry.getAttributeValue("DESCRIPTION", tmpDescription);
3313 mike    1.23 
3314                  if (!empty)
3315              	expectEndTag(parser, "ERROR");
3316              
3317 kumpf   1.50     cimException = PEGASUS_CIM_EXCEPTION(CIMStatusCode(tmpCode), tmpDescription);
3318 mike    1.23     return true;
3319              }
3320              
3321              
3322              //------------------------------------------------------------------------------
3323 kumpf   1.48 // getValueObjectElement()
3324              //
3325              // <!ELEMENT VALUE.OBJECT (CLASS|INSTANCE)>
3326              //
3327              //------------------------------------------------------------------------------
3328              
3329              Boolean XmlReader::getValueObjectElement(
3330                  XmlParser& parser, 
3331                  CIMObject& object)
3332              {
3333                  XmlEntry entry;
3334              
3335                  if (!testStartTag(parser, entry, "VALUE.OBJECT"))
3336              	return false;
3337              
3338                  CIMInstance cimInstance;
3339                  CIMClass cimClass;
3340              
3341                  if (XmlReader::getInstanceElement(parser, cimInstance))
3342                  {
3343              	object = CIMObject(cimInstance);
3344 kumpf   1.48     }
3345                  else if (!XmlReader::getClassElement(parser, cimClass))
3346                  {
3347              	object = CIMObject(cimClass);
3348                  }
3349                  else
3350                  {
3351                      throw XmlValidationError(parser.getLine(),
3352                          "Expected INSTANCE or CLASS element");
3353                  }
3354              
3355                  expectEndTag(parser, "VALUE.OBJECT");
3356              
3357                  return true;
3358              }
3359              
3360              //------------------------------------------------------------------------------
3361              // getValueObjectWithPathElement()
3362 mike    1.23 //
3363              // <!ELEMENT VALUE.OBJECTWITHPATH ((CLASSPATH,CLASS)|(INSTANCEPATH,INSTANCE))>
3364              //
3365              //------------------------------------------------------------------------------
3366              
3367 kumpf   1.48 Boolean XmlReader::getValueObjectWithPathElement(
3368 mike    1.23     XmlParser& parser, 
3369 kumpf   1.57     CIMObject& objectWithPath)
3370 mike    1.23 {
3371                  XmlEntry entry;
3372              
3373                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHPATH"))
3374              	return false;
3375              
3376 kumpf   1.54     CIMObjectPath reference;
3377 mike    1.23     Boolean isInstance = false;
3378              
3379                  if (XmlReader::getInstancePathElement(parser, reference))
3380              	isInstance = true;
3381                  else if (!XmlReader::getClassPathElement(parser, reference))
3382                  {
3383 kumpf   1.48         throw XmlValidationError(parser.getLine(),
3384                          "Expected INSTANCEPATH or CLASSPATH element");
3385 mike    1.23     }
3386              
3387                  if (isInstance)
3388                  {
3389              	CIMInstance cimInstance;
3390              
3391              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3392              	{
3393              	    throw XmlValidationError(parser.getLine(),
3394 kumpf   1.48 	        "Expected INSTANCE element");
3395 mike    1.23 	}
3396 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3397                      objectWithPath.setPath (reference);
3398 mike    1.23     }
3399                  else
3400                  {
3401              	CIMClass cimClass;
3402              
3403              	if (!XmlReader::getClassElement(parser, cimClass))
3404              	{
3405              	    throw XmlValidationError(parser.getLine(),
3406              		"Expected CLASS element");
3407              	}
3408 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3409                      objectWithPath.setPath (reference);
3410 mike    1.23     }
3411              
3412                  expectEndTag(parser, "VALUE.OBJECTWITHPATH");
3413              
3414                  return true;
3415 kumpf   1.48 }
3416              
3417              //------------------------------------------------------------------------------
3418              // getValueObjectWithLocalPathElement()
3419              //
3420              // <!ELEMENT VALUE.OBJECTWITHLOCALPATH
3421              //     ((LOCALCLASSPATH,CLASS)|(LOCALINSTANCEPATH,INSTANCE))>
3422              //
3423              //------------------------------------------------------------------------------
3424              
3425              Boolean XmlReader::getValueObjectWithLocalPathElement(
3426                  XmlParser& parser, 
3427 kumpf   1.57     CIMObject& objectWithPath)
3428 kumpf   1.48 {
3429                  XmlEntry entry;
3430              
3431                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHLOCALPATH"))
3432              	return false;
3433              
3434 kumpf   1.54     CIMObjectPath reference;
3435 kumpf   1.48     Boolean isInstance = false;
3436              
3437                  if (XmlReader::getLocalInstancePathElement(parser, reference))
3438              	isInstance = true;
3439                  else if (!XmlReader::getLocalClassPathElement(parser, reference))
3440                  {
3441                      throw XmlValidationError(parser.getLine(),
3442              	    "Expected LOCALINSTANCEPATH or LOCALCLASSPATH element");
3443                  }
3444              
3445                  if (isInstance)
3446                  {
3447              	CIMInstance cimInstance;
3448              
3449              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3450              	{
3451              	    throw XmlValidationError(parser.getLine(),
3452              	        "Expected INSTANCE element");
3453              	}
3454 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3455              	objectWithPath.setPath (reference);
3456 kumpf   1.48     }
3457                  else
3458                  {
3459              	CIMClass cimClass;
3460              
3461              	if (!XmlReader::getClassElement(parser, cimClass))
3462              	{
3463              	    throw XmlValidationError(parser.getLine(),
3464              		"Expected CLASS element");
3465              	}
3466 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3467              	objectWithPath.setPath (reference);
3468 kumpf   1.48     }
3469              
3470                  expectEndTag(parser, "VALUE.OBJECTWITHLOCALPATH");
3471              
3472                  return true;
3473              }
3474              
3475              //------------------------------------------------------------------------------
3476              // getObjectArray()
3477              //
3478              // <object>
3479              //     (VALUE.OBJECT|VALUE.OBJECTWITHLOCALPATH|VALUE.OBJECTWITHPATH)
3480              //
3481              //------------------------------------------------------------------------------
3482              
3483              void XmlReader::getObjectArray(
3484                  XmlParser& parser, 
3485 kumpf   1.57     Array<CIMObject>& objectArray)
3486 kumpf   1.48 {
3487                  CIMObject object;
3488 kumpf   1.57     CIMObject objectWithPath;
3489 kumpf   1.48 
3490                  objectArray.clear();
3491              
3492                  if (getValueObjectElement(parser, object))
3493                  {
3494 kumpf   1.57         objectArray.append(object);
3495 kumpf   1.48         while (getValueObjectElement(parser, object))
3496 kumpf   1.57             objectArray.append(object);
3497 kumpf   1.48     }
3498                  else if (getValueObjectWithPathElement(parser, objectWithPath))
3499                  {
3500                      objectArray.append(objectWithPath);
3501                      while (getValueObjectWithPathElement(parser, objectWithPath))
3502                          objectArray.append(objectWithPath);
3503                  }
3504                  else if (getValueObjectWithLocalPathElement(parser, objectWithPath))
3505                  {
3506                      objectArray.append(objectWithPath);
3507                      while (getValueObjectWithLocalPathElement(parser, objectWithPath))
3508                          objectArray.append(objectWithPath);
3509                  }
3510 mike    1.23 }
3511              
3512              //------------------------------------------------------------------------------
3513              //
3514              // <objectName>: (CLASSNAME|INSTANCENAME)
3515              //
3516              //------------------------------------------------------------------------------
3517              
3518              Boolean XmlReader::getObjectNameElement(
3519                  XmlParser& parser, 
3520 kumpf   1.54     CIMObjectPath& objectName)
3521 mike    1.23 {
3522 kumpf   1.74     CIMName className;
3523 mike    1.23 
3524                  if (getClassNameElement(parser, className, false))
3525                  {
3526 kumpf   1.62 	objectName.set(String(), CIMNamespaceName(), className);
3527 mike    1.23 	return true;
3528                  }
3529                  else if (getInstanceNameElement(parser, objectName))
3530              	return true;
3531                  else
3532                  {
3533              	throw XmlValidationError(parser.getLine(),
3534              	    "expected CLASSNAME or INSTANCENAME element");
3535                  }
3536              
3537                  return false;
3538              }
3539              
3540              //------------------------------------------------------------------------------
3541              //
3542              // <!ELEMENT OBJECTPATH (INSTANCEPATH|CLASSPATH)>
3543              //
3544              //------------------------------------------------------------------------------
3545              
3546              Boolean XmlReader::getObjectPathElement(
3547                  XmlParser& parser, 
3548 kumpf   1.54     CIMObjectPath& objectPath)
3549 mike    1.23 {
3550                  XmlEntry entry;
3551              
3552                  if (!testStartTag(parser, entry, "OBJECTPATH"))
3553              	return false;
3554              
3555                  if (getClassPathElement(parser, objectPath))
3556                  {
3557              	expectEndTag(parser, "OBJECTPATH");
3558              	return true;
3559                  }
3560                  else if (getInstancePathElement(parser, objectPath))
3561                  {
3562              	expectEndTag(parser, "OBJECTPATH");
3563              	return true;
3564                  }
3565                  else
3566                  {
3567              	throw XmlValidationError(parser.getLine(),
3568              	    "expected INSTANCEPATH or CLASSPATH element");
3569                  }
3570 mike    1.23 
3571 mike    1.24     PEGASUS_UNREACHABLE ( return false; )
3572 mike    1.25 }
3573              
3574              //------------------------------------------------------------------------------
3575              //
3576              // getEMethodCallStartTag()
3577              //
3578              //------------------------------------------------------------------------------
3579              
3580              Boolean XmlReader::getEMethodCallStartTag(
3581                  XmlParser& parser, 
3582                  const char*& name)
3583              {
3584                  XmlEntry entry;
3585              
3586                  if (!testStartTag(parser, entry, "EXPMETHODCALL"))
3587              	return false;
3588              
3589                  // Get EXPMETHODCALL.NAME attribute:
3590              
3591                  if (!entry.getAttributeValue("NAME", name))
3592              	throw XmlValidationError(parser.getLine(),
3593 mike    1.25 	    "Missing EXPMETHODCALL.NAME attribute");
3594              
3595                  return true;
3596              }
3597              
3598              //------------------------------------------------------------------------------
3599              //
3600              // getEMethodResponseStartTag()
3601              //
3602              //------------------------------------------------------------------------------
3603              
3604              Boolean XmlReader::getEMethodResponseStartTag(
3605                  XmlParser& parser, 
3606                  const char*& name)
3607              {
3608                  XmlEntry entry;
3609              
3610                  if (!testStartTag(parser, entry, "EXPMETHODRESPONSE"))
3611              	return false;
3612              
3613                  // Get EXPMETHODRESPONSE.NAME attribute:
3614 mike    1.25 
3615                  if (!entry.getAttributeValue("NAME", name))
3616              	throw XmlValidationError(parser.getLine(),
3617              	    "Missing EXPMETHODRESPONSE.NAME attribute");
3618              
3619                  return true;
3620              }
3621              
3622              //------------------------------------------------------------------------------
3623              //
3624              // getMethodCallStartTag()
3625              //
3626              //------------------------------------------------------------------------------
3627              
3628              Boolean XmlReader::getMethodCallStartTag(
3629                  XmlParser& parser, 
3630                  const char*& name)
3631              {
3632                  XmlEntry entry;
3633              
3634                  if (!testStartTag(parser, entry, "METHODCALL"))
3635 mike    1.25 	return false;
3636              
3637                  // Get METHODCALL.NAME attribute:
3638              
3639                  if (!entry.getAttributeValue("NAME", name))
3640              	throw XmlValidationError(parser.getLine(),
3641              	    "Missing METHODCALL.NAME attribute");
3642              
3643                  return true;
3644              }
3645              
3646              //------------------------------------------------------------------------------
3647              //
3648              // getMethodResponseStartTag()
3649              //
3650              //------------------------------------------------------------------------------
3651              
3652              Boolean XmlReader::getMethodResponseStartTag(
3653                  XmlParser& parser, 
3654                  const char*& name)
3655              {
3656 mike    1.25     XmlEntry entry;
3657              
3658                  if (!testStartTag(parser, entry, "METHODRESPONSE"))
3659              	return false;
3660              
3661                  // Get METHODRESPONSE.NAME attribute:
3662              
3663                  if (!entry.getAttributeValue("NAME", name))
3664              	throw XmlValidationError(parser.getLine(),
3665              	    "Missing METHODRESPONSE.NAME attribute");
3666              
3667                  return true;
3668              }
3669              
3670              //------------------------------------------------------------------------------
3671              //
3672 kumpf   1.26 // getParamValueElement()
3673              //
3674              // <!ELEMENT PARAMVALUE (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.REFARRAY)?>
3675              // <!ATTLIST PARAMVALUE
3676              //      %CIMName;
3677              //      %ParamType;>
3678 mike    1.25 //
3679              //------------------------------------------------------------------------------
3680              
3681 kumpf   1.26 Boolean XmlReader::getParamValueElement(
3682 mike    1.25     XmlParser& parser, 
3683 kumpf   1.26     CIMParamValue& paramValue)
3684 mike    1.25 {
3685                  XmlEntry entry;
3686 kumpf   1.26     const char* name;
3687                  CIMType type;
3688                  CIMValue value;
3689 mike    1.25 
3690 kumpf   1.26     if (!testStartTagOrEmptyTag(parser, entry, "PARAMVALUE"))
3691 mike    1.25 	return false;
3692              
3693 kumpf   1.26     Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3694              
3695                  // Get PARAMVALUE.NAME attribute:
3696 mike    1.25 
3697                  if (!entry.getAttributeValue("NAME", name))
3698              	throw XmlValidationError(parser.getLine(),
3699              	    "Missing PARAMVALUE.NAME attribute");
3700 kumpf   1.26 
3701                  // Get PARAMVALUE.PARAMTYPE attribute:
3702              
3703 kumpf   1.67     Boolean gotType = getCimTypeAttribute(parser.getLine(), entry, type,
3704                                                        "PARAMVALUE", "PARAMTYPE", false);
3705 kumpf   1.26 
3706                  if (!empty)
3707                  {
3708                      // Parse VALUE.REFERENCE and VALUE.REFARRAY type
3709 kumpf   1.67         if ( (type == CIMTYPE_REFERENCE) || !gotType )
3710 kumpf   1.26         {
3711 kumpf   1.54 	    CIMObjectPath reference;
3712 kumpf   1.26 	    if (XmlReader::getValueReferenceElement(parser, reference))
3713              	    {
3714              	        value.set(reference);
3715 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3716 kumpf   1.67                 gotType = true;
3717 kumpf   1.26 	    }
3718 kumpf   1.28             else if (XmlReader::getValueReferenceArrayElement(parser, value))
3719              	    {
3720 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3721 kumpf   1.67                 gotType = true;
3722 kumpf   1.28 	    }
3723 kumpf   1.27             // If type==reference but no VALUE.REFERENCE found, use null value
3724 kumpf   1.26         }
3725              
3726                      // Parse non-reference value
3727 kumpf   1.61         if ( type != CIMTYPE_REFERENCE )
3728 kumpf   1.26         {
3729 kumpf   1.67             CIMType effectiveType;
3730                          if (!gotType)
3731 kumpf   1.26 	    {
3732 kumpf   1.67 	        // If we don't know what type the value is, read it as a String
3733 kumpf   1.61 		effectiveType = CIMTYPE_STRING;
3734 kumpf   1.26 	    }
3735 kumpf   1.67             else
3736              	    {
3737              		effectiveType = type;
3738              	    }
3739 kumpf   1.26 
3740                          if ( !XmlReader::getValueArrayElement(parser, effectiveType, value) &&
3741              	         !XmlReader::getValueElement(parser, effectiveType, value) )
3742              	    {
3743              	        value.clear();    // Isn't necessary; should already be cleared
3744              	    }
3745                      }
3746              
3747                      expectEndTag(parser, "PARAMVALUE");
3748                  }
3749              
3750 kumpf   1.67     paramValue = CIMParamValue(name, value, gotType);
3751 kumpf   1.27 
3752                  return true;
3753              }
3754              
3755              //------------------------------------------------------------------------------
3756              //
3757              // getReturnValueElement()
3758              //
3759              // <!ELEMENT RETURNVALUE (VALUE|VALUE.REFERENCE)>
3760              // <!ATTLIST RETURNVALUE
3761              //      %ParamType;>
3762              //
3763              //------------------------------------------------------------------------------
3764              
3765              Boolean XmlReader::getReturnValueElement(
3766                  XmlParser& parser, 
3767                  CIMValue& returnValue)
3768              {
3769                  XmlEntry entry;
3770                  CIMType type;
3771                  CIMValue value;
3772 kumpf   1.27 
3773                  if (!testStartTag(parser, entry, "RETURNVALUE"))
3774              	return false;
3775              
3776                  // Get RETURNVALUE.PARAMTYPE attribute:
3777                  // NOTE: Array type return values are not allowed (2/20/02)
3778              
3779 kumpf   1.67     Boolean gotType = getCimTypeAttribute(parser.getLine(), entry, type,
3780                                                        "RETURNVALUE", "PARAMTYPE", false);
3781 kumpf   1.27 
3782                  // Parse VALUE.REFERENCE type
3783 kumpf   1.67     if ( (type == CIMTYPE_REFERENCE) || !gotType )
3784 kumpf   1.27     {
3785 kumpf   1.54         CIMObjectPath reference;
3786 kumpf   1.27         if (XmlReader::getValueReferenceElement(parser, reference))
3787                      {
3788                          returnValue.set(reference);
3789 kumpf   1.61             type = CIMTYPE_REFERENCE;
3790 kumpf   1.67             gotType = true;
3791 kumpf   1.27         }
3792 kumpf   1.61         else if (type == CIMTYPE_REFERENCE)
3793 kumpf   1.27         {
3794                          throw XmlValidationError(parser.getLine(),
3795                              "expected VALUE.REFERENCE element");
3796                      }
3797                  }
3798              
3799                  // Parse non-reference return value
3800 kumpf   1.61     if ( type != CIMTYPE_REFERENCE )
3801 kumpf   1.27     {
3802 kumpf   1.67         if (!gotType)
3803 kumpf   1.27         {
3804 kumpf   1.67             // If we don't know what type the value is, read it as a String
3805 kumpf   1.61             type = CIMTYPE_STRING;
3806 kumpf   1.27         }
3807              
3808                      if ( !XmlReader::getValueElement(parser, type, returnValue) )
3809                      {
3810                          throw XmlValidationError(parser.getLine(),
3811                              "expected VALUE element");
3812                      }
3813                  }
3814              
3815                  expectEndTag(parser, "RETURNVALUE");
3816 mike    1.25 
3817                  return true;
3818 mike    1.23 }
3819              
3820              PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2