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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2