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