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